Staging: Merge 2.6.37-rc2 into staging-next

This was necessary in order  to resolve some conflicts that happened
between -rc1 and -rc2 with the following files:
	drivers/staging/bcm/Bcmchar.c
	drivers/staging/intel_sst/intel_sst_app_interface.c

All should be resolved now.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 5eafdf4..49aee27 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -175,5 +175,9 @@
 
 source "drivers/staging/speakup/Kconfig"
 
+source "drivers/staging/cptm1217/Kconfig"
+
+source "drivers/staging/ste_rmi4/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a97a955..20c5641 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -68,3 +68,5 @@
 obj-$(CONFIG_FT1000)		+= ft1000/
 obj-$(CONFIG_SND_INTEL_SST)		+= intel_sst/
 obj-$(CONFIG_SPEAKUP)	+= speakup/
+obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= cptm1217/
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)	+= ste_rmi4/
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 8c95d8c..1dda9fb 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -70,7 +70,7 @@
 MODULE_PARM_DESC(start_off,
 		 "Set to 1 to switch off OLED display after it is attached");
 
-enum oled_pack_mode{
+enum oled_pack_mode {
 	PACK_MODE_G1,
 	PACK_MODE_G50,
 	PACK_MODE_LAST
diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
index c307a55..6454a86 100644
--- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
+++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
@@ -1188,7 +1188,7 @@
     HIF_DEVICE *hifdevice;
     AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
     AR_DEBUG_ASSERT(func != NULL);
-    hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
+    hifdevice = kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
     AR_DEBUG_ASSERT(hifdevice != NULL);
 #if HIF_USE_DMA_BOUNCE_BUFFER
     hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c
index 3d2c1bc..4473cc8 100644
--- a/drivers/staging/batman-adv/vis.c
+++ b/drivers/staging/batman-adv/vis.c
@@ -135,9 +135,8 @@
 	hlist_for_each_entry(entry, pos, if_list, list) {
 		if (entry->primary)
 			len += sprintf(buff + len, "PRIMARY, ");
-		else {
+		else
 			len += sprintf(buff + len,  "SEC %pM, ", entry->addr);
-		}
 	}
 
 	return len;
diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h
index 748460e..32909e2 100644
--- a/drivers/staging/bcm/Adapter.h
+++ b/drivers/staging/bcm/Adapter.h
@@ -7,53 +7,6 @@
 #define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256
 #include "Debug.h"
 
-typedef struct _LIST_ENTRY{
-	struct _LIST_ENTRY 	*next;
-	struct _LIST_ENTRY 	*prev;
-} LIST_ENTRY, *PLIST_ENTRY;
-
-typedef struct _BCM_LIST_ENTRY {
-
-    LIST_ENTRY  		Link;
-
-} BCM_LIST_ENTRY, *PBCM_LIST_ENTRY;
-
-typedef enum _RCB_STATUS
-{
-	DRIVER_PROCESSED=1,
-	APPLICATION_PROCESSED
-} RCB_STATUS, *PRCB_STATUS;
-
-#define fFILLED 1
-#define fEMPTY 0
-
-struct _BCM_CB
-{
-	// The network packet that this RCB is receiving
-	PVOID      			pv_packet;
-	// Describes the length of the packet .
-	UINT                ui_packet_length;
-	// Pointer to the first buffer in the packet (only one buffer for Rx)
-	PUCHAR				buffer;
-	atomic_t	        status;
-	UINT	            filled;
-} __attribute__((packed));
-typedef struct _BCM_CB BCM_CB,*PBCM_CB;
-
-typedef BCM_CB BCM_RCB, *PBCM_RCB;
-typedef BCM_CB BCM_TCB, *PBCM_TCB;
-
-/* This is to be stored in the "pvOsDepData" of ADAPTER */
-typedef struct LINUX_DEP_DATA
-{
-	struct net_device		*virtualdev;	/* Our Interface (veth0) */
-	struct net_device		*actualdev;	/* True Interface (eth0) */
-	struct net_device_stats netstats;	/* Net statistics */
-	struct fasync_struct	*async_queue;	/* For asynchronus notification */
-
-} LINUX_DEP_DATA, *PLINUX_DEP_DATA;
-
-
 struct _LEADER
 {
 	USHORT 	Vcid;
@@ -429,26 +382,28 @@
 struct _MINI_ADAPTER
 {
 	struct _MINI_ADAPTER *next;
-	PVOID			    pvOsDepData;
+	struct net_device	*dev;
+	u32			msg_enable;
+
 	CHAR                *caDsxReqResp;
-	atomic_t			ApplicationRunning;
+	atomic_t		ApplicationRunning;
 	volatile INT		CtrlQueueLen;
-	atomic_t            AppCtrlQueueLen;
-	BOOLEAN             AppCtrlQueueOverFlow;
-	atomic_t			CurrentApplicationCount;
-	atomic_t 			RegisteredApplicationCount;
-	BOOLEAN			    TimerActive;
-	ULONG				StatisticsPointer;
+	atomic_t            	AppCtrlQueueLen;
+	BOOLEAN             	AppCtrlQueueOverFlow;
+	atomic_t		CurrentApplicationCount;
+	atomic_t 		RegisteredApplicationCount;
+	BOOLEAN		  	LinkUpStatus;
+	BOOLEAN		    	TimerActive;
+	u32			StatisticsPointer;
 	struct sk_buff		*RxControlHead;
 	struct sk_buff		*RxControlTail;
-//	spinlock_t			RxControlQueuelock;
+
 	struct semaphore	RxAppControlQueuelock;
 	struct semaphore	fw_download_sema;
 
 	PPER_TARANG_DATA    pTarangs;
 	spinlock_t			control_queue_lock;
 	wait_queue_head_t	process_read_wait_queue;
-	ULONG		    	bcm_jiffies;	/* Store Jiffies value */
 
 	// the pointer to the first packet we have queued in send
 	// deserialized miniport support variables
@@ -458,24 +413,15 @@
 	// this to keep track of the Tx and Rx MailBox Registers.
 	atomic_t		    CurrNumFreeTxDesc;
 	// to keep track the no of byte recieved
-	atomic_t			RxRollOverCount;
 	USHORT				PrevNumRecvDescs;
 	USHORT				CurrNumRecvDescs;
-	atomic_t			GoodRxByteCount;
-	atomic_t			GoodRxPktCount;
-	atomic_t			BadRxByteCount;
-	atomic_t			RxPacketDroppedCount;
-	atomic_t			GoodTxByteCount;
-	atomic_t			TxTotalPacketCount;
-	atomic_t			TxDroppedPacketCount;
-	ULONG			   	LinkUpStatus;
-	BOOLEAN			    TransferMode;
 	UINT				u32TotalDSD;
 	PacketInfo		    PackInfo[NO_OF_QUEUES];
 	S_CLASSIFIER_RULE	astClassifierTable[MAX_CLASSIFIERS];
+	BOOLEAN			    TransferMode;
 
 	/*************** qos ******************/
-	UINT				bETHCSEnabled;
+	BOOLEAN			    bETHCSEnabled;
 
 	ULONG			    BEBucketSize;
 	ULONG			    rtPSBucketSize;
@@ -483,7 +429,6 @@
 	BOOLEAN			    AutoLinkUp;
 	BOOLEAN			    AutoSyncup;
 
-	struct net_device	*dev;
 	int				major;
 	int				minor;
 	wait_queue_head_t 	tx_packet_wait_queue;
@@ -491,8 +436,6 @@
 	atomic_t			process_waiting;
 	BOOLEAN 			fw_download_done;
 
-	unsigned int		ctrlpkt_present;
-	BOOLEAN 			packets_given_to_all;
 	char 				*txctlpacket[MAX_CNTRL_PKTS];
 	atomic_t			cntrlpktCnt ;
 	atomic_t			index_app_read_cntrlpkt;
@@ -502,34 +445,30 @@
 	struct semaphore 	rdmwrmsync;
 
 	STTARGETDSXBUFFER	astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS];
-	ULONG				ulFreeTargetBufferCnt;
+	ULONG			ulFreeTargetBufferCnt;
 	ULONG              	ulCurrentTargetBuffer;
 	ULONG              	ulTotalTargetBuffersAvailable;
-	unsigned int		timeout;
-	int 				irq;
+
 	unsigned long 		chip_id;
-	unsigned int		bFlashBoot;
-	unsigned int 		if_up;
-//	spinlock_t			sleeper_lock;
-	atomic_t			rdm_wrm_access;
-	atomic_t			tx_rx_access;
+
 	wait_queue_head_t 	lowpower_mode_wait_queue;
-	atomic_t			bAbortedByHost;
-	BOOLEAN				bBinDownloaded;
-	BOOLEAN				bCfgDownloaded;
-	USHORT				usBestEffortQueueIndex;
-	BOOLEAN				bSyncUpRequestSent;
-//	struct semaphore 	data_packet_queue_lock;
+
+	BOOLEAN			bFlashBoot;
+	BOOLEAN			bBinDownloaded;
+	BOOLEAN			bCfgDownloaded;
+	BOOLEAN			bSyncUpRequestSent;
+	USHORT			usBestEffortQueueIndex;
+
 	wait_queue_head_t 	ioctl_fw_dnld_wait_queue;
 	BOOLEAN				waiting_to_fw_download_done;
 	pid_t				fw_download_process_pid;
 	PSTARGETPARAMS		pstargetparams;
 	BOOLEAN				device_removed;
 	BOOLEAN				DeviceAccess;
-	INT					DDRSetting;
-	BOOLEAN				bDDRInitDone;
-	ULONG				ulPowerSaveMode;
 	BOOLEAN				bIsAutoCorrectEnabled;
+	BOOLEAN				bDDRInitDone;
+	INT				DDRSetting;
+	ULONG				ulPowerSaveMode;
 	spinlock_t			txtransmitlock;
 	B_UINT8				txtransmit_running;
 	/* Thread for control packet handling */
@@ -567,13 +506,13 @@
 	unsigned int	usIdleModePattern;
 	//BOOLEAN			bTriedToWakeUpFromShutdown;
 	BOOLEAN			bLinkDownRequested;
-	unsigned int	check_for_hang;
+
 	int 			downloadDDR;
 	PHS_DEVICE_EXTENSION stBCMPhsContext;
 	S_HDR_SUPRESSION_CONTEXTINFO	stPhsTxContextInfo;
 	uint8_t			ucaPHSPktRestoreBuf[2048];
 	uint8_t			bPHSEnabled;
-	int 			AutoFirmDld;
+	BOOLEAN			AutoFirmDld;
 	BOOLEAN         bMipsConfig;
 	BOOLEAN         bDPLLConfig;
 	UINT32			aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
@@ -599,10 +538,9 @@
 
 
 	struct semaphore	NVMRdmWrmLock;
-	BOOLEAN			bNetworkInterfaceRegistered;
-	BOOLEAN			bNetdeviceNotifierRegistered;
+
 	struct device *pstCreatedClassDevice;
-	BOOLEAN			bUsbClassDriverRegistered;
+
 //	BOOLEAN				InterfaceUpStatus;
 	PFLASH2X_CS_INFO psFlash2xCSInfo;
 	PFLASH_CS_INFO psFlashCSInfo ;
@@ -630,17 +568,13 @@
 	struct semaphore	LowPowerModeSync;
 	ULONG	liDrainCalculated;
 	UINT gpioBitMap;
+
     S_BCM_DEBUG_STATE stDebugState;
 
 };
 typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER;
 
-
-typedef struct _DEVICE_EXTENSION
-{
-	PMINI_ADAPTER pAdapt;
-}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
-
+#define GET_BCM_ADAPTER(net_dev)	netdev_priv(net_dev)
 
 struct _ETH_HEADER_STRUC {
     UCHAR       au8DestinationAddress[6];
@@ -667,8 +601,8 @@
 
 typedef struct _DDR_SETTING
 {
-	ULONG ulRegAddress;
-	ULONG ulRegValue;
+	UINT ulRegAddress;
+	UINT ulRegValue;
 }DDR_SETTING, *PDDR_SETTING;
 typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE;
 INT
diff --git a/drivers/staging/bcm/Arp.c b/drivers/staging/bcm/Arp.c
deleted file mode 100644
index d60d859..0000000
--- a/drivers/staging/bcm/Arp.c
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/*
- * File Name: Arp.c
- * Abstract: This file contains the routines for handling ARP PACKETS
- */
-#include "headers.h"
-#define	ARP_PKT_SIZE	60
-
-/* =========================================================================
- * Function    - reply_to_arp_request()
- *
- * Description - When this host tries to broadcast ARP request packet through
- *		 		 the virtual interface (veth0), reply directly to upper layer.
- *		 		 This function allocates a new skb for ARP reply packet,
- *		 		 fills in the fields of the packet and then sends it to
- *		 		 upper layer.
- *
- * Parameters  - skb:	Pointer to sk_buff structure of the ARP request pkt.
- *
- * Returns     - None
- * =========================================================================*/
-
-VOID
-reply_to_arp_request(struct sk_buff *skb)
-{
-	PMINI_ADAPTER		Adapter;
-	struct ArpHeader 	*pArpHdr = NULL;
-	struct ethhdr		*pethhdr = NULL;
-	UCHAR 				uiIPHdr[4];
-	/* Check for valid skb */
-	if(skb == NULL)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n");
-		return;
-	}
-
-
-	Adapter = GET_BCM_ADAPTER(skb->dev);
-	/* Print the ARP Request Packet */
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :");
-	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
-
-	/*
-	 * Extract the Ethernet Header and Arp Payload including Header
-     */
-	pethhdr = (struct ethhdr *)skb->data;
-	pArpHdr  = (struct ArpHeader *)(skb->data+ETH_HLEN);
-
-	if(Adapter->bETHCSEnabled)
-	{
-		if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
-		{
-			bcm_kfree_skb(skb);
-			return;
-		}
-	}
-
-	// Set the Ethernet Header First.
-	memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN);
-	if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
-	{
-		pethhdr->h_source[5]++;
-	}
-
-	/* Set the reply to ARP Reply */
-	pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY);
-
-	/* Set the HW Address properly */
-	memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN);
-	memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN);
-
-	// Swapping the IP Adddress
-	memcpy(uiIPHdr,pArpHdr->ar_sip,4);
-	memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4);
-	memcpy(pArpHdr->ar_tip,uiIPHdr,4);
-
-	/* Print the ARP Reply Packet */
-
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: ");
-
-	/* Send the Packet to upper layer */
-	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
-
-	skb->protocol = eth_type_trans(skb,skb->dev);
-	skb->pkt_type = PACKET_HOST;
-
-//	skb->mac.raw=skb->data+LEADER_SIZE;
-	skb_set_mac_header (skb, LEADER_SIZE);
-	netif_rx(skb);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n");
-	return;
-}
-
-
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index fead9c5..31674ea 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -12,7 +12,7 @@
 *
 * Returns	  - Zero(Success)
 ****************************************************************/
-static struct class *bcm_class = NULL;
+
 static int bcm_char_open(struct inode *inode, struct file * filp)
 {
 	PMINI_ADAPTER 		Adapter = NULL;
@@ -93,7 +93,7 @@
     /*Stop Queuing the control response Packets*/
     atomic_dec(&Adapter->ApplicationRunning);
 
-    bcm_kfree(pTarang);
+    kfree(pTarang);
 
 	/* remove this filp from the asynchronously notified filp's */
     filp->private_data = NULL;
@@ -102,11 +102,11 @@
 
 static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)
 {
-    PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data;
+	PPER_TARANG_DATA pTarang = filp->private_data;
 	PMINI_ADAPTER	Adapter = pTarang->Adapter;
-    struct sk_buff* Packet = NULL;
-    UINT            PktLen = 0;
-	int 			wait_ret_val=0;
+	struct sk_buff* Packet = NULL;
+	ssize_t         PktLen = 0;
+	int 		wait_ret_val=0;
 
 	wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
 		(pTarang->RxAppControlHead || Adapter->device_removed));
@@ -139,14 +139,16 @@
 	if(Packet)
 	{
 		PktLen = Packet->len;
-		if(copy_to_user(buf, Packet->data, PktLen))
+		if(copy_to_user(buf, Packet->data, min_t(size_t, PktLen, size)))
 		{
-			bcm_kfree_skb(Packet);
+			dev_kfree_skb(Packet);
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n");
 			return -EFAULT;
 		}
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %d Bytes From Adapter packet = 0x%p by process %d!\n", PktLen, Packet, current->pid);
-		bcm_kfree_skb(Packet);
+		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
+				"Read %zd Bytes From Adapter packet = %p by process %d!\n",
+				PktLen, Packet, current->pid);
+		dev_kfree_skb(Packet);
 	}
 
     BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n");
@@ -155,15 +157,12 @@
 
 static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
 {
-    PPER_TARANG_DATA  pTarang = (PPER_TARANG_DATA)filp->private_data;
-	void __user *argp = (void __user *)argp;
+	PPER_TARANG_DATA  pTarang = filp->private_data;
+	void __user *argp = (void __user *)arg;
 	PMINI_ADAPTER 	Adapter = pTarang->Adapter;
 	INT  			Status = STATUS_FAILURE;
-	IOCTL_BUFFER 	IoBuffer={};
-#ifndef BCM_SHM_INTERFACE
-    int timeout = 0;
-#endif
-
+	int timeout = 0;
+	IOCTL_BUFFER 	IoBuffer;
 
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
 
@@ -204,50 +203,41 @@
 
 	Status = vendorextnIoctl(Adapter, cmd, arg);
 	if(Status != CONTINUE_COMMON_PATH )
-	{
 		 return Status;
-	}
 
 	switch(cmd){
 		// Rdms for Swin Idle...
 		case IOCTL_BCM_REGISTER_READ_PRIVATE:
 		{
 			RDM_BUFFER  sRdmBuffer = {0};
-			PCHAR temp_buff = NULL;
-			UINT Bufflen = 0;
-			/* Copy Ioctl Buffer structure */
-			if(copy_from_user((PCHAR)&IoBuffer, argp,
-				sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
+			PCHAR temp_buff;
+			UINT Bufflen;
 
+			/* Copy Ioctl Buffer structure */
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+
+			if (IoBuffer.InputLength > sizeof(sRdmBuffer))
+				return -EINVAL;
+
+			if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
+
+			/* FIXME: need to restrict BuffLen */
 			Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4;
-			temp_buff = (PCHAR)kmalloc(Bufflen, GFP_KERNEL);
+			temp_buff = kmalloc(Bufflen, GFP_KERNEL);
 			if(!temp_buff)
-			{
-				return STATUS_FAILURE;
-			}
-			if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
-				IoBuffer.InputLength))
-			{
-				Status = -EFAULT;
-				break;
-			}
+				return -ENOMEM;
+
 			Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
 					(PUINT)temp_buff, Bufflen);
-			if(Status != STATUS_SUCCESS)
+			if(Status == STATUS_SUCCESS)
 			{
-				bcm_kfree(temp_buff);
-				return Status;
+				if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
+					Status = -EFAULT;
 			}
-			if(copy_to_user(IoBuffer.OutputBuffer,
-				(PCHAR)temp_buff, (UINT)IoBuffer.OutputLength))
-			{
-				Status = -EFAULT;
-			}
-			bcm_kfree(temp_buff);
+
+			kfree(temp_buff);
 			break;
 		}
 		case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
@@ -256,19 +246,16 @@
 			UINT uiTempVar=0;
 			/* Copy Ioctl Buffer structure */
 
-			if(copy_from_user(&IoBuffer, argp,
-				sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+
+			if (IoBuffer.InputLength > sizeof(sWrmBuffer))
+				return -EINVAL;
+
 			/* Get WrmBuffer structure */
-			if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
-				IoBuffer.InputLength))
-			{
-				Status = -EFAULT;
-				break;
-			}
+			if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
+
 			uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
 			if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
 			 	((uiTempVar == EEPROM_REJECT_REG_1)||
@@ -277,8 +264,7 @@
 				(uiTempVar == EEPROM_REJECT_REG_4)))
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
-				Status = -EFAULT;
-				break;
+				return -EFAULT;
 			}
 			Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
 						(PUINT)sWrmBuffer.Data, sizeof(ULONG));
@@ -305,56 +291,39 @@
 				(Adapter->bPreparingForLowPowerMode ==TRUE))
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
-				Status = -EACCES;
-				break;
+				return -EACCES;
 			}
 			/* Copy Ioctl Buffer structure */
-			if(copy_from_user(&IoBuffer, argp,
-				sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
 
-			temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
+			if (IoBuffer.InputLength > sizeof(sRdmBuffer))
+				return -EINVAL;
+
+			if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
+
+			/* FIXME: don't trust user supplied length */
+			temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
 			if(!temp_buff)
-			{
 				return STATUS_FAILURE;
-			}
-			if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
-				IoBuffer.InputLength))
-			{
-				Status = -EFAULT;
-				break;
-			}
 
-			if(
-#if !defined(BCM_SHM_INTERFACE)
-				(((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
-#endif
-					((ULONG)sRdmBuffer.Register & 0x3)
-			  )
+			if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
+			   ((ULONG)sRdmBuffer.Register & 0x3))
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n",
 					(int)sRdmBuffer.Register);
-				Status = -EINVAL;
-				break;
+				return -EINVAL;
 			}
 
 			uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
 			Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
 						(PUINT)temp_buff, IoBuffer.OutputLength);
-			if(Status != STATUS_SUCCESS)
-			{
-				bcm_kfree(temp_buff);
-				return Status;
-			}
-			if(copy_to_user(IoBuffer.OutputBuffer,
-				(PCHAR)temp_buff, (UINT)IoBuffer.OutputLength))
-			{
-				Status = -EFAULT;
-			}
-			bcm_kfree(temp_buff);
+			if(Status == STATUS_SUCCESS)
+				if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
+					Status = -EFAULT;
+
+			kfree(temp_buff);
 			break;
 		}
 		case IOCTL_BCM_REGISTER_WRITE:
@@ -367,36 +336,28 @@
 				(Adapter->bPreparingForLowPowerMode ==TRUE))
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
-				Status = -EACCES;
-				break;
+				return -EACCES;
 			}
-			/* Copy Ioctl Buffer structure */
-			if(copy_from_user((PCHAR)&IoBuffer, argp,
-					sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
-			/* Get WrmBuffer structure */
-			if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
-				IoBuffer.InputLength))
-			{
-				Status = -EFAULT;
-				break;
-			}
-			if(
-#if !defined(BCM_SHM_INTERFACE)
 
-				(((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
-#endif
-					((ULONG)sWrmBuffer.Register & 0x3)
-			 )
+			/* Copy Ioctl Buffer structure */
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+
+			if (IoBuffer.InputLength > sizeof(sWrmBuffer))
+				return -EINVAL;
+
+			/* Get WrmBuffer structure */
+			if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
+
+			if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
+					((ULONG)sWrmBuffer.Register & 0x3) )
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n",
 						(int)sWrmBuffer.Register);
-				Status = -EINVAL;
-				break;
+				return -EINVAL;
 			}
+
 			uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
 			if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
 				((uiTempVar == EEPROM_REJECT_REG_1)||
@@ -406,8 +367,7 @@
 				(cmd == IOCTL_BCM_REGISTER_WRITE))
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
-				Status = -EFAULT;
-				break;
+				return -EFAULT;
 			}
 
 			Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
@@ -436,19 +396,14 @@
 				(Adapter->bPreparingForLowPowerMode ==TRUE))
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
-				Status = -EACCES;
-				break;
+				return -EACCES;
 			}
 			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-		    }
+				return -EFAULT;
+			if (IoBuffer.InputLength > sizeof(gpio_info))
+				return -EINVAL;
 			if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
-			{
-				Status = -EFAULT;
-				break;
-			}
+				return -EFAULT;
 			uiBit  = gpio_info.uiGpioNumber;
 			uiOperation = gpio_info.uiGpioValue;
 
@@ -517,8 +472,7 @@
 		break;
 		case BCM_LED_THREAD_STATE_CHANGE_REQ:
 		{
-
-			USER_THREAD_REQ threadReq = {0};
+			USER_THREAD_REQ threadReq = { 0 };
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive");
 
 			if((Adapter->IdleMode == TRUE) ||
@@ -529,21 +483,16 @@
 				Status = -EACCES;
 				break;
 			}
-			Status =copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-			if(Status)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status);
-				Status = -EFAULT;
-				break;
-			}
 
-			Status= copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength);
-			if(Status)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the InputBuffer from user space err:%d",Status);
-				Status = -EFAULT;
-				break;
-			}
+			if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+
+			if (IoBuffer.InputLength > sizeof(threadReq))
+				return -EINVAL;
+
+			if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
+
 			//if LED thread is running(Actively or Inactively) set it state to make inactive
 			if(Adapter->LEDInfo.led_thread_running)
 			{
@@ -572,19 +521,13 @@
 			if((Adapter->IdleMode == TRUE) ||
 				(Adapter->bShutStatus ==TRUE) ||
 				(Adapter->bPreparingForLowPowerMode ==TRUE))
-			{
-				Status = -EACCES;
-				break;
-			}
-			if(copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
-                        	Status = -EFAULT;
-                    		break;
-                	}
-                if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
-                {
-                    Status = -EFAULT;
-                    break;
-                }
+				return -EACCES;
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+			if (IoBuffer.InputLength > sizeof(gpio_info))
+				return -EINVAL;
+			if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
                 uiBit  = gpio_info.uiGpioNumber;
 				  //Set the gpio output register
 				Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
@@ -608,25 +551,14 @@
 				if((Adapter->IdleMode == TRUE) ||
 				(Adapter->bShutStatus ==TRUE) ||
 				(Adapter->bPreparingForLowPowerMode ==TRUE))
-				{
-					Status = -EINVAL;
-					break;
-				}
-				Status = copy_from_user( (PCHAR)&IoBuffer, argp, sizeof( IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status);
-					Status = -EFAULT;
-					break;
-				}
+					return -EINVAL;
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+					return -EFAULT;
+				if (IoBuffer.InputLength > sizeof(gpio_multi_info))
+					return -EINVAL;
+				if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
+					return -EFAULT;
 
-				Status = copy_from_user( &gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength);
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status);
-					Status = -EFAULT;
-					break;
-				}
 				if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap);
@@ -686,7 +618,6 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
-					Status = -EFAULT;
 					break;
 				}
 			}
@@ -700,25 +631,14 @@
 			if((Adapter->IdleMode == TRUE) ||
 				(Adapter->bShutStatus ==TRUE) ||
 				(Adapter->bPreparingForLowPowerMode ==TRUE))
-			{
-					Status = -EINVAL;
-					break;
-			}
-			Status = copy_from_user(&IoBuffer, argp, sizeof( IOCTL_BUFFER));
-			if(Status)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status);
-				Status = -EFAULT;
-				break;
-			}
+					return -EINVAL;
 
-			Status = copy_from_user( &gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength);
-			if(Status)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status);
-				Status = -EFAULT;
-				break;
-			}
+			if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+			if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
+				return -EINVAL;
+			if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				return -EFAULT;
 
 			Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT));
 			if( STATUS_SUCCESS != Status)
@@ -769,7 +689,6 @@
 			if(Status)
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
-				Status = -EFAULT;
 				break;
 			}
 		}
@@ -783,24 +702,20 @@
 		case IOCTL_IDLE_REQ:
 		{
 			PVOID pvBuffer=NULL;
-			/* Copy Ioctl Buffer structure */
-			if(copy_from_user(&IoBuffer, argp,
-							sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
-			pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL);
-			if(!pvBuffer)
-			{
-				return -ENOMEM;
-			}
 
-			if(copy_from_user(pvBuffer, IoBuffer.InputBuffer,
-					IoBuffer.InputLength))
+			/* Copy Ioctl Buffer structure */
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+
+			/* FIXME: don't accept any length from user */
+			pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
+			if(!pvBuffer)
+				return -ENOMEM;
+
+			if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
 			{
 				Status = -EFAULT;
-				bcm_kfree(pvBuffer);
+				kfree(pvBuffer);
 				break;
 			}
 
@@ -820,10 +735,9 @@
 			Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
 		cntrlEnd:
 			up(&Adapter->LowPowerModeSync);
-			bcm_kfree(pvBuffer);
+			kfree(pvBuffer);
 			break;
 		}
-#ifndef BCM_SHM_INTERFACE
 		case IOCTL_BCM_BUFFER_DOWNLOAD_START:
 		{
 			INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ;
@@ -844,7 +758,7 @@
 				Status = reset_card_proc(Adapter);
 				if(Status)
 				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "reset_card_proc Failed!\n");
+					pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
 					up(&Adapter->fw_download_sema);
 					up(&Adapter->NVMRdmWrmLock);
 					break;
@@ -862,7 +776,7 @@
 		}
 		case IOCTL_BCM_BUFFER_DOWNLOAD:
 			{
-				FIRMWARE_INFO 	*psFwInfo=NULL;
+				FIRMWARE_INFO 	*psFwInfo = NULL;
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
 			do{
 				if(!down_trylock(&Adapter->fw_download_sema))
@@ -871,29 +785,23 @@
 					Status=-EINVAL;
 					break;
 				}
+
 				/* Copy Ioctl Buffer structure */
 				if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
-					Status = -EFAULT;
-					break;
-				}
+					return -EFAULT;
+
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n",
 										IoBuffer.InputLength);
-				psFwInfo=kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
+
+				if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO))
+					return -EINVAL;
+
+				psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
 				if(!psFwInfo)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Failed to allocate buffer!!!!\n");
-					Status = -ENOMEM;
-					break;
-				}
-				if(copy_from_user(psFwInfo, IoBuffer.InputBuffer,
-							IoBuffer.InputLength))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from_user 2 failed\n");
-					Status = -EFAULT;
-					break;
-				}
+					return -ENOMEM;
+
+				if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength))
+					return -EFAULT;
 
 				if(!psFwInfo->pvMappedFirmwareAddress ||
 						(psFwInfo->u32FirmwareLength == 0))
@@ -929,7 +837,7 @@
 			  if(Status != STATUS_SUCCESS)
 					up(&Adapter->fw_download_sema);
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n");
-				bcm_kfree(psFwInfo);
+				kfree(psFwInfo);
 				break;
 			}
 		case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
@@ -946,7 +854,7 @@
 				Adapter->bBinDownloaded=TRUE;
 				Adapter->bCfgDownloaded=TRUE;
 				atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
-				atomic_set(&Adapter->RxRollOverCount, 0);
+
 				Adapter->CurrNumRecvDescs=0;
 				Adapter->downloadDDR = 0;
 
@@ -999,7 +907,6 @@
 			up(&Adapter->NVMRdmWrmLock);
 			break;
 		}
-#endif
 		case IOCTL_BE_BUCKET_SIZE:
 			Status = 0;
 			if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
@@ -1050,22 +957,16 @@
 			break;
 
 		case IOCTL_GET_PACK_INFO:
-			if(copy_to_user(argp, &Adapter->PackInfo,
-				sizeof(PacketInfo)*NO_OF_QUEUES))
-			{
-				Status = -EFAULT;
-				break;
-			}
+			if(copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES))
+				return -EFAULT;
 			Status = STATUS_SUCCESS;
 			break;
 		case IOCTL_BCM_SWITCH_TRANSFER_MODE:
 		{
 			UINT uiData = 0;
 			if(copy_from_user(&uiData, argp, sizeof(UINT)))
-			{
-				Status = -EFAULT;
-				break;
-			}
+				return -EFAULT;
+
 			if(uiData)	/* Allow All Packets */
 			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
@@ -1084,22 +985,16 @@
 		{
 			/* Copy Ioctl Buffer structure */
 			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
-			if(copy_to_user(IoBuffer.OutputBuffer,
-				VER_FILEVERSION_STR, (UINT)IoBuffer.OutputLength))
-			{
-				Status = -EFAULT;
-				break;
-			}
+				return -EFAULT;
+
+			if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength))
+				return -EFAULT;
 			Status = STATUS_SUCCESS;
 			break;
 		}
 		case IOCTL_BCM_GET_CURRENT_STATUS:
 		{
-			LINK_STATE plink_state;
+			LINK_STATE link_state;
 
 			/* Copy Ioctl Buffer structure */
 			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
@@ -1108,19 +1003,19 @@
 				Status = -EFAULT;
 				break;
 			}
-			if (IoBuffer.OutputLength != sizeof(plink_state)) {
+			if (IoBuffer.OutputLength != sizeof(link_state)) {
 				Status = -EINVAL;
 				break;
 			}
 
-			if (copy_from_user(&plink_state, (void __user *)arg, sizeof(plink_state))) {
-				Status = -EFAULT;
-				break;
-			}
-			plink_state.bIdleMode = (UCHAR)Adapter->IdleMode;
-			plink_state.bShutdownMode = Adapter->bShutStatus;
-			plink_state.ucLinkStatus = (UCHAR)Adapter->LinkStatus;
-			if (copy_to_user(IoBuffer.OutputBuffer, &plink_state, IoBuffer.OutputLength)) {
+			memset(&link_state, 0, sizeof(link_state));
+			link_state.bIdleMode = Adapter->IdleMode;
+			link_state.bShutdownMode = Adapter->bShutStatus;
+			link_state.ucLinkStatus = Adapter->LinkStatus;
+
+			if (copy_to_user(IoBuffer.OutputBuffer, &link_state,
+					 min_t(size_t, sizeof(link_state), IoBuffer.OutputLength)))
+			{
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
 				Status = -EFAULT;
 				break;
@@ -1131,17 +1026,14 @@
         case IOCTL_BCM_SET_MAC_TRACING:
         {
             UINT  tracing_flag;
+
             /* copy ioctl Buffer structure */
-			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-			{
-				Status = -EFAULT;
-				break;
-			}
-			if(copy_from_user(&tracing_flag, IoBuffer.InputBuffer,sizeof(UINT)))
-            {
-				Status = -EFAULT;
-				break;
-			}
+	    if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+		    return -EFAULT;
+
+	    if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT)))
+		    return -EFAULT;
+
             if (tracing_flag)
                 Adapter->pTarangs->MacTracingEnabled = TRUE;
             else
@@ -1151,72 +1043,53 @@
 		case IOCTL_BCM_GET_DSX_INDICATION:
 		{
 			ULONG ulSFId=0;
-			if(copy_from_user((PCHAR)&IoBuffer, argp,
-					sizeof(IOCTL_BUFFER)))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid IO buffer!!!" );
-				Status = -EFAULT;
-				break;
-			}
+			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+				return -EFAULT;
+
 			if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt))
 			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Mismatch req: %lx needed is =0x%zx!!!",
-					IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
+				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,
+						"Mismatch req: %lx needed is =0x%zx!!!",
+						IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
 				return -EINVAL;
 			}
-			if(copy_from_user(&ulSFId, IoBuffer.InputBuffer,
-					sizeof(ulSFId)))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid SFID!!! %lu", ulSFId );
-				Status = -EFAULT;
-				break;
-			}
+
+			if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
+				return -EFAULT;
+
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId );
-			get_dsx_sf_data_to_application(Adapter, ulSFId,
-				IoBuffer.OutputBuffer);
+			get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
 			Status=STATUS_SUCCESS;
 		}
 		break;
 		case IOCTL_BCM_GET_HOST_MIBS:
 		{
-			PCHAR temp_buff;
+			PVOID temp_buff;
 
 			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from user for IoBuff failed\n");
-				Status = -EFAULT;
-				break;
-			}
+				return -EFAULT;
 
 			if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS))
 			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length Check failed %lu %zd\n", IoBuffer.OutputLength,
-											sizeof(S_MIBS_HOST_STATS_MIBS));
-	          	return -EINVAL;
+				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,
+						"Length Check failed %lu %zd\n",
+						IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS));
+				return -EINVAL;
 			}
 
-			temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
-
+			/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
+			temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL);
 			if(!temp_buff)
-			{
 				return STATUS_FAILURE;
-			}
 
-			Status = ProcessGetHostMibs(Adapter,
-					(PUCHAR)temp_buff, IoBuffer.OutputLength);
+			Status = ProcessGetHostMibs(Adapter, temp_buff);
+			GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
 
-	        Status = GetDroppedAppCntrlPktMibs((PVOID)temp_buff,
-									(PPER_TARANG_DATA)filp->private_data);
+			if (Status != STATUS_FAILURE)
+				if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS)))
+					Status = -EFAULT;
 
-			if(copy_to_user(IoBuffer.OutputBuffer,(PCHAR)temp_buff,
-				sizeof(S_MIBS_HOST_STATS_MIBS)))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy to user failed\n");
-				bcm_kfree(temp_buff);
-				return -EFAULT;
-			}
-
-			bcm_kfree(temp_buff);
+			kfree(temp_buff);
 			break;
 		}
 
@@ -1226,10 +1099,6 @@
 				Adapter->usIdleModePattern = ABORT_IDLE_MODE;
 				Adapter->bWakeUpDevice = TRUE;
 				wake_up(&Adapter->process_rx_cntrlpkt);
-				#if 0
-				Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
-				InterfaceAbortIdlemode (Adapter, Adapter->usIdleModePattern);
-				#endif
 			}
 			Status = STATUS_SUCCESS;
 			break;
@@ -1248,24 +1117,20 @@
 					Status = -EACCES;
 					break;
 				}
-				/* Copy Ioctl Buffer structure */
-				if(copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-				{
-					Status = -EFAULT;
-					break;
-				}
 
-				pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL);
+				/* Copy Ioctl Buffer structure */
+				if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+					return -EFAULT;
+
+				/* FIXME: restrict length */
+				pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
 				if(!pvBuffer)
-				{
 					return -ENOMEM;
-					break;
-				}
 
 				/* Get WrmBuffer structure */
-                if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
+				if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
 				{
-					bcm_kfree(pvBuffer);
+					kfree(pvBuffer);
 					Status = -EFAULT;
 					break;
 				}
@@ -1275,7 +1140,7 @@
 				if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
 					((ULONG)pBulkBuffer->Register & 0x3))
 				{
-					bcm_kfree(pvBuffer);
+					kfree(pvBuffer);
                     BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register);
 					Status = -EINVAL;
 					break;
@@ -1290,7 +1155,7 @@
 					(uiTempVar == EEPROM_REJECT_REG_4)) &&
 					(cmd == IOCTL_BCM_REGISTER_WRITE))
 				{
-					bcm_kfree(pvBuffer);
+					kfree(pvBuffer);
                     BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n");
 					Status = -EFAULT;
 					break;
@@ -1306,30 +1171,19 @@
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
 				}
 
-				bcm_kfree(pvBuffer);
+				kfree(pvBuffer);
 				break;
 			}
 
 		case IOCTL_BCM_GET_NVM_SIZE:
-			{
-
 			if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-			{
-				//IOLog("failed NVM first");
-				Status = -EFAULT;
-				break;
-			}
-			if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) {
-				if(copy_to_user(IoBuffer.OutputBuffer,
-					(unsigned char *)&Adapter->uiNVMDSDSize, (UINT)sizeof(UINT)))
-				{
-						Status = -EFAULT;
-						return Status;
-				}
-			}
+				return -EFAULT;
 
-			Status = STATUS_SUCCESS ;
+			if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) {
+				if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT)))
+					return -EFAULT;
 			}
+			Status = STATUS_SUCCESS ;
 			break;
 
 		case IOCTL_BCM_CAL_INIT :
@@ -1338,40 +1192,26 @@
 				UINT uiSectorSize = 0 ;
 				if(Adapter->eNVMType == NVM_FLASH)
 				{
-					Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-					if(Status)
-					{
-						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status);
+					if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 						return -EFAULT;
-					}
-					if (get_user(uiSectorSize, (unsigned int __user *)IoBuffer.InputBuffer))
+
+					if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
 						return -EFAULT;
 
 					if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
 					{
-
-						Status = copy_to_user(IoBuffer.OutputBuffer,
-									(unsigned char *)&Adapter->uiSectorSize ,
-									(UINT)sizeof(UINT));
-						if(Status)
-						{
-								BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status);
-								return -EFAULT;
-						}
+						if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize,
+								 sizeof(UINT)))
+							return -EFAULT;
 					}
 					else
 					{
 						if(IsFlash2x(Adapter))
 						{
-							Status = copy_to_user(IoBuffer.OutputBuffer,
-									(unsigned char *)&Adapter->uiSectorSize ,
-									(UINT)sizeof(UINT));
-							if(Status)
-							{
-									BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status);
-									return -EFAULT;
-							}
-
+							if (copy_to_user(IoBuffer.OutputBuffer,
+									 &Adapter->uiSectorSize ,
+									 sizeof(UINT)))
+							    return -EFAULT;
 						}
 						else
 						{
@@ -1395,25 +1235,19 @@
 			}
 			break;
         case IOCTL_BCM_SET_DEBUG :
+#ifdef DEBUG
             {
                 USER_BCM_DBG_STATE sUserDebugState;
 
 //				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG );
 
 				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
-				Status = copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy from user failed\n");
-					Status = -EFAULT;
-					break;
-				}
-				Status = copy_from_user(&sUserDebugState,IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,  "Copy of IoBuffer.InputBuffer failed");
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 					return -EFAULT;
-				}
+
+				if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)))
+					return -EFAULT;
+
 
 				BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
 				sUserDebugState.OnOff, sUserDebugState.Type);
@@ -1436,15 +1270,14 @@
                 BCM_SHOW_DEBUG_BITMAP(Adapter);
 
 			}
+#endif
 			break;
 		case IOCTL_BCM_NVM_READ:
 		case IOCTL_BCM_NVM_WRITE:
 			{
-
-				NVM_READWRITE  stNVMReadWrite = {};
+				NVM_READWRITE  stNVMReadWrite;
 				PUCHAR pReadData = NULL;
-				void __user * pBuffertobeCopied = NULL;
-				ULONG ulDSDMagicNumInUsrBuff = 0 ;
+				ULONG ulDSDMagicNumInUsrBuff = 0;
 				struct timeval tv0, tv1;
 				memset(&tv0,0,sizeof(struct timeval));
 				memset(&tv1,0,sizeof(struct timeval));
@@ -1469,21 +1302,12 @@
 			/* Copy Ioctl Buffer structure */
 
 				if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copy_from_user failed\n");
-					Status = -EFAULT;
-					break;
-				}
-				if(IOCTL_BCM_NVM_READ == cmd)
-					pBuffertobeCopied = IoBuffer.OutputBuffer;
-				else
-					pBuffertobeCopied = IoBuffer.InputBuffer;
+					return -EFAULT;
 
-				if(copy_from_user(&stNVMReadWrite, pBuffertobeCopied,sizeof(NVM_READWRITE)))
-				{
-					Status = -EFAULT;
-					break;
-				}
+				if(copy_from_user(&stNVMReadWrite,
+						  (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
+						  sizeof(NVM_READWRITE)))
+					return -EFAULT;
 
 				//
 				// Deny the access if the offset crosses the cal area limit.
@@ -1496,18 +1320,15 @@
 					break;
 				}
 
-				pReadData =(PCHAR)kmalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
-
+				pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
 				if(!pReadData)
 					return -ENOMEM;
 
-				memset(pReadData,0,stNVMReadWrite.uiNumBytes);
-
 				if(copy_from_user(pReadData, stNVMReadWrite.pBuffer,
 							stNVMReadWrite.uiNumBytes))
 				{
 					Status = -EFAULT;
-					bcm_kfree(pReadData);
+					kfree(pReadData);
 					break;
 				}
 
@@ -1522,7 +1343,7 @@
 					{
 						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
 						up(&Adapter->NVMRdmWrmLock);
-						bcm_kfree(pReadData);
+						kfree(pReadData);
 						return -EACCES;
 					}
 
@@ -1533,13 +1354,12 @@
 
 					if(Status != STATUS_SUCCESS)
 						{
-							bcm_kfree(pReadData);
+							kfree(pReadData);
 							return Status;
 						}
-					if(copy_to_user(stNVMReadWrite.pBuffer,
-							pReadData, (UINT)stNVMReadWrite.uiNumBytes))
+					if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes))
 						{
-							bcm_kfree(pReadData);
+							kfree(pReadData);
 							Status = -EFAULT;
 						}
 				}
@@ -1554,7 +1374,7 @@
 					{
 						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
 						up(&Adapter->NVMRdmWrmLock);
-						bcm_kfree(pReadData);
+						kfree(pReadData);
 						return -EACCES;
 					}
 
@@ -1582,7 +1402,7 @@
 							{
 								BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
 								up(&Adapter->NVMRdmWrmLock);
-								bcm_kfree(pReadData);
+								kfree(pReadData);
 								return Status;
 							}
 
@@ -1591,7 +1411,7 @@
 							{
 								BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
 								up(&Adapter->NVMRdmWrmLock);
-								bcm_kfree(pReadData);
+								kfree(pReadData);
 								return Status;
 							}
 						}
@@ -1608,7 +1428,7 @@
 
 					if(Status != STATUS_SUCCESS)
 					{
-						bcm_kfree(pReadData);
+						kfree(pReadData);
 						return Status;
 					}
 				}
@@ -1616,7 +1436,7 @@
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000);
 
 
-				bcm_kfree(pReadData);
+				kfree(pReadData);
 				Status = STATUS_SUCCESS;
 			}
 			break;
@@ -1629,7 +1449,7 @@
 				UINT BuffSize = 0;
 				UINT ReadBytes = 0;
 				UINT ReadOffset = 0;
-				char __user *OutPutBuff = NULL;
+				void __user *OutPutBuff;
 
 				if(IsFlash2x(Adapter) != TRUE)
 				{
@@ -1638,20 +1458,12 @@
 				}
 
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
-				Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 					return -EFAULT;
-				}
 
 				//Reading FLASH 2.x READ structure
-				Status = copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Input Buffer failed");
+				if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)))
 					return -EFAULT;
-				}
 
 
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section);
@@ -1687,7 +1499,7 @@
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
 					up(&Adapter->NVMRdmWrmLock);
-					bcm_kfree(pReadBuff);
+					kfree(pReadBuff);
 					return -EACCES;
 				}
 
@@ -1715,7 +1527,6 @@
 				 	if(Status)
 				 	{
 				 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status);
-						Status = -EFAULT;
 						break;
 				 	}
 					NOB = NOB - ReadBytes;
@@ -1727,15 +1538,15 @@
 
 				}
 				up(&Adapter->NVMRdmWrmLock);
-				bcm_kfree(pReadBuff);
+				kfree(pReadBuff);
 
 			 }
 			 break ;
 		case IOCTL_BCM_FLASH2X_SECTION_WRITE :
 			 {
 			 	FLASH2X_READWRITE sFlash2xWrite = {0};
-				PUCHAR pWriteBuff = NULL;
-				void __user *InputAddr = NULL;
+				PUCHAR pWriteBuff;
+				void __user *InputAddr;
 				UINT NOB = 0;
 				UINT BuffSize = 0;
 				UINT WriteOffset = 0;
@@ -1752,33 +1563,17 @@
 
 
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
-				Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 					return -EFAULT;
-				}
 
 				//Reading FLASH 2.x READ structure
-				Status = copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reading of output Buffer from IOCTL buffer fails");
+				if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
 					return -EFAULT;
-				}
 
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section);
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset);
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes);
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify);
-				#if 0
-				if((sFlash2xWrite.Section == ISO_IMAGE1) ||(sFlash2xWrite.Section == ISO_IMAGE2) ||
-					(sFlash2xWrite.Section == DSD0) || (sFlash2xWrite.Section == DSD1) || (sFlash2xWrite.Section == DSD2))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"ISO/DSD Image write is not allowed....  ");
-					return STATUS_FAILURE ;
-				}
-				#endif
 				if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) &&
 					(sFlash2xWrite.Section != VSA2) )
 				{
@@ -1798,12 +1593,10 @@
 				else
 					BuffSize = NOB ;
 
-				pWriteBuff = (PCHAR)kmalloc(BuffSize, GFP_KERNEL);
+				pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
 				if(pWriteBuff == NULL)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
 					return -ENOMEM;
-				}
+
 
 				//extracting the remainder of the given offset.
 				WriteBytes = Adapter->uiSectorSize ;
@@ -1820,7 +1613,7 @@
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
 					up(&Adapter->NVMRdmWrmLock);
-					bcm_kfree(pWriteBuff);
+					kfree(pWriteBuff);
 					return -EACCES;
 				}
 
@@ -1831,7 +1624,6 @@
 				 	if(Status)
 				 	{
 				 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status);
-						Status = -EFAULT;
 						break ;
 				 	}
 					BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes);
@@ -1859,28 +1651,22 @@
 				}	while(NOB > 0);
 				BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section);
 				up(&Adapter->NVMRdmWrmLock);
-				bcm_kfree(pWriteBuff);
+				kfree(pWriteBuff);
 			 }
 			 break ;
 		case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP :
 			 {
 
-			 	PFLASH2X_BITMAP psFlash2xBitMap = NULL ;
+				 PFLASH2X_BITMAP psFlash2xBitMap;
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
 
-				Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 					return -EFAULT;
-				}
-				if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Structure size mismatch Lib :0x%lx Driver :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH2X_BITMAP));
-					break;
-				}
 
-				psFlash2xBitMap = (PFLASH2X_BITMAP)kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
+				if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
+					return -EINVAL;
+
+				psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
 				if(psFlash2xBitMap == NULL)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available");
@@ -1895,20 +1681,16 @@
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
 					up(&Adapter->NVMRdmWrmLock);
-					bcm_kfree(psFlash2xBitMap);
+					kfree(psFlash2xBitMap);
 					return -EACCES;
 				}
 
 				BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
 				up(&Adapter->NVMRdmWrmLock);
-				Status = copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x bitMap failed");
-					bcm_kfree(psFlash2xBitMap);
-					return -EFAULT;
-				}
-				bcm_kfree(psFlash2xBitMap);
+				if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)))
+					Status = -EFAULT;
+
+				kfree(psFlash2xBitMap);
 			 }
 			 break ;
 		case IOCTL_BCM_SET_ACTIVE_SECTION :
@@ -1926,14 +1708,14 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-					return -EFAULT;
+					return Status;
 				}
 
 				Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT));
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
-					return -EFAULT;
+					return Status;
 				}
 
 				down(&Adapter->NVMRdmWrmLock);
@@ -1961,29 +1743,6 @@
 				Adapter->bAllDSDWriteAllow = FALSE ;
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
 
-				#if 0
-				SECTION_TYPE section = 0 ;
-
-
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION Called");
-				Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of IOCTL BUFFER failed");
-					return -EFAULT;
-				}
-				Status = copy_from_user((PCHAR)section,(PCHAR)&IoBuffer, sizeof(INT));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of section type failed failed");
-					return -EFAULT;
-				}
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", section);
-			 	if(section == DSD)
-					Adapter->ulFlashCalStart = Adapter->uiActiveDSDOffsetAtFwDld ;
-				else
-					Status = STATUS_FAILURE ;
-				#endif
 				Status = STATUS_SUCCESS ;
 			 }
 			 break ;
@@ -2004,14 +1763,14 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
-					return -EFAULT;
+					return Status;
 				}
 
-				Status = copy_from_user(&sCopySectStrut,IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
+				Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
-					return -EFAULT;
+					return Status;
 				}
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection);
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection);
@@ -2082,7 +1841,6 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-					Status = -EFAULT;
 					break;
 				}
 				if(Adapter->eNVMType != NVM_FLASH)
@@ -2095,35 +1853,18 @@
 				{
 
 					if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO))
-					{
-						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. \nRequired size :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH2X_CS_INFO));
-						Status = -EINVAL;
-						break;
-					}
+						return -EINVAL;
 
-					Status = copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO));
-					if(Status)
-					{
-						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x cs info failed");
-						Status = -EFAULT;
-						break;
-					}
+					if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)))
+						return -EFAULT;
 				}
 				else
 				{
 					if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO))
-					{
-						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. Required size :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH_CS_INFO));
-						Status = -EINVAL;
-						break;
-					}
-					Status = copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO));
-					if(Status)
-					{
-						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash CS info failed");
-						Status = -EFAULT;
-						break;
-					}
+						return -EINVAL;
+
+					if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)))
+						return -EFAULT;
 
 			 	 }
 			  }
@@ -2145,13 +1886,13 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-					return -EFAULT;
+					return Status;
 				}
-				Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT));
+				Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
-					return -EFAULT;
+					return Status;
 				}
 
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal);
@@ -2181,13 +1922,13 @@
 		case IOCTL_BCM_NVM_RAW_READ :
 			 {
 
-				NVM_READWRITE  stNVMRead = {};
+				 NVM_READWRITE stNVMRead;
 				INT NOB ;
 				INT BuffSize ;
 				INT ReadOffset = 0;
 				UINT ReadBytes = 0 ;
-				PUCHAR pReadBuff = NULL ;
-				char __user *OutPutBuff = NULL ;
+				PUCHAR pReadBuff;
+				void __user *OutPutBuff;
 
 				if(Adapter->eNVMType != NVM_FLASH)
 				{
@@ -2204,10 +1945,7 @@
 				}
 
 				if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE)))
-				{
-					Status = -EFAULT;
-					break;
-				}
+					return -EFAULT;
 
 				NOB = stNVMRead.uiNumBytes;
 				//In Raw-Read max Buff size : 64MB
@@ -2217,11 +1955,10 @@
 				else
 					BuffSize = NOB ;
 
-				ReadOffset = stNVMRead.uiOffset ;
+				ReadOffset = stNVMRead.uiOffset;
 				OutPutBuff = stNVMRead.pBuffer;
 
-
-				pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
+				pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
 				if(pReadBuff == NULL)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
@@ -2235,7 +1972,7 @@
 					(Adapter->bPreparingForLowPowerMode ==TRUE))
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
-					bcm_kfree(pReadBuff);
+					kfree(pReadBuff);
 					up(&Adapter->NVMRdmWrmLock);
 					return -EACCES;
 				}
@@ -2256,13 +1993,12 @@
 						break;
 					}
 
-					BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes);
+					BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes);
 
 					Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
 				 	if(Status)
 				 	{
 				 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status);
-						Status = -EFAULT;
 						break;
 				 	}
 					NOB = NOB - ReadBytes;
@@ -2275,7 +2011,7 @@
 				}
 				Adapter->bFlashRawRead = FALSE ;
 				up(&Adapter->NVMRdmWrmLock);
-				bcm_kfree(pReadBuff);
+				kfree(pReadBuff);
 				break ;
 			 }
 
@@ -2288,7 +2024,6 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space");
-					Status = -EFAULT;
 					break;
 				}
 
@@ -2296,7 +2031,6 @@
 				if(Status)
 				{
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space");
-					Status = -EFAULT;
 					break;
 				}
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask);
@@ -2315,71 +2049,44 @@
 				DevInfo.u32NVMType = Adapter->eNVMType;
 				DevInfo.u32InterfaceType = BCM_USB;
 
-				Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-					Status = -EFAULT;
-					break;
-				}
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+					return -EFAULT;
+
 				if(IoBuffer.OutputLength < sizeof(DevInfo))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length is less than actural buffer size");
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"user passed buffer size :0x%lX, expected size :0x%zx",IoBuffer.OutputLength, sizeof(DevInfo));
-					Status = -EINVAL;
-					break;
-				}
-				Status = copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying Dev info structure to user space buffer failed");
-					Status = -EFAULT;
-					break;
-				}
+					return -EINVAL;
+
+				if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
+					return -EFAULT;
 			}
 			break ;
 
 			case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
 			{
 				ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
-				struct timeval tv = {0} ;
 
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
 
-				Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-					Status = -EFAULT;
-					break;
-				}
+				if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
+					return -EFAULT;
+
 				if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length:0x%lx is less than expected buff size :0x%zX",IoBuffer.OutputLength,sizeof(ST_TIME_ELAPSED));
-					Status = -EINVAL;
-					break;
-				}
+					return -EINVAL;
 
-				//stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = Adapter->liTimeSinceLastNetEntry;
-				do_gettimeofday(&tv);
-				stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = tv.tv_sec - Adapter->liTimeSinceLastNetEntry;
+				stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
 
-				Status = copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED));
-				if(Status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying ST_TIME_ELAPSED structure to user space buffer failed");
-					Status = -EFAULT;
-					break;
-				}
+				if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
+					return -EFAULT;
 
 			}
 			break;
 
-		default:
-            BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "wrong input %x",cmd);
-			BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In default ioctl %d\n", cmd);
-			 Status = STATUS_FAILURE;
+		case IOCTL_CLOSE_NOTIFICATION:
+			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION");
+			break;
 
+		default:
+			pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
+			Status = STATUS_FAILURE;
 			break;
 	}
 	return Status;
@@ -2395,59 +2102,37 @@
 	.llseek = no_llseek,
 };
 
+extern struct class *bcm_class;
 
 int register_control_device_interface(PMINI_ADAPTER Adapter)
 {
+
 	if(Adapter->major>0)
-    	return Adapter->major;
-    Adapter->major = register_chrdev(0, "tarang", &bcm_fops);
-    if(Adapter->major < 0)
-    {
-    	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "register_chrdev:Failed to registering WiMax control char device!");
-        return Adapter->major;
-    }
+		return Adapter->major;
 
-	bcm_class = NULL;
-	bcm_class = class_create (THIS_MODULE, "tarang");
-	if(IS_ERR (bcm_class))
-	{
-    	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unable to create class\n");
-        unregister_chrdev(Adapter->major, "tarang");
-		Adapter->major = 0;
-		return -ENODEV;
+	Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops);
+	if(Adapter->major < 0) {
+		pr_err(DRV_NAME ": could not created character device\n");
+		return Adapter->major;
 	}
+
 	Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL,
-								MKDEV(Adapter->major, 0),
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)
-								NULL	,
-#endif
-								"tarang");
+							MKDEV(Adapter->major, 0), Adapter,
+							DEV_NAME);
 
-	if(IS_ERR(Adapter->pstCreatedClassDevice))
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "class device did not get created : %ld", PTR_ERR(Adapter->pstCreatedClassDevice) );
+	if(IS_ERR(Adapter->pstCreatedClassDevice)) {
+		pr_err(DRV_NAME ": class device create failed\n");
+		unregister_chrdev(Adapter->major, DEV_NAME);
+		return PTR_ERR(Adapter->pstCreatedClassDevice);
 	}
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Got Major No: %d", Adapter->major);
-    return 0;
+			
+	return 0;
 }
 
 void unregister_control_device_interface(PMINI_ADAPTER Adapter)
 {
-	if(Adapter->major > 0)
-	{
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying class device");
+	if(Adapter->major > 0) {
 		device_destroy (bcm_class, MKDEV(Adapter->major, 0));
+		unregister_chrdev(Adapter->major, DEV_NAME);
 	}
-    if(!IS_ERR(bcm_class))
-	{
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying created class ");
-        class_destroy (bcm_class);
-		bcm_class = NULL;
-	}
-	if(Adapter->major > 0)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"unregistering character interface");
-        unregister_chrdev(Adapter->major, "tarang");
-	}
-
 }
diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c
index bc29698..a6ce239 100644
--- a/drivers/staging/bcm/Bcmnet.c
+++ b/drivers/staging/bcm/Bcmnet.c
@@ -1,264 +1,238 @@
 #include "headers.h"
 
-static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev)
-{
-	struct net_device *ndev = (struct net_device*)dev;
-    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
-	//PMINI_ADAPTER 	Adapter = (PMINI_ADAPTER)ndev->priv;
-	if(strncmp(ndev->name,gblpnetdev->name,5)==0)
-	{
-		switch(event)
-		{
-			case NETDEV_CHANGEADDR:
-			case NETDEV_GOING_DOWN:
-				/*ignore this */
-					break;
-			case NETDEV_DOWN:
-				break;
-
-			case NETDEV_UP:
-				break;
-
-			case NETDEV_REGISTER:
-				 /* Increment the Reference Count for "veth0" */
-				 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n",
-									netdev_refcnt_read(ndev));
-				 dev_hold(ndev);
-				 break;
-
-			case NETDEV_UNREGISTER:
-				 /* Decrement the Reference Count for "veth0" */
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n",
-									netdev_refcnt_read(ndev));
-				dev_put(ndev);
-				break;
-		};
-	}
-	return NOTIFY_DONE;
-}
-
-/* Notifier block to receive netdevice events */
-static struct notifier_block bcm_notifier_block =
-{
-	.notifier_call = bcm_notify_event,
-};
-
 struct net_device *gblpnetdev;
-/***************************************************************************************/
-/* proto-type of lower function */
-#ifdef BCM_SHM_INTERFACE
-const char *bcmVirtDeviceName="bcmeth";
-#endif
 
 static INT bcm_open(struct net_device *dev)
 {
-    PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv;
-	Adapter = GET_BCM_ADAPTER(dev);
-    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
-    if(Adapter->fw_download_done==FALSE)
-        return -EINVAL;
-	Adapter->if_up=1;
-	if(Adapter->LinkUpStatus == 1){
-		if(netif_queue_stopped(Adapter->dev)){
-			netif_carrier_on(Adapter->dev);
-			netif_start_queue(Adapter->dev);
-		}
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+
+	if (Adapter->fw_download_done == FALSE) {
+		pr_notice(PFX "%s: link up failed (download in progress)\n",
+ 			  dev->name);
+		return -EBUSY;
 	}
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
-    return 0;
-}
+	if (netif_msg_ifup(Adapter))
+		pr_info(PFX "%s: enabling interface\n", dev->name);
 
-static INT bcm_close(struct net_device *dev)
-{
-   PMINI_ADAPTER Adapter = NULL ;//gpadapter ;
-   Adapter = GET_BCM_ADAPTER(dev);
-    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
-	Adapter->if_up=0;
-	if(!netif_queue_stopped(dev)) {
-		netif_carrier_off(dev);
-	    netif_stop_queue(dev);
+	if (Adapter->LinkUpStatus) {
+		if (netif_msg_link(Adapter))
+			pr_info(PFX "%s: link up\n", dev->name);
+
+		netif_carrier_on(Adapter->dev);
+		netif_start_queue(Adapter->dev);
 	}
-    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<=====");
-    return 0;
-}
-
-static struct net_device_stats *bcm_get_stats(struct net_device *dev)
-{
-    PLINUX_DEP_DATA pLinuxData=NULL;
-	PMINI_ADAPTER Adapter = NULL ;// gpadapter ;
-	Adapter = GET_BCM_ADAPTER(dev);
-    pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData);
-
-    //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData);
-	pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs;
-	pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount);
-	pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount);
-	pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount);
-	pLinuxData->netstats.rx_length_errors=0;
-	pLinuxData->netstats.rx_frame_errors=0;
-	pLinuxData->netstats.rx_crc_errors=0;
-	pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount);
-	pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount);
-	pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount);
-
-    return &(pLinuxData->netstats);
-}
-/**
-@ingroup init_functions
-Register other driver entry points with the kernel
-*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
-static struct net_device_ops bcmNetDevOps = {
-    .ndo_open		= bcm_open,
-    .ndo_stop 		= bcm_close,
-    .ndo_get_stats 	= bcm_get_stats,
-    .ndo_start_xmit	= bcm_transmit,
-    .ndo_change_mtu	= eth_change_mtu,
-    .ndo_set_mac_address = eth_mac_addr,
-    .ndo_validate_addr	= eth_validate_addr,
-};
-#endif
-
-int register_networkdev(PMINI_ADAPTER Adapter)
-{
-	int result=0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-	void **temp = NULL; /* actually we're *allocating* the device in alloc_etherdev */
-#endif
-	Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER));
-	if(!Adapter->dev)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev");
-		return -ENOMEM;
-	}
-	gblpnetdev							= Adapter->dev;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-	Adapter->dev->priv      			= Adapter;
-#else
-	temp = netdev_priv(Adapter->dev);
-	*temp = (void *)Adapter;
-#endif
-	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
-        Adapter->dev->netdev_ops                = &bcmNetDevOps;
-#else
-	Adapter->dev->open      			= bcm_open;
-	Adapter->dev->stop               	= bcm_close;
-	Adapter->dev->get_stats          	= bcm_get_stats;
-	Adapter->dev->hard_start_xmit    	= bcm_transmit;
-	Adapter->dev->hard_header_len    	= ETH_HLEN + LEADER_SIZE;
-#endif
-
-#ifndef BCM_SHM_INTERFACE
-	Adapter->dev->mtu					= MTU_SIZE; /* 1400 Bytes */
-	/* Read the MAC Address from EEPROM */
-	ReadMacAddressFromNVM(Adapter);
-
-
-	/* Register the notifier block for getting netdevice events */
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n");
-	result = register_netdevice_notifier(&bcm_notifier_block);
-	if(result)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered");
-		Adapter->bNetdeviceNotifierRegistered = FALSE;
-		return result;
-	}
-	else
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered");
-		Adapter->bNetdeviceNotifierRegistered = TRUE;
-	}
-
-#else
-
-	Adapter->dev->mtu			= CPE_MTU_SIZE;
-
-#if 0
-	//for CPE - harcode the virtual mac address
-	Adapter->dev->dev_addr[0] =  MII_WIMAX_MACADDRESS[0];
-	Adapter->dev->dev_addr[1] =  MII_WIMAX_MACADDRESS[1];
-	Adapter->dev->dev_addr[2] =  MII_WIMAX_MACADDRESS[2];
-	Adapter->dev->dev_addr[3] =  MII_WIMAX_MACADDRESS[3];
-	Adapter->dev->dev_addr[4] =  MII_WIMAX_MACADDRESS[4];
-	Adapter->dev->dev_addr[5] =  MII_WIMAX_MACADDRESS[5];
-#else
-	ReadMacAddressFromNVM(Adapter);
-#endif
-	strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name
-
-#endif
-
-	result = register_netdev(Adapter->dev);
-	if (!result)
-	{
-		Adapter->bNetworkInterfaceRegistered = TRUE ;
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name);
-	}
-	else
-	{
-    	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!");
-		Adapter->bNetworkInterfaceRegistered = FALSE ;
-		return result;
-	}
-
-#if 0
- Adapter->stDebugState.debug_level = DBG_LVL_CURR;
- Adapter->stDebugState.type =(UINT)0xffffffff;
- Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff;
- Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff;
- Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff;
- Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff;
-
- printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type);
- printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]);
- printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]);
- printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]);
-#endif
 
 	return 0;
 }
 
-void bcm_unregister_networkdev(PMINI_ADAPTER Adapter)
+static INT bcm_close(struct net_device *dev)
 {
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n");
-	if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered)
-		unregister_netdev(Adapter->dev);
-		/* Unregister the notifier block */
-	if(Adapter->bNetdeviceNotifierRegistered == TRUE)
-	{
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n");
-			unregister_netdevice_notifier(&bcm_notifier_block);
-  }
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+
+	if (netif_msg_ifdown(Adapter))
+		pr_info(PFX "%s: disabling interface\n", dev->name);
+
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	return 0;
 }
 
-static int bcm_init(void)
+static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
+	return ClassifyPacket(netdev_priv(dev), skb);
+}
+
+/*******************************************************************
+* Function    -	bcm_transmit()
+*
+* Description - This is the main transmit function for our virtual
+*		interface(eth0). It handles the ARP packets. It
+*		clones this packet and then Queue it to a suitable
+* 		Queue. Then calls the transmit_packet().
+*
+* Parameter   -	 skb - Pointer to the socket buffer structure
+*		 dev - Pointer to the virtual net device structure
+*
+*********************************************************************/
+
+static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
+{
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+	u16 qindex = skb_get_queue_mapping(skb);
+
+
+	if (Adapter->device_removed || !Adapter->LinkUpStatus)
+		goto drop;
+
+	if (Adapter->TransferMode != IP_PACKET_ONLY_MODE)
+		goto drop;
+
+	if (INVALID_QUEUE_INDEX == qindex)
+		goto drop;
+
+	if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >=
+	    SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
+		return NETDEV_TX_BUSY;
+
+	/* Now Enqueue the packet */
+	if (netif_msg_tx_queued(Adapter))
+		pr_info(PFX "%s: enqueueing packet to queue %d\n",
+			dev->name, qindex);
+
+	spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
+	Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
+	Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
+
+	*((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies;
+	ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
+		      Adapter->PackInfo[qindex].LastTxQueue, skb);
+	atomic_inc(&Adapter->TotalPacketCount);
+	spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
+
+	/* FIXME - this is racy and incorrect, replace with work queue */
+	if (!atomic_read(&Adapter->TxPktAvail)) {
+		atomic_set(&Adapter->TxPktAvail, 1);
+		wake_up(&Adapter->tx_packet_wait_queue);
+	}
+	return NETDEV_TX_OK;
+
+ drop:
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+
+
+/**
+@ingroup init_functions
+Register other driver entry points with the kernel
+*/
+static const struct net_device_ops bcmNetDevOps = {
+    .ndo_open		= bcm_open,
+    .ndo_stop 		= bcm_close,
+    .ndo_start_xmit	= bcm_transmit,
+    .ndo_change_mtu	= eth_change_mtu,
+    .ndo_set_mac_address = eth_mac_addr,
+    .ndo_validate_addr	= eth_validate_addr,
+    .ndo_select_queue	= bcm_select_queue,
+};
+
+static struct device_type wimax_type = {
+	.name	= "wimax",
+};
+
+static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	cmd->supported		= 0;
+	cmd->advertising	= 0;
+	cmd->speed		= SPEED_10000;
+	cmd->duplex		= DUPLEX_FULL;
+	cmd->port		= PORT_TP;
+	cmd->phy_address	= 0;
+	cmd->transceiver	= XCVR_INTERNAL;
+	cmd->autoneg		= AUTONEG_DISABLE;
+	cmd->maxtxpkt		= 0;
+	cmd->maxrxpkt		= 0;
+	return 0;
+}
+
+static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+	PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
+	struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
+		 Adapter->uiFlashLayoutMajorVersion,
+		 Adapter->uiFlashLayoutMinorVersion);
+
+	usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
+}
+
+static u32 bcm_get_link(struct net_device *dev)
+{
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+
+	return Adapter->LinkUpStatus;
+}
+
+static u32 bcm_get_msglevel (struct net_device *dev)
+{
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+
+	return Adapter->msg_enable;
+}
+
+static void bcm_set_msglevel (struct net_device *dev, u32 level)
+{
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
+
+	Adapter->msg_enable = level;
+}
+
+static const struct ethtool_ops bcm_ethtool_ops = {
+	.get_settings	= bcm_get_settings,
+	.get_drvinfo	= bcm_get_drvinfo,
+	.get_link 	= bcm_get_link,
+	.get_msglevel	= bcm_get_msglevel,
+	.set_msglevel	= bcm_set_msglevel,
+};
+
+int register_networkdev(PMINI_ADAPTER Adapter)
+{
+	struct net_device *net = Adapter->dev;
+	PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
+	struct usb_interface *udev = IntfAdapter->interface;
+	struct usb_device *xdev = IntfAdapter->udev;
+
 	int result;
-   	result = InterfaceInitialize();
-	if(result)
-	{
- 		printk("Initialisation failed for usbbcm");
+
+	net->netdev_ops = &bcmNetDevOps;
+	net->ethtool_ops = &bcm_ethtool_ops;
+	net->mtu = MTU_SIZE;	/* 1400 Bytes */
+	net->tx_queue_len = TX_QLEN;
+	net->flags |= IFF_NOARP;
+
+	netif_carrier_off(net);
+
+	SET_NETDEV_DEVTYPE(net, &wimax_type);
+
+	/* Read the MAC Address from EEPROM */
+	result = ReadMacAddressFromNVM(Adapter);
+	if (result != STATUS_SUCCESS) {
+		dev_err(&udev->dev,
+			PFX "Error in Reading the mac Address: %d", result);
+ 		return -EIO;
 	}
-	else
-	{
-		printk("Initialised usbbcm");
-	}
-	return result;
+
+	result = register_netdev(net);
+	if (result)
+		return result;
+
+	gblpnetdev = Adapter->dev;
+
+	if (netif_msg_probe(Adapter))
+		dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n",
+			 net->name, xdev->bus->bus_name, xdev->devpath,
+			 net->dev_addr);
+
+	return 0;
 }
 
-
-static void bcm_exit(void)
+void unregister_networkdev(PMINI_ADAPTER Adapter)
 {
-    printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__);
-	InterfaceExit();
-    printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__);
+	struct net_device *net = Adapter->dev;
+	PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
+	struct usb_interface *udev = IntfAdapter->interface;
+	struct usb_device *xdev = IntfAdapter->udev;
+
+	if (netif_msg_probe(Adapter))
+		dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n",
+			 net->name, xdev->bus->bus_name, xdev->devpath);
+ 
+	unregister_netdev(Adapter->dev);
 }
-
-module_init(bcm_init);
-module_exit(bcm_exit);
-MODULE_LICENSE ("GPL");
-
-
diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c
index 6f388a3..a685cad 100644
--- a/drivers/staging/bcm/CmHost.c
+++ b/drivers/staging/bcm/CmHost.c
@@ -15,6 +15,7 @@
 	eDeleteClassifier
 }E_CLASSIFIER_ACTION;
 
+static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
 
 /************************************************************
 * Function	  -	SearchSfid
@@ -28,7 +29,7 @@
 * Returns	  - Queue index for this SFID(If matched)
 				Else Invalid Queue Index(If Not matched)
 ************************************************************/
-__inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
+INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
 {
 	INT 	iIndex=0;
 	for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--)
@@ -47,26 +48,16 @@
 * Returns	  - Queue index for the free SFID
 *				Else returns Invalid Index.
 ****************************************************************/
-__inline INT SearchFreeSfid(PMINI_ADAPTER Adapter)
+static INT SearchFreeSfid(PMINI_ADAPTER Adapter)
 {
 	UINT 	uiIndex=0;
+
 	for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++)
 		if(Adapter->PackInfo[uiIndex].ulSFID==0)
 			return uiIndex;
 	return NO_OF_QUEUES+1;
 }
 
-__inline int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid)
-{
-	 int iIndex=0;
-	for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--)
-		if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
-			return iIndex;
-	return NO_OF_QUEUES+1;
-
-}
-
-
 /*
 Function:				SearchClsid
 Description:			This routinue would search Classifier  having specified ClassifierID as input parameter
@@ -76,7 +67,7 @@
 Return:					int :Classifier table index of matching entry
 */
 
-__inline int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16  uiClassifierID)
+static int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16  uiClassifierID)
 {
 	unsigned int uiClassifierIndex = 0;
 	for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
@@ -94,7 +85,7 @@
 This routinue would search Free available Classifier entry in classifier table.
 @return free Classifier Entry index in classifier table for specified SF
 */
-static __inline int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
+static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
 						)
 {
 	unsigned int uiClassifierIndex = 0;
@@ -106,7 +97,7 @@
 	return MAX_CLASSIFIERS+1;
 }
 
-VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
+static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
 {
 	//deleting all the packet held in the SF
 	flush_queue(Adapter,uiSearchRuleIndex);
@@ -985,7 +976,7 @@
 
 	if(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication)
 	{
-		bcm_kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication);
+		kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication);
 		Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL;
 	}
 	Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication;
@@ -1061,12 +1052,6 @@
 		pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate	: 0x%X",
 		pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MinimumTolerableTrafficRate	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u32MinimumTolerableTrafficRate);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32RequesttransmissionPolicy	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u32RequesttransmissionPolicy);
-#endif
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength	: 0x%X",
 		pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam		: 0x%X",
@@ -1114,13 +1099,6 @@
 		pstAddIndication->sfAuthorizedSet.u8PagingPreference);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16UnsolicitedPollingInterval		: 0x%X",
 		pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "MBSZoneIdentifierassignmentLength	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignmentLength);
-	for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "MBSZoneIdentifierassignment : 0x%X",
-			pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignment[uiLoopIndex]);
-#endif
 
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "sfAuthorizedSet.u8HARQChannelMapping %x  %x %x ",
 				*(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
@@ -1158,11 +1136,6 @@
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
-#if 0
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u8ProtocolLength				:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolLength);
-#endif
 
 		for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
 			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Protocol : 0x%02X ",
@@ -1278,14 +1251,6 @@
 			pstAddIndication->sfAdmittedSet.u8QosParamSet);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficPriority			: 0x%02X",
 			pstAddIndication->sfAdmittedSet.u8TrafficPriority);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u32MaxSustainedTrafficRate	: 0x%02X",
-			ntohl(pstAddIndication->sfAdmittedSet.u32MaxSustainedTrafficRate));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u32MinimumTolerableTrafficRate	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u32MinimumTolerableTrafficRate);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u32RequesttransmissionPolicy	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u32RequesttransmissionPolicy);
-#endif
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaxTrafficBurst			: 0x%X",
 			pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MinReservedTrafficRate	: 0x%X",
@@ -1339,13 +1304,6 @@
 		pstAddIndication->sfAdmittedSet.u16TimeBase);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8PagingPreference		: 0x%X",
 		pstAddIndication->sfAdmittedSet.u8PagingPreference);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "MBSZoneIdentifierassignmentLength	: 0x%X",
-		pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignmentLength);
-	for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "MBSZoneIdentifierassignment : 0x%X",
-	pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignment[uiLoopIndex]);
-#endif
 
 
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficIndicationPreference	: 0x%02X",
@@ -1378,11 +1336,6 @@
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
-#if 0
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolLength			:0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolLength);
-#endif
 		for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
 			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Protocol: 0x%02X ",
 			psfCSType->cCPacketClassificationRule.u8Protocol);
@@ -1497,20 +1450,10 @@
 		pstAddIndication->sfActiveSet.u8QosParamSet);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficPriority			: 0x%02X",
 		pstAddIndication->sfActiveSet.u8TrafficPriority);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u32MaxSustainedTrafficRate	: 0x%02X",
-		ntohl(pstAddIndication->sfActiveSet.u32MaxSustainedTrafficRate));
-#endif
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaxTrafficBurst			: 0x%X",
 		pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MinReservedTrafficRate	: 0x%X",
 		pstAddIndication->sfActiveSet.u32MinReservedTrafficRate);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u32MinimumTolerableTrafficRate	: 0x%X",
-		pstAddIndication->sfActiveSet.u32MinimumTolerableTrafficRate);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "u32RequesttransmissionPolicy	: 0x%X",
-		pstAddIndication->sfActiveSet.u32RequesttransmissionPolicy);
-#endif
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificQoSParamLength	: 0x%02X",
 		pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificQoSParam		: 0x%02X",
@@ -1558,13 +1501,6 @@
 		pstAddIndication->sfActiveSet.u16TimeBase);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8PagingPreference		: 0x%X",
 		pstAddIndication->sfActiveSet.u8PagingPreference);
-#if 0
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " MBSZoneIdentifierassignmentLength	: 0x%X",
-		pstAddIndication->sfActiveSet.MBSZoneIdentifierassignmentLength);
-	for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " MBSZoneIdentifierassignment : 0x%X",
-		pstAddIndication->sfActiveSet.MBSZoneIdentifierassignment[uiLoopIndex]);
-#endif
 
 
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8TrafficIndicationPreference	: 0x%X",
@@ -1597,11 +1533,6 @@
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
 			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
-#if 0
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  " u8ProtocolLength				:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolLength);
-#endif
 		for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
 			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8Protocol	: 0x%X ",
 			psfCSType->cCPacketClassificationRule.u8Protocol);
@@ -1706,12 +1637,8 @@
 		return 0;
 	}
 	ulAddrSFParamSet = ntohl(ulAddrSFParamSet);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  " RestoreSFParam: Total Words of DSX Message To Read: 0x%zx  From Target At : 0x%lx ",
-				nBytesToRead/sizeof(ULONG),ulAddrSFParamSet);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "sizeof(stServiceFlowParamSI) = %zx", sizeof(stServiceFlowParamSI));
 
 	//Read out the SF Param Set At the indicated Location
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "nBytesToRead = %x", nBytesToRead);
 	if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
 		return STATUS_FAILURE;
 
@@ -1719,7 +1646,7 @@
 }
 
 
-static __inline ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG  ulAddrSFParamSet)
+static ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG  ulAddrSFParamSet)
 {
     UINT	nBytesToWrite = sizeof(stServiceFlowParamSI);
 	UINT 	uiRetVal =0;
@@ -1728,9 +1655,6 @@
 	{
 		return 0;
 	}
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  " StoreSFParam: Total Words of DSX Message To Write: 0x%zX  To Target At : 0x%lX ",(nBytesToWrite/sizeof(ULONG)),ulAddrSFParamSet);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "WRM  with %x bytes",nBytesToWrite);
 
 	uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite);
 	if(uiRetVal < 0) {
@@ -1778,7 +1702,7 @@
 	}
 	// For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver!
 
-	pstAddIndication=(stLocalSFAddIndication *)kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
+	pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
 	if(NULL==pstAddIndication)
 		return 0;
 
@@ -1844,7 +1768,7 @@
 
 	(*puBufferLength) = sizeof(stLocalSFAddIndication);
 	*(stLocalSFAddIndication *)pvBuffer = *pstAddIndication;
-	bcm_kfree(pstAddIndication);
+	kfree(pstAddIndication);
 	return 1;
 }
 
@@ -1931,7 +1855,7 @@
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
 	return pstAddIndicationDest;
 failed_restore_sf_param:
-	bcm_kfree(pstAddIndicationDest);
+	kfree(pstAddIndicationDest);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" );
 	return NULL;
 }
@@ -1988,7 +1912,7 @@
 	return 1;
 }
 
-ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
+static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
 {
 	ULONG  ulTargetDSXBufferAddress;
 	ULONG  ulTargetDsxBufferIndexToUse,ulMaxTry;
@@ -2049,7 +1973,7 @@
 {
 	if(Adapter->caDsxReqResp)
 	{
-		bcm_kfree(Adapter->caDsxReqResp);
+		kfree(Adapter->caDsxReqResp);
 	}
 	return 0;
 
@@ -2102,7 +2026,7 @@
 
 			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  " VCID = %x", ntohs(pstAddIndication->u16VCID));
 			CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
-			bcm_kfree(pstAddIndication);
+			kfree(pstAddIndication);
 		}
 		break;
 		case DSA_RSP:
@@ -2118,7 +2042,7 @@
 		case DSA_ACK:
 		{
 			UINT uiSearchRuleIndex=0;
-			struct timeval tv = {0};
+
 			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
 				ntohs(pstAddIndication->u16VCID));
             uiSearchRuleIndex=SearchFreeSfid(Adapter);
@@ -2169,7 +2093,7 @@
 					Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
                     Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
 					Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
-					bcm_kfree(pstAddIndication);
+					kfree(pstAddIndication);
 				}
 
 				else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0))
@@ -2200,14 +2124,13 @@
 							if(!Adapter->LinkUpStatus)
 							{
 								netif_carrier_on(Adapter->dev);
-    							netif_start_queue(Adapter->dev);
+								netif_start_queue(Adapter->dev);
 								Adapter->LinkUpStatus = 1;
-								do_gettimeofday(&tv);
-
+								if (netif_msg_link(Adapter))
+									pr_info(PFX "%s: link up\n", Adapter->dev->name);
 								atomic_set(&Adapter->TxPktAvail, 1);
 								wake_up(&Adapter->tx_packet_wait_queue);
-								Adapter->liTimeSinceLastNetEntry = tv.tv_sec;
-								BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============Tx Service Flow Created!");
+								Adapter->liTimeSinceLastNetEntry = get_seconds();
 							}
 						}
 					}
@@ -2218,13 +2141,13 @@
 					Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
                     Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
 					Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
-					bcm_kfree(pstAddIndication);
+					kfree(pstAddIndication);
 				}
 			}
 			else
 			{
 				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
-				bcm_kfree(pstAddIndication);
+				kfree(pstAddIndication);
 				return FALSE;
 			}
 		}
@@ -2239,7 +2162,7 @@
 			((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
 
 			CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
-			bcm_kfree(pstAddIndication);
+			kfree(pstAddIndication);
 		}
 		break;
 		case DSC_RSP:
@@ -2312,13 +2235,13 @@
 				else if(pstChangeIndication->u8CC == 6)
 				{
 					deleteSFBySfid(Adapter,uiSearchRuleIndex);
-					bcm_kfree(pstAddIndication);
+					kfree(pstAddIndication);
 				}
 			}
 			else
 			{
 				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
-				bcm_kfree(pstAddIndication);
+				kfree(pstAddIndication);
 				return FALSE;
 			}
 		}
@@ -2355,7 +2278,7 @@
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
 			break;
 	default:
-		bcm_kfree(pstAddIndication);
+		kfree(pstAddIndication);
 		return FALSE ;
 	}
 	return TRUE;
diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h
index 847782c..8f689769b 100644
--- a/drivers/staging/bcm/CmHost.h
+++ b/drivers/staging/bcm/CmHost.h
@@ -150,8 +150,6 @@
 
 ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength);
 
-ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
-
 INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
 
 INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
@@ -159,7 +157,6 @@
 
 BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer);
 
-VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex);
 
 #pragma pack (pop)
 
diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c
index 8907e21..1c7db81 100644
--- a/drivers/staging/bcm/DDRInit.c
+++ b/drivers/staging/bcm/DDRInit.c
@@ -1,6 +1,5 @@
 #include "headers.h"
 
-#ifndef BCM_SHM_INTERFACE
 
 
 #define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00
@@ -188,17 +187,6 @@
                                         {0x0f000840,0x0FFF1B00},
                                         {0x0f000870,0x00000002}
 									  };
-#if 0
-static DDR_SET_NODE asDPLL_800MHZ[] = {
-										{0x0f000810,0x00000F95},
-										{0x0f000810,0x00000F95},
-                                        {0x0f000810,0x00000F95},
-                                        {0x0f000820,0x03F1365B},
-                                        {0x0f000840,0x0FFF0000},
-                                        {0x0f000880,0x000003DD},
-                                        {0x0f000860,0x00000000}
-									  };
-#endif
 
 #define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11  //index for 0x0F007000
 static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {//      # DPLL Clock Setting
@@ -788,7 +776,7 @@
 {
 	PDDR_SETTING psDDRSetting=NULL;
 	ULONG RegCount=0;
-	ULONG value = 0;
+	UINT value = 0;
 	UINT  uiResetValue = 0;
 	UINT uiClockSetting = 0;
 	int retval = STATUS_SUCCESS;
@@ -982,7 +970,7 @@
 		{
 			value = psDDRSetting->ulRegValue;
 		}
-		retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, (PUINT)&value, sizeof(value));
+		retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value));
 		if(STATUS_SUCCESS != retval) {
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
 			break;
@@ -1298,5 +1286,4 @@
 	return retval;
 }
 
-#endif
 
diff --git a/drivers/staging/bcm/Debug.c b/drivers/staging/bcm/Debug.c
deleted file mode 100644
index 2703f30..0000000
--- a/drivers/staging/bcm/Debug.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "headers.h"
-
-static UINT current_debug_level=BCM_SCREAM;
-
-int bcm_print_buffer( UINT debug_level, const char *function_name,
-				  char *file_name, int line_number, unsigned char *buffer, int bufferlen, enum _BASE_TYPE base)
-{
-	static const char * const buff_dump_base[] = {
-		"DEC", "HEX", "OCT", "BIN"
-	};
-	if(debug_level>=current_debug_level)
-	{
-		int i=0;
-		printk("\n%s:%s:%d:Buffer dump of size 0x%x in the %s:\n", file_name, function_name, line_number, bufferlen, buff_dump_base[1]);
-		for(;i<bufferlen;i++)
-		{
-			if(i && !(i%16) )
-				printk("\n");
-			switch(base)
-			{
-				case BCM_BASE_TYPE_DEC:
-					printk("%03d ", buffer[i]);
-					break;
-				case BCM_BASE_TYPE_OCT:
-					printk("%0x03o ", buffer[i]);
-					break;
-				case BCM_BASE_TYPE_BIN:
-					printk("%02x ", buffer[i]);
-					break;
-				case BCM_BASE_TYPE_HEX:
-				default:
-					printk("%02X ", buffer[i]);
-					break;
-			}
-		}
-		printk("\n");
-	}
-	return 0;
-}
-
-
diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h
index 3d788b5..3138729 100644
--- a/drivers/staging/bcm/Debug.h
+++ b/drivers/staging/bcm/Debug.h
@@ -9,34 +9,6 @@
 #include <linux/string.h>
 #define NONE 0xFFFF
 
-typedef enum _BASE_TYPE
-{
-	BCM_BASE_TYPE_DEC,
-	BCM_BASE_TYPE_OCT,
-	BCM_BASE_TYPE_BIN,
-	BCM_BASE_TYPE_HEX,
-	BCM_BASE_TYPE_NONE,
-} BASE_TYPE, *PBASE_TYPE;
-
-int bcm_print_buffer( UINT debug_level, const char *function_name,
-				  char *file_name, int line_number, unsigned char *buffer, int bufferlen, BASE_TYPE base);
-
-#ifdef BCM_SHM_INTERFACE
-#define CPE_VIRTUAL_ERROR_CODE_BASE_ADDR		(0xBFC02E00 + 0x4C)
-// ERROR codes for debugging
-extern unsigned char u32ErrorCounter ;
-#define ERROR_DEVICE_REMOVED  0x1
-#define ERROR_LEADER_LENGTH_ZERO  0x2
-#define ERROR_LEADER_LENGTH_CORRUPTED  0x3
-#define ERROR_NO_SKBUFF  0x4
-
-#define ERROR_DL_MODULE 0xaa000000
-extern void  CPE_ERROR_LOG(unsigned int module,unsigned int code);
-
-#endif
-
-
-
 
 //--------------------------------------------------------------------------------
 
@@ -242,43 +214,33 @@
 
 //--- Only for direct printk's; "hidden" to API.
 #define DBG_TYPE_PRINTK		3
-#define PRINTKS_ON			1	// "hidden" from API, set to 0 to turn off all printk's
 
-#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) do { \
-	if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) {	\
-		printk ("%s:" string, __FUNCTION__, ##args);	\
-		printk("\n");	\
-	} else if (!Adapter)			\
-		;							\
-	else {							\
-		if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) &&	\
-		   ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
-		   		if (dbg_level & DBG_NO_FUNC_PRINT)		\
-					printk (string, ##args);						\
-				else	\
-					{												\
-					printk ("%s:" string, __FUNCTION__, ##args);	\
-					printk("\n"); \
-					} \
-		}	\
-		}	\
-} while (0)
+#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \
+	do {								\
+		if (DBG_TYPE_PRINTK == Type)				\
+			pr_info("%s:" string, __func__, ##args);	\
+		else if (Adapter &&					\
+			 (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \
+			 (Type & Adapter->stDebugState.type) &&		\
+			 (SubType & Adapter->stDebugState.subtype[Type])) { \
+			if (dbg_level & DBG_NO_FUNC_PRINT)		\
+				printk(KERN_DEBUG string, ##args);	\
+			else						\
+				printk(KERN_DEBUG "%s:" string, __func__, ##args);	\
+		}							\
+	} while (0)
 
 #define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level,  buffer, bufferlen) do { \
-		if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) {	\
-			bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX);	\
-		} else if (!Adapter)			\
-			;							\
-		else {							\
-			if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level)  && \
-			   ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
-					if (dbg_level & DBG_NO_FUNC_PRINT)		\
-						bcm_print_buffer( dbg_level, NULL, NULL, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX);						\
-					else												\
-						bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX);	\
-			}	\
-		}	\
-	} while (0)
+	if (DBG_TYPE_PRINTK == Type ||					\
+	    (Adapter &&							\
+	     (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level  && \
+	     (Type & Adapter->stDebugState.type) &&			\
+	     (SubType & Adapter->stDebugState.subtype[Type]))) {	\
+		printk(KERN_DEBUG "%s:\n", __func__);			\
+		print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET,	\
+			       16, 1, buffer, bufferlen, false);	\
+	}								\
+} while(0)
 
 
 #define BCM_SHOW_DEBUG_BITMAP(Adapter)	do { \
diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c
index 7b2ec28..2b1e9e1 100644
--- a/drivers/staging/bcm/HandleControlPacket.c
+++ b/drivers/staging/bcm/HandleControlPacket.c
@@ -11,8 +11,7 @@
 Enqueue the control packet for Application.
 @return None
 */
-VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, 	/**<Pointer to the Adapter structure*/
-								struct sk_buff *skb)				/**<Pointer to the socket buffer*/
+static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb)
 {
 	PPER_TARANG_DATA	pTarang = NULL;
 	BOOLEAN HighPriorityMessage = FALSE;
@@ -20,8 +19,10 @@
 	CHAR cntrl_msg_mask_bit = 0;
 	BOOLEAN drop_pkt_flag = TRUE ;
 	USHORT usStatus = *(PUSHORT)(skb->data);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "=====>");
-	/* Get the Leader field */
+
+	if (netif_msg_pktdata(Adapter))
+		print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
+			       16, 1, skb->data, skb->len, 0);
 
 	switch(usStatus)
 	{
@@ -134,7 +135,7 @@
     }
 	up(&Adapter->RxAppControlQueuelock);
     wake_up(&Adapter->process_read_wait_queue);
-    bcm_kfree_skb(skb);
+    dev_kfree_skb(skb);
 	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible");
 }
 
@@ -185,33 +186,7 @@
 			{
 				DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail);
 //				Adapter->RxControlHead=ctrl_packet->next;
-				((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_packets++;
-				((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_bytes+=
-				((PLEADER)ctrl_packet->data)->PLength;
 			}
-			#if 0  //Idle mode debug profiling...
-			if(*(PUSHORT)ctrl_packet->data == IDLE_MODE_STATUS)
-			{
-				puiBuffer = (PUINT)(ctrl_packet->data +sizeof(USHORT));
-				if((ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD))
-				{
-					memset(&tv, 0, sizeof(tv));
-					do_gettimeofday(&tv);
-					if((ntohl(*(puiBuffer+1)) == 0))
-					{
-						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode Wake-up Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
-					}
-					else
-					{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode req Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
-					}
-				}
-				else if((ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "GOT IDLE_MODE_SF_UPDATE MSG at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
-				}
-			}
-			#endif
 
 			spin_unlock_irqrestore (&Adapter->control_queue_lock, flags);
 		 	handle_rx_control_packet(Adapter, ctrl_packet);
@@ -234,7 +209,7 @@
 		{
 			PacketToDrop=pTarang->RxAppControlHead;
 			DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
-			bcm_kfree_skb(PacketToDrop);
+			dev_kfree_skb(PacketToDrop);
 		}
 		pTarang->AppCtrlQueueLen = 0;
 		//dropped contrl packet statistics also should be reset.
diff --git a/drivers/staging/bcm/HostMibs.h b/drivers/staging/bcm/HostMibs.h
deleted file mode 100644
index 28a5783..0000000
--- a/drivers/staging/bcm/HostMibs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _HOST_MIBS_H
-#define _HOST_MIBS_H
-
-INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
-						  PVOID ioBuffer,
-						  ULONG inputBufferLength);
-#endif
diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c
index 5ec3b89..91b6fbe 100644
--- a/drivers/staging/bcm/IPv6Protocol.c
+++ b/drivers/staging/bcm/IPv6Protocol.c
@@ -1,5 +1,9 @@
 #include "headers.h"
 
+static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
+static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
+static VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
+
 static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength)
 {
 	UCHAR *pucRetHeaderPtr = NULL;
@@ -257,7 +261,7 @@
 }
 
 
-BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
+static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
 {
 	UINT uiLoopIndex=0;
 	UINT  uiIpv6AddIndex=0;
@@ -310,7 +314,7 @@
 	return FALSE;
 }
 
-BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
+static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
 {
 	UINT uiLoopIndex=0;
 	UINT  uiIpv6AddIndex=0;
@@ -376,7 +380,7 @@
 
 }
 
-VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
+static VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
 {
 	UCHAR ucVersion;
 	UCHAR  ucPrio ;
diff --git a/drivers/staging/bcm/IPv6ProtocolHdr.h b/drivers/staging/bcm/IPv6ProtocolHdr.h
index b93f790..a0db5a1 100644
--- a/drivers/staging/bcm/IPv6ProtocolHdr.h
+++ b/drivers/staging/bcm/IPv6ProtocolHdr.h
@@ -101,15 +101,12 @@
 
 
 //Function Prototypes
-BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
-BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
 
 USHORT	IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
 					PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
 					S_CLASSIFIER_RULE *pstClassifierRule );
 
 VOID DumpIpv6Address(ULONG *puIpv6Address);
-VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
 
 extern BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
 extern BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c
index 60c0f29..df64acb 100644
--- a/drivers/staging/bcm/InterfaceDld.c
+++ b/drivers/staging/bcm/InterfaceDld.c
@@ -1,20 +1,18 @@
 #include "headers.h"
 
-#ifndef BCM_SHM_INTERFACE
 
 int InterfaceFileDownload( PVOID arg,
                         struct file *flp,
                         unsigned int on_chip_loc)
 {
-    char            *buff=NULL;
    // unsigned int    reg=0;
     mm_segment_t    oldfs={0};
     int             errno=0, len=0 /*,is_config_file = 0*/;
     loff_t          pos=0;
 	PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
 	//PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
+    char            *buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
 
-    buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
     if(!buff)
     {
         return -ENOMEM;
@@ -49,7 +47,7 @@
         on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
 	}/* End of for(;;)*/
 
-	bcm_kfree(buff);
+	kfree(buff);
     return errno;
 }
 
@@ -57,7 +55,7 @@
                         struct file *flp,
                         unsigned int on_chip_loc)
 {
-    char            *buff=NULL, *buff_readback=NULL;
+    char            *buff, *buff_readback;
     unsigned int    reg=0;
     mm_segment_t    oldfs={0};
     int             errno=0, len=0, is_config_file = 0;
@@ -66,12 +64,12 @@
 	INT				Status = STATUS_SUCCESS;
 	PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
 
-    buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
-    buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
+    buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
+    buff_readback=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
     if(!buff || !buff_readback)
     {
-        bcm_kfree(buff);
-        bcm_kfree(buff_readback);
+        kfree(buff);
+        kfree(buff_readback);
 
         return -ENOMEM;
     }
@@ -138,8 +136,8 @@
         on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
     }/* End of while(1)*/
 exit:
-    bcm_kfree(buff);
-    bcm_kfree(buff_readback);
+    kfree(buff);
+    kfree(buff_readback);
 	return Status;
 }
 
@@ -165,7 +163,7 @@
 			psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
 	if(retval)
 	{
-		bcm_kfree (Adapter->pstargetparams);
+		kfree(Adapter->pstargetparams);
 		Adapter->pstargetparams = NULL;
 		return -EFAULT;
 	}
@@ -231,41 +229,6 @@
 
 	return retval;
 }
-#if 0
-static int bcm_download_buffer(PMINI_ADAPTER Adapter,
-	unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
-	unsigned long u32StartingAddress)
-{
-    char            *buff=NULL;
-    unsigned int    len = 0;
-	int 			retval = STATUS_SUCCESS;
-	buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
-
-	len = u32FirmwareLength;
-
-	while(u32FirmwareLength)
-	{
-		len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
-		if(STATUS_SUCCESS != (retval = copy_from_user(buff,
-				(unsigned char *)mappedbuffer, len)))
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
-			break;
-		}
-		retval = wrm (Adapter, u32StartingAddress, buff, len);
-		if(retval)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n");
-			break;
-		}
-		u32StartingAddress 	+= len;
-		u32FirmwareLength  	-= len;
-		mappedbuffer	   	+=len;
-	}
-	bcm_kfree(buff);
-	return retval;
-}
-#endif
 static int bcm_compare_buff_contents(unsigned char *readbackbuff,
 	unsigned char *buff,unsigned int len)
 {
@@ -297,58 +260,6 @@
 	}
 	return retval;
 }
-#if 0
-static int bcm_buffer_readback(PMINI_ADAPTER Adapter,
-	unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
-	unsigned long u32StartingAddress)
-{
-	unsigned char *buff = NULL;
-	unsigned char *readbackbuff = NULL;
-	unsigned int  len = u32FirmwareLength;
-	int retval = STATUS_SUCCESS;
-
-    buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
-	if(NULL == buff)
-		return -ENOMEM;
-	readbackbuff =  (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,
-					GFP_KERNEL);
-	if(NULL == readbackbuff)
-	{
-		bcm_kfree(buff);
-		return -ENOMEM;
-	}
-	while (u32FirmwareLength && !retval)
-	{
-		len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
-
-		/* read from the appl buff and then read from the target, compare */
-		if(STATUS_SUCCESS != (retval = copy_from_user(buff,
-				(unsigned char *)mappedbuffer, len)))
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
-			break;
-		}
-		retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
-		if(retval)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n");
-			break;
-		}
-
-		if (STATUS_SUCCESS !=
-			(retval = bcm_compare_buff_contents (readbackbuff, buff, len)))
-		{
-			break;
-		}
-		u32StartingAddress 	+= len;
-		u32FirmwareLength  	-= len;
-		mappedbuffer	   	+=len;
-	}/* end of while (u32FirmwareLength && !retval) */
-	bcm_kfree(buff);
-	bcm_kfree(readbackbuff);
-	return retval;
-}
-#endif
 int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
 {
 	int retval = STATUS_SUCCESS;
@@ -375,7 +286,7 @@
 	else
 	{
 
-		buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
+		buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
 		if(buff==NULL)
 		{
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
@@ -389,23 +300,6 @@
 			goto error ;
 		}
 
-		#if 0
-		retval = bcm_download_buffer(Adapter,
-				(unsigned char *)psFwInfo->pvMappedFirmwareAddress,
-				psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
-		if(retval != STATUS_SUCCESS)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails....");
-		}
-		retval = bcm_buffer_readback (Adapter,
-				(unsigned char *)psFwInfo->pvMappedFirmwareAddress,
-				psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
-
-		if(retval != STATUS_SUCCESS)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ....");
-		}
-		#endif
 		retval = buffDnldVerify(Adapter,
 					buff,
 					psFwInfo->u32FirmwareLength,
@@ -417,7 +311,7 @@
 		}
 	}
 error:
-	bcm_kfree(buff);
+	kfree(buff);
 	return retval;
 }
 
@@ -450,11 +344,10 @@
 			PUCHAR mappedbuffer, UINT u32FirmwareLength,
 			ULONG u32StartingAddress)
 {
-	PUCHAR readbackbuff = NULL;
 	UINT len = u32FirmwareLength;
 	INT retval = STATUS_SUCCESS;
+	PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
 
-	readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
 	if(NULL == readbackbuff)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
@@ -480,7 +373,7 @@
 		u32FirmwareLength  	-= len;
 		mappedbuffer	   	+=len;
 	}/* end of while (u32FirmwareLength && !retval) */
-	bcm_kfree(readbackbuff);
+	kfree(readbackbuff);
 	return retval;
 }
 
@@ -506,5 +399,4 @@
 	return status;
 }
 
-#endif
 
diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c
index 0750382..bf5c0ad 100644
--- a/drivers/staging/bcm/InterfaceIdleMode.c
+++ b/drivers/staging/bcm/InterfaceIdleMode.c
@@ -98,14 +98,6 @@
 			Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
 
 			wake_up(&Adapter->lowpower_mode_wait_queue);
-		#if 0
-			if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"LED Thread is Running. Hence Setting the LED Event as IDLEMODE_EXIT");
-				Adapter->DriverState = IDLEMODE_EXIT;
-				wake_up(&Adapter->LEDInfo.notify_led_event);
-			}
-		#endif
 
 		}
 		else
@@ -154,17 +146,7 @@
 	return status;
 }
 
-
-VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter)
-{
-/*	BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e);
-	BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e);
-	BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);
-	BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);*/
-	return;
-}
-
-int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
+static int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
 {
 	int 	status = STATUS_SUCCESS;
 	unsigned int value;
diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h
index 1bc723d..859a2ff 100644
--- a/drivers/staging/bcm/InterfaceIdleMode.h
+++ b/drivers/staging/bcm/InterfaceIdleMode.h
@@ -7,8 +7,6 @@
 
 VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter);
 
-INT InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern);
-
 INT InterfaceWakeUp(PMINI_ADAPTER Adapter);
 
 VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter);
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c
index 824f9a4..869ebab 100644
--- a/drivers/staging/bcm/InterfaceInit.c
+++ b/drivers/staging/bcm/InterfaceInit.c
@@ -2,14 +2,27 @@
 
 static struct usb_device_id InterfaceUsbtable[] = {
     { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) },
-	{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
-	{ USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) },
-    	{ USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
-	{ USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
-    {}
+    { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) },
+    { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) },
+    { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) },
+    { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) },
+    { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) },
+    { }
 };
+MODULE_DEVICE_TABLE(usb, InterfaceUsbtable);
 
-VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter)
+static int debug = -1;
+module_param(debug, uint, 0600);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+static const u32 default_msg =
+    NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
+    | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
+
+static INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
+
+static VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter)
 {
 	INT i = 0;
 	// Wake up the wait_queue...
@@ -48,7 +61,7 @@
 	{
 		if (psIntfAdapter->asUsbRcb[i].urb != NULL)
 		{
-			bcm_kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer);
+			kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer);
 			usb_free_urb(psIntfAdapter->asUsbRcb[i].urb);
 			psIntfAdapter->asUsbRcb[i].urb = NULL;
 		}
@@ -56,30 +69,7 @@
 	AdapterFree(psIntfAdapter->psAdapter);
 }
 
-
-
-static int usbbcm_open(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static int usbbcm_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static ssize_t usbbcm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	return 0;
-}
-
-static ssize_t usbbcm_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos)
-{
-	return 0;
-}
-
-
-VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter)
+static VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter)
 {
 	ULONG ulReg = 0;
 
@@ -157,48 +147,32 @@
 
 }
 
-static struct file_operations usbbcm_fops = {
-    .open    =  usbbcm_open,
-    .release =  usbbcm_release,
-    .read    =  usbbcm_read,
-    .write   =  usbbcm_write,
-    .owner   =  THIS_MODULE,
-	.llseek = no_llseek,
-};
-
-static struct usb_class_driver usbbcm_class = {
-    .name =     	"usbbcm",
-    .fops =     	&usbbcm_fops,
-    .minor_base =   BCM_USB_MINOR_BASE,
-};
-
 static int
 usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-	int retval =0 ;
-   	PMINI_ADAPTER psAdapter = NULL;
-	PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
-	struct usb_device      *udev = NULL;
+	struct usb_device *udev = interface_to_usbdev (intf);
+	int retval;
+	PMINI_ADAPTER psAdapter;
+	PS_INTERFACE_ADAPTER psIntfAdapter;
+	struct net_device *ndev;
 
-//	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!");
-	if((intf == NULL) || (id == NULL))
-	{
-	//	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL");
-		return -EINVAL;
-	}
-
-	/* Allocate Adapter structure */
-	if((psAdapter = kzalloc(sizeof(MINI_ADAPTER), GFP_KERNEL)) == NULL)
-	{
-		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory");
+	/* Reserve one extra queue for the bit-bucket */
+	ndev = alloc_etherdev_mq(sizeof(MINI_ADAPTER), NO_OF_QUEUES+1);
+	if(ndev == NULL) {
+		dev_err(&udev->dev, DRV_NAME ": no memory for device\n");
 		return -ENOMEM;
 	}
 
+	SET_NETDEV_DEV(ndev, &intf->dev);
+
+	psAdapter = netdev_priv(ndev);
+	psAdapter->dev = ndev;
+	psAdapter->msg_enable = netif_msg_init(debug, default_msg);
+
     /* Init default driver debug state */
 
-    psAdapter->stDebugState.debug_level = DBG_LVL_CURR;
+	psAdapter->stDebugState.debug_level = DBG_LVL_CURR;
 	psAdapter->stDebugState.type = DBG_TYPE_INITEXIT;
-	memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype));
 
     /* Technically, one can start using BCM_DEBUG_PRINT after this point.
 	 * However, realize that by default the Type/Subtype bitmaps are all zero now;
@@ -217,22 +191,21 @@
 	retval = InitAdapter(psAdapter);
 	if(retval)
 	{
-		BCM_DEBUG_PRINT (psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InitAdapter Failed\n");
+		dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n");
 		AdapterFree(psAdapter);
 		return retval;
 	}
 
 	/* Allocate interface adapter structure */
-	if((psAdapter->pvInterfaceAdapter =
-		kmalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL)) == NULL)
+	psIntfAdapter = kzalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL);
+	if (psIntfAdapter == NULL)
 	{
-		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory");
+		dev_err(&udev->dev, DRV_NAME ": no memory for Interface adapter\n");
 		AdapterFree (psAdapter);
 		return -ENOMEM;
 	}
-	memset(psAdapter->pvInterfaceAdapter, 0, sizeof(S_INTERFACE_ADAPTER));
 
-	psIntfAdapter = InterfaceAdapterGet(psAdapter);
+	psAdapter->pvInterfaceAdapter = psIntfAdapter;
 	psIntfAdapter->psAdapter = psAdapter;
 
 	/* Store usb interface in Interface Adapter */
@@ -255,8 +228,6 @@
 		usb_set_intfdata(intf, NULL);
 		udev = interface_to_usbdev (intf);
 		usb_put_dev(udev);
-		if(psAdapter->bUsbClassDriverRegistered == TRUE)
-				usb_deregister_dev (intf, &usbbcm_class);
 		InterfaceAdapterFree(psIntfAdapter);
 		return retval ;
 	}
@@ -269,7 +240,6 @@
 		}
 	}
 
-	udev = interface_to_usbdev (intf);
 	/* Check whether the USB-Device Supports remote Wake-Up */
 	if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes)
 	{
@@ -309,38 +279,26 @@
 
 static void usbbcm_disconnect (struct usb_interface *intf)
 {
-	PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
-	PMINI_ADAPTER psAdapter = NULL;
-	struct usb_device       *udev = NULL;
-    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+	PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
+	PMINI_ADAPTER psAdapter;
+	struct usb_device  *udev = interface_to_usbdev (intf);
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected");
-	if(intf == NULL)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL");
-		return;
-	}
-	psIntfAdapter = usb_get_intfdata(intf);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%p",psIntfAdapter);
 	if(psIntfAdapter == NULL)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL");
 		return;
-	}
+
 	psAdapter = psIntfAdapter->psAdapter;
+	netif_device_detach(psAdapter->dev);
+
 	if(psAdapter->bDoSuspend)
 		intf->needs_remote_wakeup = 0;
 
 	psAdapter->device_removed = TRUE ;
 	usb_set_intfdata(intf, NULL);
 	InterfaceAdapterFree(psIntfAdapter);
-	udev = interface_to_usbdev (intf);
 	usb_put_dev(udev);
-	usb_deregister_dev (intf, &usbbcm_class);
 }
 
-
-static __inline int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
+static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
 {
 	int i = 0;
 	for(i = 0; i < MAXIMUM_USB_TCB; i++)
@@ -382,13 +340,11 @@
 	status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter);
 	if(status != STATUS_SUCCESS)
 	{
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "InitCardAndDownloadFirmware failed.\n");
+		pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n");
 		return status;
 	}
 	if(TRUE == psIntfAdapter->psAdapter->fw_download_done)
 	{
-
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Sending first interrupt URB down......");
 		if(StartInterruptUrb(psIntfAdapter))
 		{
 			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB");
@@ -401,48 +357,17 @@
 					psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ);
 
 		if(value == 0)
-		{
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Mailbox Interrupt has not reached to Driver..");
-		}
-		else
-		{
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Got the mailbox interrupt ...Registering control interface...\n ");
-		}
+			pr_err(DRV_NAME ": Mailbox Interrupt has not reached to Driver..\n");
+
 		if(register_control_device_interface(psIntfAdapter->psAdapter) < 0)
 		{
-			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Register Control Device failed...");
+			pr_err(DRV_NAME ": Register Control Device failed...\n");
 			return -EIO;
 		}
 	}
 	return 0;
 }
 
-#if 0
-static void	print_usb_interface_desc(struct usb_interface_descriptor *usb_intf_desc)
-{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** INTERFACE DESCRIPTOR *********************");
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength: %x", usb_intf_desc->bLength);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType: %x", usb_intf_desc->bDescriptorType);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceNumber: %x", usb_intf_desc->bInterfaceNumber);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bAlternateSetting: %x", usb_intf_desc->bAlternateSetting);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bNumEndpoints: %x", usb_intf_desc->bNumEndpoints);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceClass: %x", usb_intf_desc->bInterfaceClass);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceSubClass: %x", usb_intf_desc->bInterfaceSubClass);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceProtocol: %x", usb_intf_desc->bInterfaceProtocol);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "iInterface :%x\n",usb_intf_desc->iInterface);
-}
-static void	print_usb_endpoint_descriptor(struct usb_endpoint_descriptor *usb_ep_desc)
-{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** ENDPOINT DESCRIPTOR *********************");
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength  :%x ", usb_ep_desc->bLength);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType  :%x ", usb_ep_desc->bDescriptorType);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bEndpointAddress  :%x ", usb_ep_desc->bEndpointAddress);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bmAttributes  :%x ", usb_ep_desc->bmAttributes);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "wMaxPacketSize  :%x ",usb_ep_desc->wMaxPacketSize);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterval  :%x ",usb_ep_desc->bInterval);
-}
-
-#endif
 
 static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
 {
@@ -518,7 +443,7 @@
 	return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd));
 }
 
-INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
+static INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
 {
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
@@ -530,20 +455,9 @@
 	UINT uiData = 0;
 
 	/* Store the usb dev into interface adapter */
-	psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(
-								psIntfAdapter->interface));
+	psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(psIntfAdapter->interface));
 
-	if((psIntfAdapter->udev->speed == USB_SPEED_HIGH))
-	{
-		psIntfAdapter->bHighSpeedDevice = TRUE ;
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO HIGH_SPEED ");
-	}
-	else
-	{
-		psIntfAdapter->bHighSpeedDevice = FALSE ;
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO FULL_SPEED ");
-	}
-
+	psIntfAdapter->bHighSpeedDevice = (psIntfAdapter->udev->speed == USB_SPEED_HIGH);
 	psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
 	psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
 
@@ -552,28 +466,27 @@
 		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n");
 		return STATUS_FAILURE;
 	}
-    if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0)))
-	{
-		psIntfAdapter->psAdapter->chip_id=(psIntfAdapter->psAdapter->chip_id&~(0xF0));
-	}
 
-	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "First RDM Chip ID 0x%lx\n", psIntfAdapter->psAdapter->chip_id);
+	if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0)))
+		psIntfAdapter->psAdapter->chip_id &= ~0xF0;
 
-    iface_desc = psIntfAdapter->interface->cur_altsetting;
-	//print_usb_interface_desc(&(iface_desc->desc));
+	dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n",
+		 psIntfAdapter->psAdapter->chip_id);
+
+	iface_desc = psIntfAdapter->interface->cur_altsetting;
 
 	if(psIntfAdapter->psAdapter->chip_id == T3B)
 	{
-
 		//
 		//T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not.
 		//
 		BeceemEEPROMBulkRead(psIntfAdapter->psAdapter,&uiData,0x0,4);
 		if(uiData == BECM)
-		{
 			bBcm16 = TRUE;
-		}
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Number of Altsetting aviailable for This Modem 0x%x\n", psIntfAdapter->interface->num_altsetting);
+
+		dev_info(&psIntfAdapter->udev->dev, "number of alternate setting %d\n",
+			 psIntfAdapter->interface->num_altsetting);
+
 		if(bBcm16 == TRUE)
 		{
 			//selecting alternate setting one as a default setting for High Speed  modem.
@@ -644,12 +557,10 @@
 	}
 
 	iface_desc = psIntfAdapter->interface->cur_altsetting;
-	//print_usb_interface_desc(&(iface_desc->desc));
-   	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Current number of endpoints :%x \n", iface_desc->desc.bNumEndpoints);
-    for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value)
+
+	for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value)
 	{
-        endpoint = &iface_desc->endpoint[value].desc;
-		//print_usb_endpoint_descriptor(endpoint);
+		endpoint = &iface_desc->endpoint[value].desc;
 
         if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint))
         {
@@ -682,10 +593,10 @@
             psIntfAdapter->sIntrIn.int_in_buffer =
 						kmalloc(buffer_size, GFP_KERNEL);
             if (!psIntfAdapter->sIntrIn.int_in_buffer) {
-                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_in_buffer");
+		    dev_err(&psIntfAdapter->udev->dev,
+			    "could not allocate interrupt_in_buffer\n");
                 return -EINVAL;
             }
-			//psIntfAdapter->sIntrIn.int_in_pipe =
         }
 
         if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint))
@@ -716,26 +627,15 @@
 	            psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size,
 														GFP_KERNEL);
 	            	if (!psIntfAdapter->sIntrOut.int_out_buffer)
-					{
-	                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_out_buffer");
-	                return -EINVAL;
-            }
+			{
+				dev_err(&psIntfAdapter->udev->dev,
+					"could not allocate interrupt_out_buffer\n");
+					return -EINVAL;
+			}
         }
     }
 	}
     usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter);
-    retval = usb_register_dev(psIntfAdapter->interface, &usbbcm_class);
-	if(retval)
-	{
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb register dev failed = %d", retval);
-		psIntfAdapter->psAdapter->bUsbClassDriverRegistered = FALSE;
-		return retval;
-	}
-	else
-	{
-		psIntfAdapter->psAdapter->bUsbClassDriverRegistered = TRUE;
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb dev registered");
-	}
 
 	psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload;
 	psIntfAdapter->psAdapter->bcm_file_readback_from_chip =
@@ -757,21 +657,13 @@
 	}
 
 
-	retval = device_run(psIntfAdapter);
-	if(retval)
-	{
-		return retval;
-	}
-
-
-	return 0;
+	return device_run(psIntfAdapter);
 }
 
 static int InterfaceSuspend (struct usb_interface *intf, pm_message_t message)
 {
 	PS_INTERFACE_ADAPTER  psIntfAdapter = usb_get_intfdata(intf);
-	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=================================\n");
-	//Bcm_kill_all_URBs(psIntfAdapter);
+
 	psIntfAdapter->bSuspended = TRUE;
 
 	if(TRUE == psIntfAdapter->bPreparingForBusSuspend)
@@ -812,57 +704,43 @@
 	return 0;
 }
 
-static int InterfacePreReset(struct usb_interface *intf)
-{
-    printk("====================>");
-	return STATUS_SUCCESS;
-}
-
-static int InterfacePostReset(struct usb_interface *intf)
-{
-    printk("Do Post chip reset setting here if it is required");
-   	return STATUS_SUCCESS;
-}
 static struct usb_driver usbbcm_driver = {
     .name = "usbbcm",
     .probe = usbbcm_device_probe,
     .disconnect = usbbcm_disconnect,
     .suspend = InterfaceSuspend,
     .resume = InterfaceResume,
-	.pre_reset=InterfacePreReset,
-	.post_reset=InterfacePostReset,
     .id_table = InterfaceUsbtable,
     .supports_autosuspend = 1,
 };
 
-
-/*
-Function:				InterfaceInitialize
-
-Description:			This is the hardware specific initialization Function.
-						Registering the driver with NDIS , other device specific NDIS
-						and hardware initializations are done here.
-
-Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
+struct class *bcm_class;
 
 
-Return:					BCM_STATUS_SUCCESS - If Initialization of the
-						HW Interface was successful.
-						Other           - If an error occured.
-*/
-INT InterfaceInitialize(void)
+static __init int bcm_init(void)
 {
-//	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!");
+	printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION);
+	printk(KERN_INFO "%s\n", DRV_COPYRIGHT);
+
+	bcm_class = class_create(THIS_MODULE, DRV_NAME);
+	if (IS_ERR(bcm_class)) {
+		printk(KERN_ERR DRV_NAME ": could not create class\n");
+		return PTR_ERR(bcm_class);
+	}
+
 	return usb_register(&usbbcm_driver);
 }
 
-INT InterfaceExit(void)
+static __exit void bcm_exit(void)
 {
-	//PMINI_ADAPTER psAdapter = NULL;
-	int status = 0;
+        class_destroy (bcm_class);
 
-	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!");
 	usb_deregister(&usbbcm_driver);
-	return status;
 }
+
+module_init(bcm_init);
+module_exit(bcm_exit);
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE ("GPL");
diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h
index e7a96e5..091cf78 100644
--- a/drivers/staging/bcm/InterfaceInit.h
+++ b/drivers/staging/bcm/InterfaceInit.h
@@ -11,6 +11,7 @@
 #define BCM_USB_PRODUCT_ID_SYM  0x15E
 #define BCM_USB_PRODUCT_ID_1901 0xe017
 #define BCM_USB_PRODUCT_ID_226  0x0132
+#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007
 
 #define BCM_USB_MINOR_BASE 		192
 
@@ -19,33 +20,7 @@
 
 INT InterfaceExit(void);
 
-#ifndef BCM_SHM_INTERFACE
-INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
-
 INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
 
-VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter);
-
-#else
-INT InterfaceAdapterInit(PMINI_ADAPTER Adapter);
-#endif
-
-
-#if 0
-
-ULONG InterfaceClaimAdapter(PMINI_ADAPTER Adapter);
-
-VOID InterfaceDDRControllerInit(PMINI_ADAPTER Adapter);
-
-ULONG InterfaceReset(PMINI_ADAPTER Adapter);
-
-ULONG InterfaceRegisterResources(PMINI_ADAPTER Adapter);
-
-VOID InterfaceUnRegisterResources(PMINI_ADAPTER Adapter);
-
-ULONG InterfaceFirmwareDownload(PMINI_ADAPTER Adapter);
-
-#endif
-
 #endif
 
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c
index f928fe4..4234647 100644
--- a/drivers/staging/bcm/InterfaceIsr.c
+++ b/drivers/staging/bcm/InterfaceIsr.c
@@ -1,6 +1,5 @@
 #include "headers.h"
 
-#ifndef BCM_SHM_INTERFACE
 
 static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
 {
@@ -8,6 +7,10 @@
 	PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context;
 	PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ;
 
+	if (netif_msg_intr(Adapter))
+		pr_info(PFX "%s: interrupt status %d\n",
+			Adapter->dev->name, status);
+
 	if(Adapter->device_removed == TRUE)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed.");
@@ -164,40 +167,3 @@
 	return status;
 }
 
-/*
-Function:				InterfaceEnableInterrupt
-
-Description:			This is the hardware specific Function for configuring
-						and enabling the interrupts on the device.
-
-Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
-
-
-Return:				BCM_STATUS_SUCCESS - If configuring the interrupts was successful.
-						Other           - If an error occured.
-*/
-
-void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter)
-{
-
-}
-
-/*
-Function:				InterfaceDisableInterrupt
-
-Description:			This is the hardware specific Function for disabling the interrupts on the device.
-
-Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
-
-
-Return:				BCM_STATUS_SUCCESS - If disabling the interrupts was successful.
-						Other           - If an error occured.
-*/
-
-void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter)
-{
-
-}
-
-#endif
-
diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c
index 8fc893b..b7d6e7a 100644
--- a/drivers/staging/bcm/InterfaceMisc.c
+++ b/drivers/staging/bcm/InterfaceMisc.c
@@ -1,17 +1,5 @@
 #include "headers.h"
 
-#ifndef BCM_SHM_INTERFACE
-
-PS_INTERFACE_ADAPTER
-InterfaceAdapterGet(PMINI_ADAPTER psAdapter)
-{
-	if(psAdapter == NULL)
-	{
-		return NULL;
-	}
-	return (PS_INTERFACE_ADAPTER)(psAdapter->pvInterfaceAdapter);
-}
-
 INT
 InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
             UINT addr,
@@ -236,9 +224,7 @@
 	}
 
 	/* Cancel All submitted TX URB's */
-	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All Submitted TX Urbs \n");
-
-    for(i = 0; i < MAXIMUM_USB_TCB; i++)
+	for(i = 0; i < MAXIMUM_USB_TCB; i++)
 	{
 		tempUrb = psIntfAdapter->asUsbTcb[i].urb;
 		if(tempUrb)
@@ -248,9 +234,6 @@
 		}
 	}
 
-
-    BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All submitted Rx Urbs \n");
-
 	for(i = 0; i < MAXIMUM_USB_RCB; i++)
 	{
 		tempUrb = psIntfAdapter->asUsbRcb[i].urb;
@@ -261,16 +244,11 @@
 		}
 	}
 
-
 	atomic_set(&psIntfAdapter->uNumTcbUsed, 0);
 	atomic_set(&psIntfAdapter->uCurrTcb, 0);
 
 	atomic_set(&psIntfAdapter->uNumRcbUsed, 0);
 	atomic_set(&psIntfAdapter->uCurrRcb, 0);
-
-	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "TCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumTcbUsed), atomic_read(&psIntfAdapter->uCurrTcb));
-	BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "RCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumRcbUsed), atomic_read(&psIntfAdapter->uCurrRcb));
-
 }
 
 VOID putUsbSuspend(struct work_struct *work)
@@ -282,9 +260,6 @@
 
 	if(psIntfAdapter->bSuspended == FALSE)
 		usb_autopm_put_interface(intf);
-	else
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n");
 
 }
 
-#endif
diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h
index 74c81d4..6c9e39b 100644
--- a/drivers/staging/bcm/InterfaceMisc.h
+++ b/drivers/staging/bcm/InterfaceMisc.h
@@ -1,9 +1,6 @@
 #ifndef __INTERFACE_MISC_H
 #define __INTERFACE_MISC_H
 
-PS_INTERFACE_ADAPTER
-InterfaceAdapterGet(PMINI_ADAPTER psAdapter);
-
 INT
 InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
 			UINT addr,
diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c
index 6fee968..533f8eb 100644
--- a/drivers/staging/bcm/InterfaceRx.c
+++ b/drivers/staging/bcm/InterfaceRx.c
@@ -1,5 +1,15 @@
 #include "headers.h"
-extern int SearchVcid(PMINI_ADAPTER , unsigned short);
+
+static int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid)
+{
+	int iIndex=0;
+
+	for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--)
+		if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
+			return iIndex;
+	return NO_OF_QUEUES+1;
+
+}
 
 
 static PUSB_RCB
@@ -38,13 +48,9 @@
 	PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
 	PLEADER pLeader = urb->transfer_buffer;
 
-
-	#if 0
-	int *puiBuffer = NULL;
-	struct timeval tv;
-	memset(&tv, 0, sizeof(tv));
-	do_gettimeofday(&tv);
-	#endif
+	if (unlikely(netif_msg_rx_status(Adapter)))
+		pr_info(PFX "%s: rx urb status %d length %d\n",
+			Adapter->dev->name, urb->status, urb->actual_length);
 
 	if((Adapter->device_removed == TRUE)  ||
 		(TRUE == Adapter->bEndPointHalted) ||
@@ -89,10 +95,10 @@
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid);
 	if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n",
-					pLeader->PLength);
-		atomic_inc(&Adapter->RxPacketDroppedCount);
-		atomic_add(pLeader->PLength, &Adapter->BadRxByteCount);
+		if (netif_msg_rx_err(Adapter))
+			pr_info(PFX "%s: corrupted leader length...%d\n",
+				Adapter->dev->name, pLeader->PLength);
+		++Adapter->dev->stats.rx_dropped;
 		atomic_dec(&psIntfAdapter->uNumRcbUsed);
 		return;
 	}
@@ -145,10 +151,9 @@
 		skb_put (skb, pLeader->PLength + ETH_HLEN);
 		Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength;
 		Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength;
-		atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount);
         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength);
 
-		if(Adapter->if_up)
+		if(netif_running(Adapter->dev))
 		{
 			/* Moving ahead by ETH_HLEN to the data ptr as received from FW */
 			skb_pull(skb, ETH_HLEN);
@@ -173,9 +178,12 @@
 		else
 		{
 		    BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
-			bcm_kfree_skb(skb);
+			dev_kfree_skb(skb);
 		}
-		atomic_inc(&Adapter->GoodRxPktCount);
+
+		++Adapter->dev->stats.rx_packets;
+		Adapter->dev->stats.rx_bytes += pLeader->PLength;
+
 		for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
 		{
 			if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))
diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c
index 771f7b3..f434b89 100644
--- a/drivers/staging/bcm/InterfaceTx.c
+++ b/drivers/staging/bcm/InterfaceTx.c
@@ -1,50 +1,5 @@
 #include "headers.h"
 
-#ifndef BCM_SHM_INTERFACE
-
-/*
-Function:				InterfaceTxDataPacket
-
-Description:			This is the hardware specific Function for Transmitting
-						data packet to the device.
-
-Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
-						PVOID Packet				-  Packet Containing the data to be transmitted
-						USHORT usVcid			   - VCID on which data packet is to be sent
-
-
-Return:				BCM_STATUS_SUCCESS - If Tx was successful.
-						Other           - If an error occured.
-*/
-
-ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid)
-{
-	ULONG	Status = 0;
-	return Status;
-}
-
-/*
-Function:				InterfaceTxControlPacket
-
-Description:			This is the hardware specific Function for Transmitting
-						control packet to the device.
-
-Input parameters:		IN PMINI_ADAPTER Adapter   - Miniport Adapter Context
-						PVOID pvBuffer			   - Buffer containg control packet
-						UINT uiBufferLength		   - Buffer Length
-
-Return:				BCM_STATUS_SUCCESS - If control packet transmit was successful.
-						Other           - If an error occured.
-*/
-
-ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength)
-{
-	ULONG	Status = 0;
-
-
-
-	return Status;
-}
 /*this is transmit call-back(BULK OUT)*/
 static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
 {
@@ -54,10 +9,10 @@
 	PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ;
 	BOOLEAN bpowerDownMsg = FALSE ;
     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
-#if 0
-	struct timeval tv;
-	UINT time_ms = 0;
-#endif
+
+    if (unlikely(netif_msg_tx_done(Adapter)))
+	    pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status);
+
 	if(urb->status != STATUS_SUCCESS)
 	{
 		if(urb->status == -EPIPE)
@@ -78,11 +33,6 @@
 
 	if(TRUE == psAdapter->bPreparingForLowPowerMode)
 	{
-		#if 0
-		do_gettimeofday(&tv);
-		time_ms = tv.tv_sec *1000 + tv.tv_usec/1000;
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms);
-		#endif
 
 		if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
 			(pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)))
@@ -162,7 +112,7 @@
 }
 
 
-static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
+static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
 {
 	PUSB_TCB pTcb = NULL;
 	UINT index = 0;
@@ -183,7 +133,7 @@
 	return pTcb;
 }
 
-static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
+static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
 {
 
 	struct urb *urb = pTcb->urb;
@@ -255,5 +205,4 @@
 	return TransmitTcb(psIntfAdapter, pTcb, data, len);
 }
 
-#endif
 
diff --git a/drivers/staging/bcm/InterfaceTx.h b/drivers/staging/bcm/InterfaceTx.h
index 053f631..2731475 100644
--- a/drivers/staging/bcm/InterfaceTx.h
+++ b/drivers/staging/bcm/InterfaceTx.h
@@ -3,11 +3,5 @@
 
 INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len);
 
-
-ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid);
-
-ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength);
-
-
 #endif
 
diff --git a/drivers/staging/bcm/Interfacemain.h b/drivers/staging/bcm/Interfacemain.h
deleted file mode 100644
index e0db563..0000000
--- a/drivers/staging/bcm/Interfacemain.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _MAIN_
-#define _MAIN_
-#if 0
-typedef struct _MINI_ADAPTER
-{
-	S_INTERFACE_ADAPTER stInterfaceAdapter;
-}MINI_ADAPTER,*PMINI_ADAPTER;
-
-#endif
-#endif
diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c
index cae3823..f4cf41c 100644
--- a/drivers/staging/bcm/LeakyBucket.c
+++ b/drivers/staging/bcm/LeakyBucket.c
@@ -75,14 +75,14 @@
 * Returns     - The number of bytes allowed for transmission.
 *
 ***********************************************************************/
-static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
+static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
 {
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>");
 	/* Validate the parameters */
 	if(NULL == Adapter || (psSF < Adapter->PackInfo &&
 		(uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority]))
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %ld\n", Adapter, (psSF-Adapter->PackInfo));
+		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", Adapter, (psSF-Adapter->PackInfo));
 		return 0;
 	}
 
@@ -94,51 +94,27 @@
 		}
 		else
 		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %ld Available %u\n",
+			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n",
 				psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
 			psSF->uiPendedLast = 1;
 		}
 	}
 	else
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %ld not valid\n", psSF-Adapter->PackInfo);
+		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo);
 	}
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
 	return 0;
 }
 
-static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet)
-{
-	struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL;
-	psQueueCurrent = pPackInfo->FirstTxQueue;
-	while(psQueueCurrent)
-	{
-		if(Packet == psQueueCurrent)
-		{
-			if(psQueueCurrent == pPackInfo->FirstTxQueue)
-			{
-				pPackInfo->FirstTxQueue=psQueueCurrent->next;
-				if(psQueueCurrent==pPackInfo->LastTxQueue)
-					pPackInfo->LastTxQueue=NULL;
-			}
-			else
-			{
-				psLastQueueNode->next=psQueueCurrent->next;
-			}
-			break;
-		}
-		psLastQueueNode = psQueueCurrent;
-		psQueueCurrent=psQueueCurrent->next;
-	}
-}
 /**
 @ingroup tx_functions
 This function despatches packet from the specified queue.
 @return Zero(success) or Negative value(failure)
 */
-static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
-								PacketInfo *psSF,		/**<Queue identifier*/
-								struct sk_buff*  Packet)	/**<Pointer to the packet to be sent*/
+static INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
+			       PacketInfo *psSF,		/**<Queue identifier*/
+			       struct sk_buff*  Packet)	/**<Pointer to the packet to be sent*/
 {
 	INT  	Status=STATUS_FAILURE;
 	UINT uiIndex =0,PktLen = 0;
@@ -180,8 +156,7 @@
 * Returns     - None.
 *
 ****************************************************************************/
-static __inline VOID CheckAndSendPacketFromIndex
-(PMINI_ADAPTER Adapter, PacketInfo *psSF)
+static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF)
 {
 	struct sk_buff	*QueuePacket=NULL;
 	char 			*pControlPacket = NULL;
@@ -189,7 +164,7 @@
 	int				iPacketLen=0;
 
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%ld ====>", (psSF-Adapter->PackInfo));
+	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo));
 	if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet
   	{
 		if(!psSF->ucDirection )
@@ -197,10 +172,8 @@
 
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
 		if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n");
-			return;
-		}
+			return;	/* in idle mode */
+
 		// Check for Free Descriptors
 		if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
 		{
@@ -208,9 +181,6 @@
 			return ;
 		}
 
-#if 0
-		PruneQueue(Adapter,(psSF-Adapter->PackInfo));
-#endif
 		spin_lock_bh(&psSF->SFQueueLock);
 		QueuePacket=psSF->FirstTxQueue;
 
@@ -240,7 +210,7 @@
 			}
 			else
 			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %ld\n", psSF-Adapter->PackInfo);
+				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo);
 				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
 					psSF->uiCurrentTokenCount, iPacketLen);
 				//this part indicates that becuase of non-availability of the tokens
@@ -290,17 +260,6 @@
 			}
 	   	}
 	}
-
-	if(Status != STATUS_SUCCESS)	//Tx of data packet to device Failed
-	{
-		if(Adapter->bcm_jiffies == 0)
-			Adapter->bcm_jiffies = jiffies;
-	}
-	else
-	{
-		Adapter->bcm_jiffies = 0;
-	}
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<=====");
 }
 
 
@@ -387,12 +346,7 @@
 		if(exit_flag == TRUE )
 		    break ;
 	}/* end of inner while loop */
-	if(Adapter->bcm_jiffies == 0 &&
-		atomic_read(&Adapter->TotalPacketCount) != 0 &&
-	   	uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount))
-	{
-		Adapter->bcm_jiffies = jiffies;
-	}
+
 	update_per_cid_rx  (Adapter);
 	Adapter->txtransmit_running = 0;
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");
diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h
index 0241234..feb3515 100644
--- a/drivers/staging/bcm/Macros.h
+++ b/drivers/staging/bcm/Macros.h
@@ -4,10 +4,6 @@
 #ifndef	__MACROS_H__
 #define __MACROS_H__
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#define kthread_run(threadfn,data,datafmt)(struct task_struct *)kernel_thread(threadfn,data,0)
-#endif
-
 #define TX_TIMER_PERIOD 10	//10 msec
 #define MAX_CLASSIFIERS 100
 //#define MAX_CLASSIFIERS_PER_SF  20
@@ -17,10 +13,9 @@
 #define MAX_DATA_PKTS 		200
 #define MAX_ETH_SIZE 		1536
 #define MAX_CNTL_PKT_SIZE 2048
-/* TIMER RELATED */
-#define JIFFIES_2_QUADPART()	(ULONG)(jiffies * 10000) // jiffies(1msec) to Quadpart(100nsec)
 
 #define MTU_SIZE 1400
+#define TX_QLEN  5
 
 #define MAC_ADDR_REGISTER 0xbf60d000
 
@@ -266,7 +261,7 @@
 
 #define FIRMWARE_BEGIN_ADDR 0xBFC00000
 
-#define INVALID_QUEUE_INDEX (USHORT)-1
+#define INVALID_QUEUE_INDEX NO_OF_QUEUES
 
 #define INVALID_PID (pid_t)-1
 #define DDR_80_MHZ  	0
@@ -300,12 +295,7 @@
 
 /* Idle Mode Related Registers */
 #define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C
-#ifdef BCM_SHM_INTERFACE
-#define SW_ABORT_IDLEMODE_LOC 		0xbfc02f9c
-#define CPE_VIRTUAL_MAILBOX_REG     0xBFC02E58
-#else
 #define SW_ABORT_IDLEMODE_LOC 		0x0FF01FFC
-#endif
 
 #define SW_ABORT_IDLEMODE_PATTERN 	0xd0ea1d1e
 #define DEVICE_INT_OUT_EP_REG0		0x0F011870
@@ -355,12 +345,7 @@
 	HYBRID_MODE_6   = 2
 }PMU_MODE;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-#define MAX_RDM_WRM_RETIRES 16
-#else
 #define MAX_RDM_WRM_RETIRES 1
-#endif
-
 
 enum eAbortPattern {
 	ABORT_SHUTDOWN_MODE = 1,
@@ -369,27 +354,6 @@
 	ABORT_IDLE_SYNCDOWN = 3
 };
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-	#define GET_BCM_ADAPTER(net_dev)  ({\
-    PMINI_ADAPTER __Adapter = NULL;	\
-    if (net_dev)    {   \
-         __Adapter = (PMINI_ADAPTER)(net_dev->priv); \
-    } \
-    else    {   \
-         __Adapter = NULL;  \
-    }__Adapter;} )
-#else
-	#define GET_BCM_ADAPTER(net_dev) ({\
-    PMINI_ADAPTER __Adapter = NULL;	\
-    if (net_dev)    {   \
-         __Adapter = (PMINI_ADAPTER)(*((unsigned long *)netdev_priv(net_dev)));  \
-    } \
-    else    {   \
-         __Adapter = NULL;  \
-    }__Adapter;})
-
-
-#endif
 
 /* Offsets used by driver in skb cb variable */
 #define SKB_CB_CLASSIFICATION_OFFSET    0
diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile
index c3ae25a..652b7f8 100644
--- a/drivers/staging/bcm/Makefile
+++ b/drivers/staging/bcm/Makefile
@@ -6,7 +6,7 @@
 
 bcm_wimax-y :=  InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \
 		InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \
-		Arp.o CmHost.o Debug.o IPv6Protocol.o Qos.o Transmit.o\
+		CmHost.o IPv6Protocol.o Qos.o Transmit.o\
 		Bcmnet.o DDRInit.o HandleControlPacket.o\
 		LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\
-	 	Osal_Misc.o led_control.o nvm.o vendorspecificextn.o
+		led_control.o nvm.o vendorspecificextn.o
diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c
index 22550f7..1bb6a1d 100644
--- a/drivers/staging/bcm/Misc.c
+++ b/drivers/staging/bcm/Misc.c
@@ -1,5 +1,12 @@
 #include "headers.h"
 
+static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path,
+                        unsigned int loc);
+static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
+static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
+static int bcm_parse_target_params(PMINI_ADAPTER Adapter);
+static void beceem_protocol_reset (PMINI_ADAPTER Adapter);
+
 static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter)
 {
 
@@ -60,21 +67,11 @@
     //init_waitqueue_head(&psAdapter->device_wake_queue);
     psAdapter->fw_download_done=FALSE;
 
-    psAdapter->pvOsDepData = (PLINUX_DEP_DATA) kmalloc(sizeof(LINUX_DEP_DATA),
-                 GFP_KERNEL);
-
-    if(psAdapter->pvOsDepData == NULL)
-	{
-        BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Linux Specific Data allocation failed");
-        return -ENOMEM;
-    }
-    memset(psAdapter->pvOsDepData, 0, sizeof(LINUX_DEP_DATA));
 
 	default_wimax_protocol_initialize(psAdapter);
 	for (i=0;i<MAX_CNTRL_PKTS;i++)
 	{
-		psAdapter->txctlpacket[i] = (char *)kmalloc(MAX_CNTL_PKT_SIZE,
-												GFP_KERNEL);
+		psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL);
 		if(!psAdapter->txctlpacket[i])
 		{
 			BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i);
@@ -117,7 +114,7 @@
 
 VOID AdapterFree(PMINI_ADAPTER Adapter)
 {
-	INT count = 0;
+	int count;
 
 	beceem_protocol_reset(Adapter);
 
@@ -125,72 +122,66 @@
 
 	if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
 	  	kthread_stop (Adapter->control_packet_handler);
+
 	if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
-    	kthread_stop (Adapter->transmit_packet_thread);
-    wake_up(&Adapter->process_read_wait_queue);
+		kthread_stop (Adapter->transmit_packet_thread);
+
+	wake_up(&Adapter->process_read_wait_queue);
+
 	if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
 		kthread_stop (Adapter->LEDInfo.led_cntrl_threadid);
-	bcm_unregister_networkdev(Adapter);
+
+	unregister_networkdev(Adapter);
+
+	/* FIXME: use proper wait_event and refcounting */
 	while(atomic_read(&Adapter->ApplicationRunning))
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning));
 		msleep(100);
 	}
 	unregister_control_device_interface(Adapter);
-	if(Adapter->dev && !IS_ERR(Adapter->dev))
-		free_netdev(Adapter->dev);
-	if(Adapter->pstargetparams != NULL)
-	{
-		bcm_kfree(Adapter->pstargetparams);
-	}
+
+	kfree(Adapter->pstargetparams);
+
 	for (count =0;count < MAX_CNTRL_PKTS;count++)
-	{
-		if(Adapter->txctlpacket[count])
-			bcm_kfree(Adapter->txctlpacket[count]);
-	}
+		kfree(Adapter->txctlpacket[count]);
+
 	FreeAdapterDsxBuffer(Adapter);
-	if(Adapter->pvOsDepData)
-		bcm_kfree (Adapter->pvOsDepData);
-	if(Adapter->pvInterfaceAdapter)
-		bcm_kfree(Adapter->pvInterfaceAdapter);
+
+	kfree(Adapter->pvInterfaceAdapter);
 
 	//Free the PHS Interface
 	PhsCleanup(&Adapter->stBCMPhsContext);
 
-#ifndef BCM_SHM_INTERFACE
 	BcmDeAllocFlashCSStructure(Adapter);
-#endif
 
-	bcm_kfree (Adapter);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n");
+	free_netdev(Adapter->dev);
 }
 
-
-int create_worker_threads(PMINI_ADAPTER psAdapter)
+static int create_worker_threads(PMINI_ADAPTER psAdapter)
 {
-	BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Init Threads...");
 	// Rx Control Packets Processing
 	psAdapter->control_packet_handler = kthread_run((int (*)(void *))
-			control_packet_handler, psAdapter, "CtrlPktHdlr");
+							control_packet_handler, psAdapter, "%s-rx", DRV_NAME);
 	if(IS_ERR(psAdapter->control_packet_handler))
 	{
-		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success\n");
+		pr_notice(DRV_NAME ": could not create control thread\n");
 		return PTR_ERR(psAdapter->control_packet_handler);
 	}
+
 	// Tx Thread
 	psAdapter->transmit_packet_thread = kthread_run((int (*)(void *))
-		tx_pkt_handler, psAdapter, "TxPktThread");
+							tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME);
 	if(IS_ERR (psAdapter->transmit_packet_thread))
 	{
-		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success");
+		pr_notice(DRV_NAME ": could not creat transmit thread\n");
 		kthread_stop(psAdapter->control_packet_handler);
 		return PTR_ERR(psAdapter->transmit_packet_thread);
 	}
 	return 0;
 }
 
-
-static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path)
+static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path)
 {
     struct file             *flp=NULL;
     mm_segment_t        oldfs;
@@ -200,26 +191,20 @@
     set_fs(oldfs);
     if(IS_ERR(flp))
     {
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable To Open File %s, err  %lx",
-				path, PTR_ERR(flp));
-		flp = NULL;
+	    pr_err(DRV_NAME "Unable To Open File %s, err %ld",
+		   path, PTR_ERR(flp));
+	    flp = NULL;
     }
-    else
-    {
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got file descriptor pointer of %s!",
-			path);
-    }
-	if(Adapter->device_removed)
-	{
-		flp = NULL;
-	}
+
+    if(Adapter->device_removed)
+	    flp = NULL;
 
     return flp;
 }
 
 
-int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
-                        char *path,     /**< path to image file */
+static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
+                        const char *path,     /**< path to image file */
                         unsigned int loc    /**< Download Address on the chip*/
                         )
 {
@@ -265,31 +250,10 @@
 	if(flp && !(IS_ERR(flp)))
     	filp_close(flp, current->files);
     set_fs(oldfs);
-    do_gettimeofday(&tv);
-    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "file download done at %lx", ((tv.tv_sec * 1000) +
-                            (tv.tv_usec/1000)));
+
     return errorno;
 }
 
-
-void bcm_kfree_skb(struct sk_buff *skb)
-{
-	if(skb)
-    {
-    	kfree_skb(skb);
-    }
-	skb = NULL ;
-}
-
-VOID bcm_kfree(VOID *ptr)
-{
-	if(ptr)
-	{
-		kfree(ptr);
-	}
-	ptr = NULL ;
-}
-
 /**
 @ingroup ctrl_pkt_functions
 This function copies the contents of given buffer
@@ -395,13 +359,6 @@
 			/*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent
 			  the wake up from idlemode is from host*/
 			//Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE;
-#if 0
-			if(STATUS_SUCCESS != InterfaceIdleModeWakeup(Adapter))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Wake up Failed\n");
-				return STATUS_FAILURE;
-			}
-#endif
 			Adapter->bWakeUpDevice = TRUE;
 			wake_up(&Adapter->process_rx_cntrlpkt);
 
@@ -489,9 +446,6 @@
 		atomic_inc(&Adapter->index_wr_txcntrlpkt);
 		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets");
 		atomic_set(&Adapter->TxPktAvail, 1);
-#ifdef BCM_SHM_INTERFACE
-		virtual_mail_box_interrupt();
-#endif
 		wake_up(&Adapter->tx_packet_wait_queue);
 	}
 	else
@@ -530,18 +484,6 @@
 #endif
 
 
-void SendLinkDown(PMINI_ADAPTER Adapter)
-{
-	LINK_REQUEST	stLinkDownRequest;
-	memset(&stLinkDownRequest, 0, sizeof(LINK_REQUEST));
-	stLinkDownRequest.Leader.Status=LINK_UP_CONTROL_REQ;
-	stLinkDownRequest.Leader.PLength=sizeof(ULONG);//minimum 4 bytes
-	stLinkDownRequest.szData[0]=LINK_DOWN_REQ_PAYLOAD;
-	Adapter->bLinkDownRequested = TRUE;
-
-	CopyBufferToControlPacket(Adapter,&stLinkDownRequest);
-}
-
 /******************************************************************
 * Function    - LinkMessage()
 *
@@ -552,7 +494,7 @@
 *
 * Returns     - None.
 *******************************************************************/
-__inline VOID LinkMessage(PMINI_ADAPTER Adapter)
+VOID LinkMessage(PMINI_ADAPTER Adapter)
 {
 	PLINK_REQUEST	pstLinkRequest=NULL;
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
@@ -594,7 +536,7 @@
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket");
 		CopyBufferToControlPacket(Adapter, pstLinkRequest);
-		bcm_kfree(pstLinkRequest);
+		kfree(pstLinkRequest);
 	}
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
 	return;
@@ -614,8 +556,8 @@
 VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer)
 {
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__);
-	Adapter->StatisticsPointer = ntohl(*(PULONG)pvBuffer);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %lx", Adapter->StatisticsPointer);
+	Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
+	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer);
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__);
 	return;
 }
@@ -787,12 +729,10 @@
 			down(&Adapter->rdmwrmsync);
 			Adapter->bPreparingForLowPowerMode = TRUE;
 			up(&Adapter->rdmwrmsync);
-#ifndef BCM_SHM_INTERFACE
 			//Killing all URBS.
 			if(Adapter->bDoSuspend == TRUE)
 				Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
 
-#endif
 		}
 		else
 		{
@@ -811,9 +751,7 @@
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n");
 		Adapter->bPreparingForLowPowerMode = FALSE;
-#ifndef BCM_SHM_INTERFACE
 		StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
-#endif
 	}
 	do_gettimeofday(&tv);
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
@@ -980,12 +918,10 @@
 
 }
 
-
-__inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
+int reset_card_proc(PMINI_ADAPTER ps_adapter)
 {
 	int retval = STATUS_SUCCESS;
 
-#ifndef BCM_SHM_INTERFACE
     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
 	PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
 	unsigned int value = 0, uiResetValue = 0;
@@ -1006,11 +942,9 @@
 		wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
 	}
 
-#ifndef BCM_SHM_INTERFACE
 	//killing all submitted URBs.
 	psIntfAdapter->psAdapter->StopAllXaction = TRUE ;
 	Bcm_kill_all_URBs(psIntfAdapter);
-#endif
 	/* Reset the UMA-B Device */
 	if(ps_adapter->chip_id >= T3LPB)
 	{
@@ -1111,11 +1045,10 @@
 
 err_exit :
 	psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
-#endif
 	return retval;
 }
 
-__inline int run_card_proc(PMINI_ADAPTER ps_adapter )
+int run_card_proc(PMINI_ADAPTER ps_adapter )
 {
 	unsigned int value=0;
 	{
@@ -1148,19 +1081,15 @@
 
 	UINT status = STATUS_SUCCESS;
 	UINT value = 0;
-#ifdef BCM_SHM_INTERFACE
-	unsigned char *pConfigFileAddr = (unsigned char *)CPE_MACXVI_CFG_ADDR;
-#endif
 	/*
  	 * Create the threads first and then download the
  	 * Firm/DDR Settings..
  	 */
 
-	if((status = create_worker_threads(ps_adapter))<0)
-	{
-		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Cannot create thread");
+	status = create_worker_threads(ps_adapter);
+	if (status<0)
 		return status;
-	}
+
 	/*
  	 * For Downloading the Firm, parse the cfg file first.
  	 */
@@ -1169,7 +1098,6 @@
 		return status;
 	}
 
-#ifndef BCM_SHM_INTERFACE
 	if(ps_adapter->chip_id >= T3LPB)
 	{
 		rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value));
@@ -1187,7 +1115,7 @@
 	status = ddr_init(ps_adapter);
 	if(status)
 	{
-		BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "ddr_init Failed\n");
+		pr_err(DRV_NAME "ddr_init Failed\n");
 		return status;
 	}
 
@@ -1201,7 +1129,6 @@
 		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file");
 		goto OUT;
 	}
-	BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "CFG file downloaded");
 
 	if(register_networkdev(ps_adapter))
 	{
@@ -1266,12 +1193,6 @@
 			goto OUT;
 		}
 	}
-#if 0
-	else if(psAdapter->eNVMType == NVM_EEPROM)
-	{
-		PropagateCalParamsFromEEPROMToMemory();
-	}
-#endif
 
 	/* Download Firmare */
 	if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR)))
@@ -1280,7 +1201,6 @@
 		goto OUT;
 	}
 
-	BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "BIN file downloaded");
 	status = run_card_proc(ps_adapter);
 	if(status)
 	{
@@ -1299,68 +1219,19 @@
 		wake_up(&ps_adapter->LEDInfo.notify_led_event);
 	}
 
-#else
-
-	ps_adapter->bDDRInitDone = TRUE;
-	//Initializing the NVM.
-	BcmInitNVM(ps_adapter);
-
-	//Propagating the cal param from Flash to DDR
-	value = 0;
-	wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
-	wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
-
-	if(ps_adapter->eNVMType == NVM_FLASH)
-	{
-		status = PropagateCalParamsFromFlashToMemory(ps_adapter);
-		if(status)
-		{
-			printk("\nPropogation of Cal param from flash to DDR failed ..\n" );
-		}
-	}
-
-	//Copy config file param to DDR.
-	memcpy(pConfigFileAddr,ps_adapter->pstargetparams, sizeof(STARGETPARAMS));
-
-	if(register_networkdev(ps_adapter))
-	{
-		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed.");
-		return -EIO;
-	}
-
-
-	status = InitLedSettings (ps_adapter);
-	if(status)
-	{
-		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n");
-		return status;
-	}
-
-
-	if(register_control_device_interface(ps_adapter) < 0)
-	{
-		BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed.");
-		return -EIO;
-	}
-
-	ps_adapter->fw_download_done = TRUE;
-#endif
 	return status;
 }
 
 
-int bcm_parse_target_params(PMINI_ADAPTER Adapter)
+static int bcm_parse_target_params(PMINI_ADAPTER Adapter)
 {
-#ifdef BCM_SHM_INTERFACE
-	extern void read_cfg_file(PMINI_ADAPTER Adapter);
-#endif
 	struct file 		*flp=NULL;
 	mm_segment_t 	oldfs={0};
-	char *buff = NULL;
+	char *buff;
 	int len = 0;
 	loff_t	pos = 0;
 
-	buff=(PCHAR)kmalloc(BUFFER_1K, GFP_KERNEL);
+	buff=kmalloc(BUFFER_1K, GFP_KERNEL);
 	if(!buff)
 	{
 		return -ENOMEM;
@@ -1368,14 +1239,14 @@
 	if((Adapter->pstargetparams =
 		kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
 	{
-		bcm_kfree(buff);
+		kfree(buff);
 		return -ENOMEM;
 	}
 	flp=open_firmware_file(Adapter, CFG_FILE);
 	if(!flp) {
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE);
-		bcm_kfree(buff);
-		bcm_kfree(Adapter->pstargetparams);
+		kfree(buff);
+		kfree(Adapter->pstargetparams);
 		Adapter->pstargetparams = NULL;
 		return -ENOENT;
 	}
@@ -1386,8 +1257,8 @@
 	if(len != sizeof(STARGETPARAMS))
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n");
-		bcm_kfree(buff);
-		bcm_kfree(Adapter->pstargetparams);
+		kfree(buff);
+		kfree(Adapter->pstargetparams);
 		Adapter->pstargetparams = NULL;
 		filp_close(flp, current->files);
 		return -ENOENT;
@@ -1399,12 +1270,8 @@
 	 * Values in Adapter->pstargetparams are in network byte order
 	 */
 	memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS));
-	bcm_kfree (buff);
+	kfree (buff);
 	beceem_parse_target_struct(Adapter);
-#ifdef BCM_SHM_INTERFACE
-	read_cfg_file(Adapter);
-
-#endif
 	return STATUS_SUCCESS;
 }
 
@@ -1414,22 +1281,23 @@
 
 	if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE)
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Disabled\n");
+		pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
 		Adapter->AutoSyncup = FALSE;
 	}
 	else
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Enabled\n");
+		pr_info(DRV_NAME ": AutoSyncup is Enabled\n");
 		Adapter->AutoSyncup	= TRUE;
 	}
+
 	if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE)
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling autolink up");
+		pr_info(DRV_NAME ": Enabling autolink up");
 		Adapter->AutoLinkUp = TRUE;
 	}
 	else
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling autolink up");
+		pr_info(DRV_NAME ": Disabling autolink up");
 		Adapter->AutoLinkUp = FALSE;
 	}
 	// Setting the DDR Setting..
@@ -1438,59 +1306,54 @@
 	Adapter->ulPowerSaveMode =
 			(ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL, "Power Save Mode: %lx\n",
-							Adapter->ulPowerSaveMode);
+	pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting);
+	pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode);
 	if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD)
     {
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling Auto Firmware Download\n");
+        pr_info(DRV_NAME ": Enabling Auto Firmware Download\n");
         Adapter->AutoFirmDld = TRUE;
     }
     else
     {
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling Auto Firmware Download\n");
+        pr_info(DRV_NAME ": Disabling Auto Firmware Download\n");
         Adapter->AutoFirmDld = FALSE;
     }
 	uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
 	Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"MIPSConfig   : 0x%X\n",Adapter->bMipsConfig);
+	pr_info(DRV_NAME ": MIPSConfig   : 0x%X\n",Adapter->bMipsConfig);
 	//used for backward compatibility.
 	Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;
 
 	Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "PMU MODE: %x", Adapter->PmuMode);
+	pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode);
 
     if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01))
     {
         Adapter->bDoSuspend = TRUE;
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Making DoSuspend TRUE as per configFile");
+        pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile");
     }
 
 	uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "uiEEPROMFlag  : 0x%X\n",uiEEPROMFlag);
+	pr_info(DRV_NAME ": uiEEPROMFlag  : 0x%X\n",uiEEPROMFlag);
 	Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3);
 
-
 	Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1;
-	//printk(("bStatusWrite   : 0x%X\n", Adapter->bStatusWrite));
 
 	Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));
-	//printk(("uiSectorSize   : 0x%X\n", Adapter->uiSectorSizeInCFG));
 
 	Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1;
-	//printk(MP_INIT,("bSectorSizeOverride   : 0x%X\n",Adapter->bSectorSizeOverride));
 
 	if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01)
 		Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;
-	//autocorrection part
+
 	if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
 		doPowerAutoCorrection(Adapter);
 
 }
 
-VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
+static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
 {
-	UINT reporting_mode = 0;
+	UINT reporting_mode;
 
 	reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ;
 	psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
@@ -1504,20 +1367,9 @@
 	if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB))
 	{
 		//If reporting mode is enable, switch PMU to PMC
-		#if 0
-		if(reporting_mode == FALSE)
-		{
-			psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN;
-			psAdapter->bDoSuspend = TRUE;
-			BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMU selected ....");
-
-		}
-		else
-		#endif
 		{
 			psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
 			psAdapter->bDoSuspend =FALSE;
-			BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMC selected..");
 
 		}
 
@@ -1540,12 +1392,10 @@
 #if 0
 static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
 {
-	unsigned char *pucmacaddr = NULL;
-	int status = 0, i=0;
-	unsigned int temp =0;
+	int status = 0, i = 0;
+	unsigned int temp = 0;
+	unsigned char *pucmacaddr = kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);
 
-
-	pucmacaddr = (unsigned char *)kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);
 	if(!pucmacaddr)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n");
@@ -1558,7 +1408,7 @@
 	if(status != STATUS_SUCCESS)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n");
-		bcm_kfree(pucmacaddr);
+		kfree(pucmacaddr);
 		pucmacaddr = NULL;
 		goto OUT;
 	}
@@ -1568,7 +1418,7 @@
 		if(status != STATUS_SUCCESS)
 		{
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
-			bcm_kfree(pucmacaddr);
+			kfree(pucmacaddr);
 			pucmacaddr = NULL;
 			goto OUT;
 		}
@@ -1580,43 +1430,6 @@
 }
 #endif
 
-#if 0
-INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter)
-{
-	unsigned char *puMacAddr = NULL;
-	int i =0;
-
-	puMacAddr = ReadMacAddrEEPROM(Adapter,0x200);
-	if(!puMacAddr)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Couldn't retrieve the Mac Address\n");
-		return STATUS_FAILURE;
-	}
-	else
-	{
-		if((puMacAddr[0] == 0x0  && puMacAddr[1] == 0x0  &&
-			puMacAddr[2] == 0x0  && puMacAddr[3] == 0x0  &&
-			puMacAddr[4] == 0x0  && puMacAddr[5] == 0x0) ||
-		   (puMacAddr[0] == 0xFF && puMacAddr[1] == 0xFF &&
-			puMacAddr[2] == 0xFF && puMacAddr[3] == 0xFF &&
-			puMacAddr[4] == 0xFF && puMacAddr[5] == 0xFF))
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Invalid Mac Address\n");
-			bcm_kfree(puMacAddr);
-			return STATUS_FAILURE;
-		}
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "The Mac Address received is: \n");
-		memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
-        for(i=0;i<MAC_ADDRESS_SIZE;i++)
-        {
-            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%02x ", Adapter->dev->dev_addr[i]);
-        }
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"\n");
-		bcm_kfree(puMacAddr);
-	}
-	return STATUS_SUCCESS;
-}
-#endif
 
 static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
 {
@@ -1640,81 +1453,21 @@
 {
 	INT uiRetVal =0;
 
-#ifndef BCM_SHM_INTERFACE
 	uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
 			uiAddress, pucBuff, sSize);
 
 	if(uiRetVal < 0)
 		return uiRetVal;
 
-#else
-	int indx;
-	uiRetVal = STATUS_SUCCESS;
-	if(uiAddress & 0x10000000) {
-			// DDR Memory Access
-		uiAddress |= CACHE_ADDRESS_MASK;
-		memcpy(pucBuff,(unsigned char *)uiAddress ,sSize);
-	}
-	else {
-		// Register, SPRAM, Flash
-		uiAddress |= UNCACHE_ADDRESS_MASK;
-    if ((uiAddress & FLASH_ADDR_MASK) == (FLASH_CONTIGIOUS_START_ADDR_BCS350 & FLASH_ADDR_MASK))
-	{
-		#if defined(FLASH_DIRECT_ACCESS)
-        	memcpy(pucBuff,(unsigned char *)uiAddress ,sSize);
-		#else
-			printk("\nInvalid GSPI ACCESS :Addr :%#X", uiAddress);
-			uiRetVal = STATUS_FAILURE;
-		#endif
-	}
-    else if(((unsigned int )uiAddress & 0x3) ||
-			((unsigned int )pucBuff & 0x3) ||
-			((unsigned int )sSize & 0x3)) {
-		  	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"rdmalt :unalligned register access uiAddress =  %x,pucBuff = %x  size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize);
-			 uiRetVal = STATUS_FAILURE;
-		}
-		else {
-		 	for (indx=0;indx<sSize;indx+=4){
-		   		*(PUINT)(pucBuff + indx) = *(PUINT)(uiAddress + indx);
-		  	}
-		}
-	}
-#endif
 	return uiRetVal;
 }
 int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
 {
 	int iRetVal;
 
-#ifndef BCM_SHM_INTERFACE
 	iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
 			uiAddress, pucBuff, sSize);
 
-#else
-	int indx;
-	if(uiAddress & 0x10000000) {
-		// DDR Memory Access
-		uiAddress |= CACHE_ADDRESS_MASK;
-		memcpy((unsigned char *)(uiAddress),pucBuff,sSize);
-	}
-	else {
-		// Register, SPRAM, Flash
-		uiAddress |= UNCACHE_ADDRESS_MASK;
-
-		if(((unsigned int )uiAddress & 0x3) ||
-			((unsigned int )pucBuff & 0x3) ||
-			((unsigned int )sSize & 0x3)) {
-		  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrmalt: unalligned register access uiAddress =  %x,pucBuff = %x  size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize);
-			 iRetVal = STATUS_FAILURE;
-		}
-		else {
-		 	for (indx=0;indx<sSize;indx+=4) {
-		  		*(PUINT)(uiAddress + indx) = *(PUINT)(pucBuff + indx);
-			}
-		}
-	}
-	iRetVal = STATUS_SUCCESS;
-#endif
 
 	return iRetVal;
 }
@@ -1735,26 +1488,7 @@
 	return uiRetVal;
 }
 
-int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
-{
 
-	INT status = STATUS_SUCCESS ;
-	down(&Adapter->rdmwrmsync);
-
-	if((Adapter->IdleMode == TRUE) ||
-		(Adapter->bShutStatus ==TRUE) ||
-		(Adapter->bPreparingForLowPowerMode ==TRUE))
-	{
-		status = -EACCES;
-		goto exit;
-	}
-
-	status = rdm(Adapter, uiAddress, pucBuff, sSize);
-
-exit:
-	up(&Adapter->rdmwrmsync);
-	return status ;
-}
 int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
 {
 	INT status = STATUS_SUCCESS ;
@@ -1921,10 +1655,8 @@
 			Adapter->bPreparingForLowPowerMode = TRUE;
 			up(&Adapter->rdmwrmsync);
 			//Killing all URBS.
-#ifndef BCM_SHM_INTERFACE
 			if(Adapter->bDoSuspend == TRUE)
 				Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
-#endif
 		}
 		else
 		{
@@ -1943,14 +1675,12 @@
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n");
 		Adapter->bPreparingForLowPowerMode = FALSE;
 
-#ifndef BCM_SHM_INTERFACE
 		StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
-#endif
 	}
 }
 
 
-void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
+static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
 {
 	B_UINT32 uiResetValue = 0;
 
@@ -2077,11 +1807,7 @@
 	if(!atomic_read (&Adapter->uiMBupdate))
 		return;
 
-#ifdef BCM_SHM_INTERFACE
-	if(rdmalt(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
-#else
 	if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
-#endif
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
 		return;
@@ -2107,9 +1833,7 @@
 void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
 {
 	struct sk_buff* 			PacketToDrop=NULL;
-	struct net_device_stats*		netstats=NULL;
-
-	netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
+	struct net_device_stats*		netstats = &Adapter->dev->stats;
 
 	spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
 
@@ -2130,25 +1854,23 @@
 			Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len;
 			Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
 
-			bcm_kfree_skb(PacketToDrop);
+			dev_kfree_skb(PacketToDrop);
 			atomic_dec(&Adapter->TotalPacketCount);
-			atomic_inc(&Adapter->TxDroppedPacketCount);
-
 		}
 	}
 	spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
 
 }
 
-void beceem_protocol_reset (PMINI_ADAPTER Adapter)
+static void beceem_protocol_reset (PMINI_ADAPTER Adapter)
 {
-	int i =0;
+	int i;
 
-	if(NULL != Adapter->dev)
-	{
-		netif_carrier_off(Adapter->dev);
-		netif_stop_queue(Adapter->dev);
-	}
+	if (netif_msg_link(Adapter))
+		pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name);
+
+	netif_carrier_off(Adapter->dev);
+	netif_stop_queue(Adapter->dev);
 
 	Adapter->IdleMode = FALSE;
 	Adapter->LinkUpStatus = FALSE;
@@ -2166,78 +1888,18 @@
 		Adapter->TimerActive = FALSE;
 
 	memset(Adapter->astFragmentedPktClassifierTable, 0,
-			sizeof(S_FRAGMENTED_PACKET_INFO) *
-			MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
+	       sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
 
 	for(i = 0;i<HiPriority;i++)
 	{
 		//resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF.
 		// It is same between MIBs and SF.
-		memset((PVOID)&Adapter->PackInfo[i],0,sizeof(S_MIBS_SERVICEFLOW_TABLE));
+		memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable,
+		       0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS));
 	}
 }
 
 
 
-#ifdef BCM_SHM_INTERFACE
-
-
-#define GET_GTB_DIFF(start, end)  \
-( (start) < (end) )? ( (end) - (start) ) : ( ~0x0 - ( (start) - (end)) +1 )
-
-void usdelay ( unsigned int a) {
-	unsigned int start= *(unsigned int *)0xaf8051b4;
-	unsigned int end  = start+1;
-	unsigned int diff = 0;
-
-	while(1) {
-		end = *(unsigned int *)0xaf8051b4;
-		diff = (GET_GTB_DIFF(start,end))/80;
-		if (diff >= a)
-			break;
-	}
-}
-void read_cfg_file(PMINI_ADAPTER Adapter) {
-
-
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Config File Version = 0x%x \n",Adapter->pstargetparams->m_u32CfgVersion );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Center Frequency =  0x%x \n",Adapter->pstargetparams->m_u32CenterFrequency );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band A Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandAScan );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band B Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandBScan );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band C Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandCScan );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ERTPS Options = 0x%x \n",Adapter->pstargetparams->m_u32ErtpsOptions );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PHS Enable = 0x%x \n",Adapter->pstargetparams->m_u32PHSEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Handoff Enable = 0x%x \n",Adapter->pstargetparams->m_u32HoEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved1 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved1 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved2 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved2 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MIMO Enable = 0x%x \n",Adapter->pstargetparams->m_u32MimoEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PKMv2 Enable = 0x%x \n",Adapter->pstargetparams->m_u32SecurityEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Powersaving Modes Enable = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModesEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Power Saving Mode Options = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModeOptions );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ARQ Enable = 0x%x \n",Adapter->pstargetparams->m_u32ArqEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Harq Enable = 0x%x \n",Adapter->pstargetparams->m_u32HarqEnable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"EEPROM Flag = 0x%x \n",Adapter->pstargetparams->m_u32EEPROMFlag );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Customize = 0x%x \n",Adapter->pstargetparams->m_u32Customize );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Bandwidth = 0x%x \n",Adapter->pstargetparams->m_u32ConfigBW );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ShutDown Timer Value = 0x%x \n",Adapter->pstargetparams->m_u32ShutDownInitThresholdTimer );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RadioParameter = 0x%x \n",Adapter->pstargetparams->m_u32RadioParameter );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter1 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter1 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter2 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter2 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter3 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter3 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"m_u32TestOptions = 0x%x \n",Adapter->pstargetparams->m_u32TestOptions );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperDLFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperDLFrame );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperULFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperULFrame );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corr2MacFlags = 0x%x \n",Adapter->pstargetparams->m_u32Corr2MacFlags );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig1 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig1 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig2 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig2 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig3 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig3 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig4 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig4 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig5 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig5 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig6 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig6 );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Segmented PUSC Enable = 0x%x \n",Adapter->pstargetparams->m_u32SegmentedPUSCenable );
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BamcEnable = 0x%x \n",Adapter->pstargetparams->m_u32BandAMCEnable );
-}
-
-#endif
 
 
diff --git a/drivers/staging/bcm/Osal_Misc.c b/drivers/staging/bcm/Osal_Misc.c
deleted file mode 100644
index feefd20..0000000
--- a/drivers/staging/bcm/Osal_Misc.c
+++ /dev/null
@@ -1,27 +0,0 @@
-	/*++
-
-	Copyright (c) Beceem Communications Inc.
-
-	Module Name:
-		WIN_Misc.c
-
-	Abstract:
-		Implements the Miscelanneous OS Construts
-			Linked Lists
-			Dispatcher Objects(Events,Semaphores,Spin Locks and the like)
-			Files
-
-	Revision History:
-		Who         When        What
-		--------    --------    ----------------------------------------------
-		Name		Date		Created/reviewed/modified
-		Rajeev		24/1/08		Created
-	Notes:
-
-	--*/
-#include "headers.h"
-
-bool OsalMemCompare(void *dest, void *src, UINT len)
-{
-	return (memcmp(src, dest, len));
-}
diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c
index 8a38cf4..d1ca191 100644
--- a/drivers/staging/bcm/PHSModule.c
+++ b/drivers/staging/bcm/PHSModule.c
@@ -1,10 +1,54 @@
 #include "headers.h"
 
+static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
+
+static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
+
+static UINT CreateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
+
+static UINT UpdateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
+
+static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
+
+static BOOLEAN DerefPhsRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
+
+static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
+
+static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
+
+static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
+
+static int phs_compress(S_PHS_RULE   *phs_members,unsigned char *in_buf,
+						unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
+
+
+static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
+								unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
+
+static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
+						  S_PHS_RULE   *phs_rules,UINT *header_size);
+
+
+static ULONG PhsCompress(void* pvContext,
+				  B_UINT16 uiVcid,
+				  B_UINT16 uiClsId,
+				  void *pvInputBuffer,
+				  void *pvOutputBuffer,
+				  UINT *pOldHeaderSize,
+				  UINT *pNewHeaderSize );
+
+static ULONG PhsDeCompress(void* pvContext,
+				  B_UINT16 uiVcid,
+				  void *pvInputBuffer,
+				  void *pvOutputBuffer,
+				  UINT *pInHeaderSize,
+				  UINT *pOutHeaderSize);
+
+
+
 #define IN
 #define OUT
 
-void DumpDataPacketHeader(PUCHAR pPkt);
-
 /*
 Function:				PHSTransmit
 
@@ -81,8 +125,6 @@
 	{
 
 
-		//DumpDataPacketHeader(pucPHSPktHdrInBuf);
-
 		// Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
 	// Suppress only if IP Header and PHS Enabled For the Service Flow
 		if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
@@ -120,15 +162,15 @@
 						if(newPacket == NULL)
 							return STATUS_FAILURE;
 
-						bcm_kfree_skb(Packet);
+						dev_kfree_skb(Packet);
 						*pPacket = Packet = newPacket;
 						pucPHSPktHdrInBuf = Packet->data  + BytesToRemove;
 					}
 
 					numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
 
-					OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
-					OsalMemMove(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
+					memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
+					memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
 					skb_pull(Packet, numBytesCompressed);
 
 					return STATUS_SUCCESS;
@@ -223,23 +265,12 @@
 			}
 		}
 
-		OsalMemMove(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
+		memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
 	}
 
 	return STATUS_SUCCESS;
 }
 
-void DumpDataPacketHeader(PUCHAR pPkt)
-{
-	struct iphdr *iphd = (struct iphdr*)pPkt;
-    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Phs Send/Recieve : IP Packet Hdr \n");
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"TOS : %x \n",iphd->tos);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Src  IP : %x \n",iphd->saddr);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Dest IP : %x \n \n",iphd->daddr);
-
-}
-
 void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
 {
 	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -270,15 +301,9 @@
 		return -EINVAL;
 
 	pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
-      (S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE),
-            PHS_MEM_TAG);
+		kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
 
-    if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
-	{
-		OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable,
-              sizeof(S_SERVICEFLOW_TABLE));
-	}
-	else
+    if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
 		return -ENOMEM;
@@ -288,14 +313,8 @@
 	for(i=0;i<MAX_SERVICEFLOWS;i++)
 	{
 		S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
-		sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc(
-            sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG);
-		if(sServiceFlow.pstClassifierTable)
-		{
-			OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE));
-			pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable;
-    	}
-		else
+		sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
+		if(!sServiceFlow.pstClassifierTable)
 		{
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
 			free_phs_serviceflow_rules(pPhsdeviceExtension->
@@ -305,9 +324,7 @@
 		}
 	}
 
-
-	pPhsdeviceExtension->CompressedTxBuffer =
-          OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
+	pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
 
     if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
 	{
@@ -317,12 +334,11 @@
 		return -ENOMEM;
 	}
 
-	pPhsdeviceExtension->UnCompressedRxBuffer =
-      OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
+    pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
 	if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
-		OsalMemFree(pPhsdeviceExtension->CompressedTxBuffer,PHS_BUFFER_SIZE);
+		kfree(pPhsdeviceExtension->CompressedTxBuffer);
 		free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
 		pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
 		return -ENOMEM;
@@ -343,16 +359,11 @@
 		pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
 	}
 
-	if(pPHSDeviceExt->CompressedTxBuffer)
-	{
-		OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE);
-		pPHSDeviceExt->CompressedTxBuffer = NULL;
-	}
-	if(pPHSDeviceExt->UnCompressedRxBuffer)
-	{
-		OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE);
-		pPHSDeviceExt->UnCompressedRxBuffer = NULL;
-	}
+	kfree(pPHSDeviceExt->CompressedTxBuffer);
+	pPHSDeviceExt->CompressedTxBuffer = NULL;
+
+	kfree(pPHSDeviceExt->UnCompressedRxBuffer);
+	pPHSDeviceExt->UnCompressedRxBuffer = NULL;
 
 	return 0;
 }
@@ -478,20 +489,12 @@
 			{
 				if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
 				{
-					if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
-                                        .pstPhsRule->u8PHSI == u8PHSI)
-					{
-						if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
-                                                ->u8RefCnt)
-							pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
-						          ->u8RefCnt--;
-						if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
-                            .pstPhsRule->u8RefCnt)
-							OsalMemFree(pstClassifierRulesTable
-						    ->stActivePhsRulesList[nClsidIndex].pstPhsRule,
-						      sizeof(S_PHS_RULE));
-						OsalZeroMemory(&pstClassifierRulesTable
-							->stActivePhsRulesList[nClsidIndex],
+					if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI)					{
+						if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
+							pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
+						if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
+							kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
+						memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
 							sizeof(S_CLASSIFIER_ENTRY));
 					}
 				}
@@ -548,10 +551,10 @@
 				if(pstClassifierEntry->pstPhsRule->u8RefCnt)
 				pstClassifierEntry->pstPhsRule->u8RefCnt--;
 				if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
-				OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
+					kfree(pstClassifierEntry->pstPhsRule);
 
 			}
-			OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
+			memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
 		}
 
 		nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
@@ -559,10 +562,8 @@
 
 	   if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
 		{
-			if(pstClassifierEntry->pstPhsRule)
-			//Delete the classifier entry
-			OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
-			OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
+			kfree(pstClassifierEntry->pstPhsRule);
+			memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
 		}
 	}
 	return lStatus;
@@ -619,14 +620,11 @@
 						                                    .pstPhsRule->u8RefCnt--;
 					if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
                                                           .pstPhsRule->u8RefCnt)
-						OsalMemFree(pstClassifierRulesTable
-						            ->stActivePhsRulesList[nClsidIndex].pstPhsRule,
-						             sizeof(S_PHS_RULE));
+						kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
 					    pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
                                         .pstPhsRule = NULL;
 				}
-				OsalZeroMemory(&pstClassifierRulesTable
-                    ->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY));
+				memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
 				if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
 				{
 					if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
@@ -635,15 +633,12 @@
 						                  .pstPhsRule->u8RefCnt--;
 					if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
                                         .pstPhsRule->u8RefCnt)
-						OsalMemFree(pstClassifierRulesTable
-						      ->stOldPhsRulesList[nClsidIndex].pstPhsRule,
-						       sizeof(S_PHS_RULE));
+						kfree(pstClassifierRulesTable
+						      ->stOldPhsRulesList[nClsidIndex].pstPhsRule);
 					pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
                               .pstPhsRule = NULL;
 				}
-				OsalZeroMemory(&pstClassifierRulesTable
-                  ->stOldPhsRulesList[nClsidIndex],
-                   sizeof(S_CLASSIFIER_ENTRY));
+				memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
 			}
 		}
 		pstServiceFlowEntry->bUsed = FALSE;
@@ -849,7 +844,7 @@
 // Does not return any value.
 //-----------------------------------------------------------------------------
 
-void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
+static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
 {
 	int i,j;
     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -876,8 +871,7 @@
   							                                                ->u8RefCnt--;
 						if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
                                                                 ->u8RefCnt)
-							OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j].
-							                                              pstPhsRule, sizeof(S_PHS_RULE));
+							kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
 						pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
 					}
 					if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
@@ -888,24 +882,23 @@
 							                                          ->u8RefCnt--;
 						if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
                                                                       ->u8RefCnt)
-							OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j]
-							                        .pstPhsRule,sizeof(S_PHS_RULE));
+							kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
 						pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
 					}
 				}
-			    OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE));
+				kfree(pstClassifierRulesTable);
 			    stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
 			}
 		}
 	}
 
-	OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE));
-	psServiceFlowRulesTable = NULL;
+    kfree(psServiceFlowRulesTable);
+    psServiceFlowRulesTable = NULL;
 }
 
 
 
-BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
+static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
 {
 	if(psPhsRule)
 	{
@@ -988,9 +981,9 @@
 	return PHS_INVALID_TABLE_INDEX;
 }
 
-UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
-      IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
-      OUT S_PHS_RULE **ppstPhsRule)
+static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
+			    IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
+			    OUT S_PHS_RULE **ppstPhsRule)
 {
 	int  i;
 	S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
@@ -1102,7 +1095,7 @@
 		if(psPhsRule->u8PHSFLength)
 		{
 			//update PHSF
-			OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF,
+			memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
 			    psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
 		}
 		if(psPhsRule->u8PHSFLength)
@@ -1114,7 +1107,7 @@
 		if(psPhsRule->u8PHSMLength)
 		{
 			//update PHSM
-			OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM,
+			memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
 			    psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
 		}
 		if(psPhsRule->u8PHSMLength)
@@ -1147,7 +1140,7 @@
 	return uiStatus;
 }
 
-UINT CreateClassifierPHSRule(IN B_UINT16  uiClsId,
+static UINT CreateClassifierPHSRule(IN B_UINT16  uiClsId,
     S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
     E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
 {
@@ -1234,8 +1227,7 @@
 	{
 		if(psClassifierRules->pstPhsRule == NULL)
 		{
-			psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc
-                (sizeof(S_PHS_RULE),PHS_MEM_TAG);
+			psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
 
           if(NULL == psClassifierRules->pstPhsRule)
 				return ERR_PHSRULE_MEMALLOC_FAIL;
@@ -1247,7 +1239,7 @@
 		psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
 
         /* Update The PHS rule */
-		OsalMemMove(psClassifierRules->pstPhsRule,
+		memcpy(psClassifierRules->pstPhsRule,
 		    psPhsRule, sizeof(S_PHS_RULE));
 	}
 	else
@@ -1259,7 +1251,7 @@
 }
 
 
-UINT UpdateClassifierPHSRule(IN B_UINT16  uiClsId,
+static UINT UpdateClassifierPHSRule(IN B_UINT16  uiClsId,
       IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
       S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
       B_UINT8 u8AssociatedPHSI)
@@ -1289,13 +1281,13 @@
 		//Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
 		if(FALSE == bPHSRuleOrphaned)
 		{
-			pstClassifierEntry->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc(sizeof(S_PHS_RULE),PHS_MEM_TAG);
+			pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
 			if(NULL == pstClassifierEntry->pstPhsRule)
 			{
 				return ERR_PHSRULE_MEMALLOC_FAIL;
 			}
 		}
-		OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
+		memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
 
 	}
 	else
@@ -1304,14 +1296,8 @@
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
 		if(bPHSRuleOrphaned)
 		{
-		    if(pstClassifierEntry->pstPhsRule)
-		    {
-		    	//Just Free the PHS Rule as Ref Count is Zero
-		    	OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
+			kfree(pstClassifierEntry->pstPhsRule);
 			pstClassifierEntry->pstPhsRule = NULL;
-
-		    }
-
 		}
 		pstClassifierEntry->pstPhsRule = pstAddPhsRule;
 
@@ -1326,7 +1312,7 @@
 
 }
 
-BOOLEAN DerefPhsRule(IN B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
+static BOOLEAN DerefPhsRule(IN B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
 {
 	if(pstPhsRule==NULL)
 		return FALSE;
@@ -1345,22 +1331,6 @@
 	}
 }
 
-static void DumpBuffer(PVOID BuffVAddress, int xferSize)
-{
-	int i;
-	int iPrintLength;
-	PUCHAR temp=(PUCHAR)BuffVAddress;
-    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
-	iPrintLength=(xferSize<32?xferSize:32);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
-
-	for (i=0;i < iPrintLength;i++) {
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]);
-	}
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
-}
-
-
 void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
 {
 	int i,j,k,l;
@@ -1520,8 +1490,8 @@
 //	size-The number of bytes copied into the output buffer i.e dynamic fields
 //	0	-If PHS rule is NULL.If PHSV field is not set.If the verification fails.
 //-----------------------------------------------------------------------------
-int phs_compress(S_PHS_RULE  *phs_rule,unsigned char *in_buf
-						,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
+static int phs_compress(S_PHS_RULE  *phs_rule,unsigned char *in_buf
+			,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
 {
 	unsigned char *old_addr = out_buf;
 	int supress = 0;
@@ -1581,9 +1551,9 @@
 //	0	-Packet has failed the verification.
 //-----------------------------------------------------------------------------
 
- int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
-								unsigned char *phsf,unsigned char *phsm,unsigned int phss,
-								unsigned int phsv,UINT* new_header_size)
+static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
+				unsigned char *phsf,unsigned char *phsm,unsigned int phss,
+				unsigned int phsv,UINT* new_header_size)
 {
 	unsigned int size=0;
 	int bit,i=0;
diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h
index bf2b576..0dd05a7 100644
--- a/drivers/staging/bcm/PHSModule.h
+++ b/drivers/staging/bcm/PHSModule.h
@@ -27,19 +27,6 @@
 
 int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter);
 
-void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
-
-int phs_compress(S_PHS_RULE   *phs_members,unsigned char *in_buf,
-						unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
-
-
-int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
-								unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
-
-int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
-						  S_PHS_RULE   *phs_rules,UINT *header_size);
-
-
 int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt);
 
 //Utility Functions
@@ -52,42 +39,10 @@
 ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ;
 
 
-ULONG PhsCompress(void* pvContext,
-				  B_UINT16 uiVcid,
-				  B_UINT16 uiClsId,
-				  void *pvInputBuffer,
-				  void *pvOutputBuffer,
-				  UINT *pOldHeaderSize,
-				  UINT *pNewHeaderSize );
-
-ULONG PhsDeCompress(void* pvContext,
-				  B_UINT16 uiVcid,
-				  void *pvInputBuffer,
-				  void *pvOutputBuffer,
-				  UINT *pInHeaderSize,
-				  UINT *pOutHeaderSize);
-
-
 BOOLEAN ValidatePHSRule(S_PHS_RULE *psPhsRule);
 
-BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
-
 UINT GetServiceFlowEntry(S_SERVICEFLOW_TABLE *psServiceFlowTable,B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry);
 
-UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
-
-UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
-
-
-UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
-
-UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16  uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
-
-UINT CreateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
-
-UINT UpdateClassifierPHSRule(B_UINT16  uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
-
-BOOLEAN DerefPhsRule(B_UINT16  uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
 
 void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
 
diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h
index 00f1cc1..b8a4009 100644
--- a/drivers/staging/bcm/Protocol.h
+++ b/drivers/staging/bcm/Protocol.h
@@ -85,10 +85,10 @@
 	ETH_HEADER_STRUC EThHdr;
 } __attribute__((packed)) ETH_CS_ETH2_FRAME;
 
+#define ETHERNET_FRAMETYPE_IPV4		ntohs(0x0800)
+#define ETHERNET_FRAMETYPE_IPV6 	ntohs(0x86dd)
+#define ETHERNET_FRAMETYPE_802QVLAN 	ntohs(0x8100)
 
-#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800)
-#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd)
-#define ETHERNET_FRAMETYPE_802QVLAN 0x8100
 //Per SF CS Specification Encodings
 typedef enum _E_SERVICEFLOW_CS_SPEC_
 {
diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h
index 70ec8bc..b80b806 100644
--- a/drivers/staging/bcm/Prototypes.h
+++ b/drivers/staging/bcm/Prototypes.h
@@ -1,23 +1,12 @@
 #ifndef _PROTOTYPES_H_
 #define _PROTOTYPES_H_
 
-int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
-                        char *path,     /**< path to image file */
-                        unsigned int loc    /**< Download Address on the chip*/
-                        );
 VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer);
 
 VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer);
 
 VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer);
 
-void bcm_kfree_skb(struct sk_buff *skb);
-VOID bcm_kfree(VOID *ptr);
-
-
-VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, 	/**<Pointer to the Adapter structure*/
-								struct sk_buff *skb);				/**<Pointer to the socket buffer*/
-
 int control_packet_handler	(PMINI_ADAPTER Adapter);
 
 VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex);
@@ -38,25 +27,16 @@
 
 VOID flush_all_queues(PMINI_ADAPTER Adapter);
 
-USHORT	IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
-					struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
-					S_CLASSIFIER_RULE *pstClassifierRule );
-
-VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
-					INT iIndex/**<Queue Index*/
-					);
-
 VOID PruneQueueAllSF(PMINI_ADAPTER Adapter);
 
 INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid);
 
-USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
-								struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
-								);
+USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
 
-VOID
-reply_to_arp_request(struct sk_buff *skb  /**<sk_buff of ARP request*/
-						);
+BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
+BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
+BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
+
 
 INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
 					struct sk_buff *Packet, /**<data buffer*/
@@ -70,11 +50,9 @@
 							char *pControlPacket/**<Control Packet*/
 							);
 
-INT bcm_transmit(struct sk_buff *skb, 		/**< skb */
-					struct net_device *dev 	/**< net device pointer */
-					);
 
 int register_networkdev(PMINI_ADAPTER Adapter);
+void unregister_networkdev(PMINI_ADAPTER Adapter);
 
 INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
 
@@ -82,8 +60,6 @@
 
 INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
 
-int create_worker_threads(PMINI_ADAPTER psAdapter);
-
 int tx_pkt_handler(PMINI_ADAPTER Adapter);
 
 int  reset_card_proc(PMINI_ADAPTER Adapter );
@@ -92,7 +68,6 @@
 
 int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter);
 
-int bcm_parse_target_params(PMINI_ADAPTER Adapter);
 
 INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter);
 
@@ -110,26 +85,15 @@
 
 int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId, void __user * user_buffer);
 
-void SendLinkDown(PMINI_ADAPTER Adapter);
-
 void SendIdleModeResponse(PMINI_ADAPTER Adapter);
 
-void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
 
-int  ProcessGetHostMibs(PMINI_ADAPTER Adapter, PVOID ioBuffer,
-	ULONG inputBufferLength);
-
-int GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang);
+int  ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *buf);
+void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, PPER_TARANG_DATA pTarang);
 void beceem_parse_target_struct(PMINI_ADAPTER Adapter);
 
-void doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
-
 int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo);
 
-void bcm_unregister_networkdev(PMINI_ADAPTER Adapter);
-
-int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid);
-
 void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
 		CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex);
 
@@ -149,7 +113,6 @@
 
 void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll);
 
-void beceem_protocol_reset (PMINI_ADAPTER Adapter);
 
 void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex);
 
@@ -164,31 +127,11 @@
 	UINT uiNumBytes);
 
 
-INT BeceemFlashBulkRead(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes);
-
-UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
 
 INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData);
 
-UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
-
-UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
-
-INT BeceemFlashBulkWrite(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes,
-	BOOLEAN bVerify);
-
 INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
 
-INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
-
 
 INT BeceemEEPROMBulkWrite(
 	PMINI_ADAPTER Adapter,
@@ -198,11 +141,8 @@
 	BOOLEAN bVerify);
 
 
-INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
-
 INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
 
-NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
 
 INT BeceemNVMRead(
 	PMINI_ADAPTER Adapter,
@@ -217,24 +157,12 @@
 	UINT uiNumBytes,
 	BOOLEAN bVerify);
 
-INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
 
 INT BcmInitNVM(PMINI_ADAPTER Adapter);
 
-INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
+INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
+BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
 
-INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
-
-VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
-
-VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter);
-
-INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
-INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd);
-INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
-INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage);
-INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
-B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
 INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
 
 INT BcmFlash2xBulkWrite(
@@ -251,7 +179,6 @@
 	FLASH2X_SECTION_VAL eFlashSectionVal,
 	UINT uiOffsetWithinSectionVal,
 	UINT uiNumBytes);
-INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
 
 INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
 
@@ -264,34 +191,13 @@
 INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
 INT	validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
 INT IsFlash2x(PMINI_ADAPTER Adapter);
-INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
-INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
 INT	BcmCopySection(PMINI_ADAPTER Adapter,
 						FLASH2X_SECTION_VAL SrcSection,
 						FLASH2X_SECTION_VAL DstSection,
 						UINT offset,
 						UINT numOfBytes);
 
-INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
-INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset);
-INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
-INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
-FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
-INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
-INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
-FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
-INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
-										PUINT pBuff,
-										FLASH2X_SECTION_VAL eFlash2xSectionVal,
-										UINT uiOffset,
-										UINT uiNumBytes
-										);
 
-//UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType);
-BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
-INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
-INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
-INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
 BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter);
 
 
@@ -300,7 +206,6 @@
 int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
 int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
 
-int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
 int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
 INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
 		unsigned long u32StartingAddress);
@@ -309,11 +214,6 @@
 VOID putUsbSuspend(struct work_struct *work);
 BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios);
 
-#ifdef BCM_SHM_INTERFACE
-INT beceem_virtual_device_init(void);
-VOID virtual_mail_box_interrupt(void);
-INT beceem_virtual_device_exit(void);
-#endif
 
 #endif
 
diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c
index 75b2b87..8ce4536 100644
--- a/drivers/staging/bcm/Qos.c
+++ b/drivers/staging/bcm/Qos.c
@@ -4,15 +4,14 @@
 */
 #include "headers.h"
 
-BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP);
-BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService);
-BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
-BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort);
-BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
-BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP);
-USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
-void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
-BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
+static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
+static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
+
+static USHORT	IpVersion4(PMINI_ADAPTER Adapter, struct iphdr *iphd,
+			   S_CLASSIFIER_RULE *pstClassifierRule );
+
+static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex);
+
 
 /*******************************************************************
 * Function    - MatchSrcIpAddress()
@@ -205,11 +204,10 @@
 Compares IPV4 Ip address and port number
 @return Queue Index.
 */
-USHORT	IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
-					struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
-					S_CLASSIFIER_RULE *pstClassifierRule )
+static USHORT	IpVersion4(PMINI_ADAPTER Adapter,
+			   struct iphdr *iphd,
+			   S_CLASSIFIER_RULE *pstClassifierRule )
 {
-	//IPHeaderFormat 		*pIpHeader=NULL;
 	xporthdr     		*xprt_hdr=NULL;
 	BOOLEAN	bClassificationSucceed=FALSE;
 
@@ -261,15 +259,6 @@
 		//if protocol is not TCP or UDP then no need of comparing source port and destination port
 		if(iphd->protocol!=TCP && iphd->protocol!=UDP)
 			break;
-#if 0
-		//check if memory is available of src and Dest port
-		if(ETH_AND_IP_HEADER_LEN + L4_SRC_PORT_LEN + L4_DEST_PORT_LEN > Packet->len)
-		{
-			//This is not an erroneous condition and pkt will be checked for next classification.
-			bClassificationSucceed = FALSE;
-			break;
-		}
-#endif
 		//******************Checking Transport Layer Header field if present *****************//
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
 			(iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source);
@@ -312,29 +301,6 @@
 
 	return bClassificationSucceed;
 }
-/**
-@ingroup tx_functions
-@return  Queue Index based on priority.
-*/
-USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
-								struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
-								)
-{
-	USHORT			usIndex=-1;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "=====>");
-
-	if(NULL==Adapter || NULL==Packet)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got NULL Values<======");
-		return -1;
-	}
-
-	usIndex = ClassifyPacket(Adapter,Packet);
-
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got Queue Index %x",usIndex);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "GetPacketQueueIndex <==============");
-	return usIndex;
-}
 
 VOID PruneQueueAllSF(PMINI_ADAPTER Adapter)
 {
@@ -357,23 +323,21 @@
 drops packets from the Head till the number of bytes is
 less than or equal to max queue size for the queue.
 */
-VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
-					INT iIndex/**<Queue Index*/
-					)
+static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex)
 {
 	struct sk_buff* PacketToDrop=NULL;
-	struct net_device_stats*  netstats=NULL;
+	struct net_device_stats *netstats;
 
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d",iIndex);
 
    	if(iIndex == HiPriority)
-       	return;
+		return;
 
 	if(!Adapter || (iIndex < 0) || (iIndex > HiPriority))
 		return;
 
 	/* To Store the netdevice statistic */
-	netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
+	netstats = &Adapter->dev->stats;
 
 	spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
 
@@ -395,9 +359,13 @@
 
 		if(PacketToDrop)
 		{
-			if(netstats)
-				netstats->tx_dropped++;
-			atomic_inc(&Adapter->TxDroppedPacketCount);
+			struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iIndex);
+			if (netif_msg_tx_err(Adapter))
+				pr_info(PFX "%s: tx queue %d overlimit\n", 
+					Adapter->dev->name, iIndex);
+
+			txq->tx_dropped++;
+
 			DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue,
 						Adapter->PackInfo[iIndex].LastTxQueue);
 			/// update current bytes and packets count
@@ -407,7 +375,7 @@
 			/// update dropped bytes and packets counts
 			Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len;
 			Adapter->PackInfo[iIndex].uiDroppedCountPackets++;
-			bcm_kfree_skb(PacketToDrop);
+			dev_kfree_skb(PacketToDrop);
 
 		}
 
@@ -416,7 +384,6 @@
 			Adapter->PackInfo[iIndex].uiDroppedCountPackets);
 
 		atomic_dec(&Adapter->TotalPacketCount);
-		Adapter->bcm_jiffies = jiffies;
 	}
 
 	spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
@@ -430,16 +397,15 @@
 {
 	INT		iQIndex;
 	UINT	uiTotalPacketLength;
-	struct sk_buff*				PacketToDrop=NULL;
-	struct net_device_stats*  	netstats=NULL;
+	struct sk_buff*			PacketToDrop=NULL;
 
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>");
-	/* To Store the netdevice statistic */
-	netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
 
 //	down(&Adapter->data_packet_queue_lock);
 	for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++)
 	{
+		struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iQIndex);
+
 		spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
 		while(Adapter->PackInfo[iQIndex].FirstTxQueue)
 		{
@@ -447,8 +413,7 @@
 			if(PacketToDrop)
 			{
 				uiTotalPacketLength = PacketToDrop->len;
-				netstats->tx_dropped++;
-				atomic_inc(&Adapter->TxDroppedPacketCount);
+				txq->tx_dropped++;
 			}
 			else
 				uiTotalPacketLength = 0;
@@ -457,7 +422,7 @@
 						Adapter->PackInfo[iQIndex].LastTxQueue);
 
 			/* Free the skb */
-			bcm_kfree_skb(PacketToDrop);
+			dev_kfree_skb(PacketToDrop);
 
 			/// update current bytes and packets count
 			Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength;
@@ -559,12 +524,6 @@
 
 	for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--)
 	{
-		if (Adapter->device_removed)
-		{
-			bClassificationSucceed = FALSE;
-			break;
-		}
-
 		if(bClassificationSucceed)
 			break;
 		//Iterate through all classifiers which are already in order of priority
@@ -810,7 +769,10 @@
 }
 
 
-BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport)
+static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,
+				PS_ETHCS_PKT_INFO pstEthCsPktInfo,
+				S_CLASSIFIER_RULE *pstClassifierRule,
+				B_UINT8 EthCSCupport)
 {
 	BOOLEAN bClassificationSucceed = FALSE;
 	bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress);
@@ -840,9 +802,11 @@
 	return bClassificationSucceed;
 }
 
-void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo)
+static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,
+			    PS_ETHCS_PKT_INFO pstEthCsPktInfo)
 {
 	USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype);
+
 	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,  "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype);
 	if(u16Etype > 0x5dc)
 	{
diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO
index 366634b..cd3e9f2 100644
--- a/drivers/staging/bcm/TODO
+++ b/drivers/staging/bcm/TODO
@@ -1,15 +1,22 @@
+This driver is barely functional in its current state.
+
+BIG:
+	- existing API is (/dev/tarang) should be replaced
+	  Is it possible to use same API as Intel Wimax stack and
+	  have same user level components.
+	- Qos and queue model is non-standard and inflexible.
+	  Use existing TC Qos?
+
 TODO:
+	- support more than one board - eliminate global variables
+	- remove developer debug BCM_DEBUG() macros
+	  add a limited number of messages through netif_msg()
 	- fix non-standard kernel style
-	- sparse warnings
 	- checkpatch warnings
-   	- remove compatiablity code for older kernels
-	- remove #ifdef's
-	- fix bogus device nameing and reference counting (see bcm_notify_event)
-	- fix use of file I/O to load config
-	- request firmware
-	- update to current network device API
-	- merge some files together
+	- use request firmware
+	- fix use of file I/O to load config with better API
+	- merge some files together?
 	- cleanup/eliminate debug messages
 
-	- integrate with existing Wimax stack?
+
 
diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c
index 12f9e13..0f70009 100644
--- a/drivers/staging/bcm/Transmit.c
+++ b/drivers/staging/bcm/Transmit.c
@@ -6,7 +6,7 @@
 digraph transmit1 {
 node[shape=box]
 edge[weight=5;color=red]
-bcm_transmit->reply_to_arp_request[label="ARP"]
+
 bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
 GetPacketQueueIndex->IpVersion4[label="IPV4"]
 GetPacketQueueIndex->IpVersion6[label="IPV6"]
@@ -35,169 +35,16 @@
 
 #include "headers.h"
 
-/*******************************************************************
-* Function    -	bcm_transmit()
-*
-* Description - This is the main transmit function for our virtual
-*				interface(veth0). It handles the ARP packets. It
-*				clones this packet and then Queue it to a suitable
-* 		 		Queue. Then calls the transmit_packet().
-*
-* Parameter   -	 skb - Pointer to the socket buffer structure
-*				 dev - Pointer to the virtual net device structure
-*
-* Returns     -	 zero (success) or -ve value (failure)
-*
-*********************************************************************/
-
-INT bcm_transmit(struct sk_buff *skb, 		/**< skb */
-					struct net_device *dev 	/**< net device pointer */
-					)
-{
-	PMINI_ADAPTER      	Adapter = NULL;
-	USHORT				qindex=0;
-	struct timeval tv;
-	UINT		pkt_type = 0;
-	UINT 		calltransmit = 0;
-
-	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);
-
-	memset(&tv, 0, sizeof(tv));
-	/* Check for valid parameters */
-	if(skb == NULL || dev==NULL)
-	{
-	    BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n");
-		return -EINVAL;
-	}
-
-	Adapter = GET_BCM_ADAPTER(dev);
-	if(!Adapter)
-	{
-		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n");
-  		return -EINVAL;
-	}
-	if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
-	{
-		if(!netif_queue_stopped(dev)) {
-				netif_carrier_off(dev);
-				netif_stop_queue(dev);
-		}
-		return STATUS_FAILURE;
-	}
-	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);
-
-	/*Add Ethernet CS check here*/
-	if(Adapter->TransferMode == IP_PACKET_ONLY_MODE )
-	{
-        pkt_type = ntohs(*(PUSHORT)(skb->data + 12));
-		/* Get the queue index where the packet is to be queued */
-		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index.....");
-
-		qindex = GetPacketQueueIndex(Adapter,skb);
-
-		if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex)
-		{
-			if(pkt_type == ETH_ARP_FRAME)
-			{
-				/*
-				Reply directly to ARP request packet
-				ARP Spoofing only if NO ETH CS rule matches for it
-				*/
-				BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x",
-
-                (*(PUCHAR)(skb->data + 21)));
-
-                reply_to_arp_request(skb);
-
-                BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");
-
-			}
-			else
-			{
-                BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,
-    			"Invalid queue index, dropping pkt\n");
-
-				bcm_kfree_skb(skb);
-			}
-			return STATUS_SUCCESS;
-        }
-
-		if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
-		{
-			atomic_inc(&Adapter->TxDroppedPacketCount);
-			bcm_kfree_skb(skb);
-			return STATUS_SUCCESS;
-		}
-
-		/* Now Enqueue the packet */
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
-		spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
-		Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
-		Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
-
-		*((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
-		ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
-  	                  Adapter->PackInfo[qindex].LastTxQueue, skb);
-		atomic_inc(&Adapter->TotalPacketCount);
-		spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
-		do_gettimeofday(&tv);
-
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n",
-		(skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec);
-
-#ifdef BCM_SHM_INTERFACE
-		spin_lock(&Adapter->txtransmitlock);
-		if(Adapter->txtransmit_running == 0)
-		{
-			Adapter->txtransmit_running = 1;
-			calltransmit = 1;
-		}
-		else
-			calltransmit = 0;
-
-		spin_unlock(&Adapter->txtransmitlock);
-#endif
-		if(calltransmit == 1)
-			transmit_packets(Adapter);
-		else
-		{
-			if(!atomic_read(&Adapter->TxPktAvail))
-			{
-				atomic_set(&Adapter->TxPktAvail, 1);
-#ifdef BCM_SHM_INTERFACE
-				virtual_mail_box_interrupt();
-#endif
-				wake_up(&Adapter->tx_packet_wait_queue);
-			}
-		}
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
-	}
-	else
-		bcm_kfree_skb(skb);
-
-  return STATUS_SUCCESS;
-}
-
 
 /**
 @ingroup ctrl_pkt_functions
 This function dispatches control packet to the h/w interface
 @return zero(success) or -ve value(failure)
 */
-INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
-							char *pControlPacket/**<Control Packet*/
-							)
+INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket)
 {
-	PLEADER PLeader = NULL;
-	struct timeval tv;
-	memset(&tv, 0, sizeof(tv));
+	PLEADER PLeader = (PLEADER)pControlPacket;
 
-
-
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>");
-
-	PLeader=(PLEADER)pControlPacket;
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
 	if(!pControlPacket || !Adapter)
 	{
@@ -208,12 +55,6 @@
 		((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
     {
     	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
-       	if(Adapter->bcm_jiffies == 0)
-        {
-        	Adapter->bcm_jiffies = jiffies;
-            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu",
-				Adapter->bcm_jiffies);
-        }
         return STATUS_FAILURE;
     }
 
@@ -224,76 +65,33 @@
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
 	if(Adapter->device_removed)
 		return 0;
-#ifndef BCM_SHM_INTERFACE
+
+	if (netif_msg_pktdata(Adapter))
+		print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,
+			       16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);
+
 	Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
 					pControlPacket, (PLeader->PLength + LEADER_SIZE));
-#else
-	tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1);
 
-	if(PLeader->Status==IDLE_MESSAGE)
-	{
-		if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD &&
-		((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n");
-        	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n");
-			do_gettimeofday(&tv);
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "IdleMode Msg sent to f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
-			if(Adapter->bDoSuspend != TRUE)
-			{
-				Adapter->IdleMode = TRUE;
-				Adapter->bPreparingForLowPowerMode = FALSE ;
-			}
-		}
-	}
-	if((PLeader->Status == LINK_UP_CONTROL_REQ) &&
-		((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK &&
-		((PUCHAR)pControlPacket)[sizeof(LEADER)+1] ==
-								LINK_SHUTDOWN_REQ_FROM_FIRMWARE  &&
-		((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n");
-		if(Adapter->bDoSuspend != TRUE)
-		{
-			Adapter->bShutStatus = TRUE;
-			Adapter->bPreparingForLowPowerMode = FALSE;
-			Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
-		}
-
-	}
-#endif
-
-	((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++;
-	((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+=
-			PLeader->PLength;
 	atomic_dec(&Adapter->CurrNumFreeTxDesc);
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
 	return STATUS_SUCCESS;
 }
-static	LEADER Leader={0};
+
 /**
 @ingroup tx_functions
 This function despatches the IP packets with the given vcid
 to the target via the host h/w interface.
 @return  zero(success) or -ve value(failure)
 */
-INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
-					struct sk_buff *Packet, /**<data buffer*/
-					USHORT Vcid)			/**<VCID for this packet*/
+INT SetupNextSend(PMINI_ADAPTER Adapter,  struct sk_buff *Packet, USHORT Vcid)
 {
 	int		status=0;
-#ifdef GDMA_INTERFACE
-	int dontfree = 0;
-#endif
 	BOOLEAN bHeaderSupressionEnabled = FALSE;
 	B_UINT16            uiClassifierRuleID;
-	int QueueIndex = NO_OF_QUEUES + 1;
+	u16	QueueIndex = skb_get_queue_mapping(Packet);
+	LEADER Leader={0};
 
-	if(!Adapter || !Packet)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
-		return -EINVAL;
-	}
 	if(Packet->len > MAX_DEVICE_DESC_SIZE)
 	{
 		status = STATUS_FAILURE;
@@ -302,14 +100,10 @@
 
 	/* Get the Classifier Rule ID */
 	uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
-	QueueIndex = SearchVcid( Adapter,Vcid);
-	if(QueueIndex < NO_OF_QUEUES)
-	{
-		bHeaderSupressionEnabled =
-			Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
-		bHeaderSupressionEnabled =
-			bHeaderSupressionEnabled & Adapter->bPHSEnabled;
-	}
+
+	bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
+		& Adapter->bPHSEnabled;
+
 	if(Adapter->device_removed)
 		{
 		status = STATUS_FAILURE;
@@ -327,15 +121,10 @@
 
 	Leader.Vcid	= Vcid;
 
-    if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
-	{
-        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n");
+	if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
 		Leader.Status = LEADER_STATUS_TCP_ACK;
-	}
 	else
-	{
 		Leader.Status = LEADER_STATUS;
-	}
 
 	if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
 	{
@@ -351,68 +140,53 @@
 		skb_push(Packet, LEADER_SIZE);
 		memcpy(Packet->data, &Leader, LEADER_SIZE);
 	}
-
 	else
 	{
 		Leader.PLength = Packet->len - ETH_HLEN;
 		memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
 	}
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid);
-
-#ifndef BCM_SHM_INTERFACE
 	status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
 			Packet->data, (Leader.PLength + LEADER_SIZE));
-#else
-	status = tx_pkts_to_firmware(Packet,Packet->len,0);
-#endif
 	if(status)
 	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n");
+		++Adapter->dev->stats.tx_errors;
+		if (netif_msg_tx_err(Adapter))
+			pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
+				status);
 	}
 	else
 	{
+		struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, QueueIndex);
 		Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
-		atomic_add(Leader.PLength, &Adapter->GoodTxByteCount);
-		atomic_inc(&Adapter->TxTotalPacketCount);
-#ifdef GDMA_INTERFACE
-    dontfree = 1;
-#endif
-	}
 
-	atomic_dec(&Adapter->CurrNumFreeTxDesc);
+		txq->tx_bytes += Leader.PLength;
+		++txq->tx_packets;
 
-errExit:
-
-	if(STATUS_SUCCESS == status)
-	{
 		Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
 		Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
 		Adapter->PackInfo[QueueIndex].uiSentPackets++;
 		Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
 
 		atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
-#ifdef BCM_SHM_INTERFACE
-		if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0)
-		{
-			atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0);
-		}
-#endif
 		Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
 	}
 
+	atomic_dec(&Adapter->CurrNumFreeTxDesc);
 
-#ifdef GDMA_INTERFACE
-  if(!dontfree){
-  	bcm_kfree_skb(Packet);
-  }
-#else
-  	bcm_kfree_skb(Packet);
-#endif
+errExit:
+
+	dev_kfree_skb(Packet);
 	return status;
 }
 
+static int tx_pending(PMINI_ADAPTER Adapter)
+{
+	return (atomic_read(&Adapter->TxPktAvail)
+		&& MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
+		|| Adapter->device_removed || (1 == Adapter->downloadDDR);
+}
+
 /**
 @ingroup tx_functions
 Transmit thread
@@ -420,57 +194,26 @@
 int tx_pkt_handler(PMINI_ADAPTER Adapter  /**< pointer to adapter object*/
 				)
 {
-#ifndef BCM_SHM_INTERFACE
 	int status = 0;
-#endif
 
-	UINT calltransmit = 1;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = %p",Adapter);
-
-
-	while(1)
-	{
-		if(Adapter->LinkUpStatus){
+	while(! kthread_should_stop()) {
+		/* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
+		if(Adapter->LinkUpStatus)
 			wait_event_timeout(Adapter->tx_packet_wait_queue,
-				((atomic_read(&Adapter->TxPktAvail) &&
-				(MINIMUM_PENDING_DESCRIPTORS <
-				atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
-				(Adapter->device_removed == FALSE))) ||
-				(1 == Adapter->downloadDDR) || kthread_should_stop()
-#ifndef BCM_SHM_INTERFACE
-				|| (TRUE == Adapter->bEndPointHalted)
-#endif
-				, msecs_to_jiffies(10));
-		}
-		else{
-			wait_event(Adapter->tx_packet_wait_queue,
-				((atomic_read(&Adapter->TxPktAvail) &&
-				(MINIMUM_PENDING_DESCRIPTORS <
-				atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
-				(Adapter->device_removed == FALSE))) ||
-				(1 == Adapter->downloadDDR) || kthread_should_stop()
-#ifndef BCM_SHM_INTERFACE
-				|| (TRUE == Adapter->bEndPointHalted)
-#endif
-				);
-		}
+					   tx_pending(Adapter), msecs_to_jiffies(10));
+		else
+			wait_event_interruptible(Adapter->tx_packet_wait_queue,
+						 tx_pending(Adapter));
 
-		if(kthread_should_stop() || Adapter->device_removed)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
-			Adapter->transmit_packet_thread = NULL;
-			return 0;
-		}
-
-#ifndef BCM_SHM_INTERFACE
+		if (Adapter->device_removed)
+			break;
 
 		if(Adapter->downloadDDR == 1)
 		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n");
 			Adapter->downloadDDR +=1;
 			status = download_ddr_settings(Adapter);
 			if(status)
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n");
+				pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
 			continue;
 		}
 
@@ -489,7 +232,6 @@
 				update_per_sf_desc_cnts(Adapter);
 			}
 		}
-#endif
 
 		if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
 			Adapter->LinkStatus == SYNC_UP_REQUEST &&
@@ -507,49 +249,12 @@
 				wake_up(&Adapter->process_rx_cntrlpkt);
 		}
 
-#ifdef BCM_SHM_INTERFACE
-		spin_lock_bh(&Adapter->txtransmitlock);
-		if(Adapter->txtransmit_running == 0)
-		{
-			Adapter->txtransmit_running = 1;
-			calltransmit = 1;
-		}
-		else
-			calltransmit = 0;
-		spin_unlock_bh(&Adapter->txtransmitlock);
-#endif
-
-		if(calltransmit)
-			transmit_packets(Adapter);
+		transmit_packets(Adapter);
 
 		atomic_set(&Adapter->TxPktAvail, 0);
 	}
+
+	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
+	Adapter->transmit_packet_thread = NULL;
 	return 0;
 }
-
-#ifdef BCM_SHM_INTERFACE
-extern PMINI_ADAPTER psAdaptertest;
-void  virtual_mail_box_interrupt(void)
-{
-
-#ifndef GDMA_INTERFACE
-	PUINT ptr =  (PUINT)CPE_VIRTUAL_MAILBOX_REG;
-	UINT intval = (UINT)((*ptr & 0xFF00) >> 8);
-	if (intval != 0)
-	{
-		atomic_set(&psAdaptertest->CurrNumFreeTxDesc,	intval);
-		atomic_set (&psAdaptertest->uiMBupdate, TRUE);
-
-		//make it to 0
-		*ptr = *ptr & 0xffff00ff;
-	}
-#endif
-}
-unsigned int total_tx_pkts_pending(void)
-{
-	return atomic_read(&psAdaptertest->TotalPacketCount);
-}
-
-#endif
-
-
diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h
index 4cbe300..8907784 100644
--- a/drivers/staging/bcm/cntrl_SignalingInterface.h
+++ b/drivers/staging/bcm/cntrl_SignalingInterface.h
@@ -2,19 +2,6 @@
 #define CNTRL_SIGNALING_INTERFACE_
 
 
-#ifdef BECEEM_TARGET
-
-#include <mac_common.h>
-#include <msg_Dsa.h>
-#include <msg_Dsc.h>
-#include <msg_Dsd.h>
-#include <sch_definitions.h>
-using namespace Beceem;
-#ifdef ENABLE_CORRIGENDUM2_UPDATE
-extern B_UINT32 g_u32Corr2MacFlags;
-#endif
-
-#else
 
 
 #define DSA_REQ 11
@@ -28,7 +15,6 @@
 #define DSD_ACK 19
 #define MAX_CLASSIFIERS_IN_SF  4
 
-#endif
 
 #define MAX_STRING_LEN 20
 #define MAX_PHS_LENGTHS 255
@@ -57,37 +43,7 @@
 ////////////////////////structure Definitions///////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 /// \brief class cCPacketClassificationRule
-#ifdef BECEEM_TARGET
-class CCPacketClassificationRuleSI{
-	public:
-		/// \brief Constructor for the class
-	CCPacketClassificationRuleSI():
-		u8ClassifierRulePriority(mClassifierRulePriority),
-		u8IPTypeOfServiceLength(mIPTypeOfService),
-		u8Protocol(mProtocol),
-		u8IPMaskedSourceAddressLength(0),
-		u8IPDestinationAddressLength(0),
-		u8ProtocolSourcePortRangeLength(0),
-		u8ProtocolDestPortRangeLength(0),
-		u8EthernetDestMacAddressLength(0),
-		u8EthernetSourceMACAddressLength(0),
-		u8EthertypeLength(0),
-		u16UserPriority(mUserPriority),
-		u16VLANID(mVLANID),
-		u8AssociatedPHSI(mAssociatedPHSI),
-		u16PacketClassificationRuleIndex(mPacketClassifierRuleIndex),
-		u8VendorSpecificClassifierParamLength(mVendorSpecificClassifierParamLength),
-		u8IPv6FlowLableLength(mIPv6FlowLableLength),
-		u8ClassifierActionRule(mClassifierActionRule)
-
-		{}
-              void Reset()
-              {
-                    CCPacketClassificationRuleSI();
-              }
-#else
 struct _stCPacketClassificationRuleSI{
-#endif
 
 	/**  16bit UserPriority Of The Service Flow*/
     B_UINT16                        u16UserPriority;
@@ -145,29 +101,10 @@
     B_UINT8							u8ClassifierActionRule;
     B_UINT16							u16ValidityBitMap;
 };
-#ifndef BECEEM_TARGET
 typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
-#endif
 
 /// \brief class CPhsRuleSI
-#ifdef BECEEM_TARGET
-class CPhsRuleSI{
-	public:
-		/// \brief Constructor for the class
-		CPhsRuleSI():
-			u8PHSI(mPHSI),
-			u8PHSFLength(0),
-			u8PHSMLength(0),
-			u8PHSS(mPHSS),
-			u8PHSV(mPHSV),
-			u8VendorSpecificPHSParamsLength(mVendorSpecificPHSParamLength){}
-                void Reset()
-                {
-        		CPhsRuleSI();
-                }
-#else
 typedef struct _stPhsRuleSI {
-#endif
 	/**  8bit PHS Index Of The Service Flow*/
     B_UINT8                         u8PHSI;
 	/**  PHSF Length Of The Service Flow*/
@@ -188,31 +125,11 @@
     B_UINT8                         u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
 
 	B_UINT8                         u8Padding[2];
-#ifdef BECEEM_TARGET
-};
-#else
 }stPhsRuleSI,*pstPhsRuleSI;
 typedef stPhsRuleSI CPhsRuleSI;
-#endif
 
 /// \brief structure cConvergenceSLTypes
-#ifdef BECEEM_TARGET
-class CConvergenceSLTypes{
-	public:
-		/// \brief Constructor for the class
-		CConvergenceSLTypes():
-		u8ClassfierDSCAction(mClassifierDSCAction),
-		u8PhsDSCAction	(mPhsDSCAction)
-		{}
-              void Reset()
-              {
-                    CConvergenceSLTypes();
-                    cCPacketClassificationRule.Reset();
-                    cPhsRule.Reset();
-              }
-#else
 struct _stConvergenceSLTypes{
-#endif
 	/**  8bit Phs Classfier Action Of The Service Flow*/
     B_UINT8                         u8ClassfierDSCAction;
 	/**  8bit Phs DSC Action Of The Service Flow*/
@@ -220,111 +137,15 @@
 	/**   16bit Padding */
     B_UINT8                         u8Padding[2];
     /// \brief class cCPacketClassificationRule
-#ifdef BECEEM_TARGET
-    CCPacketClassificationRuleSI      cCPacketClassificationRule;
-#else
     stCPacketClassificationRuleSI     cCPacketClassificationRule;
-#endif
     /// \brief class CPhsRuleSI
-#ifdef BECEEM_TARGET
-    CPhsRuleSI				cPhsRule;
-#else
      struct _stPhsRuleSI		cPhsRule;
-#endif
 };
-#ifndef BECEEM_TARGET
 typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
-#endif
 
 
 /// \brief structure CServiceFlowParamSI
-#ifdef BECEEM_TARGET
-class CServiceFlowParamSI{
-	public:
-		/// \brief Constructor for the class
-		CServiceFlowParamSI():
-			u32SFID(mSFid),
-			u16CID(mCid),
-			u8ServiceClassNameLength(mServiceClassNameLength),
-			u8MBSService(mMBSService),
-			u8QosParamSet(mQosParamSetType),
-			u8TrafficPriority(mTrafficPriority),
-			u32MaxSustainedTrafficRate(mMaximumSustainedTrafficRate),
-			u32MaxTrafficBurst(mMaximumTrafficBurst),
-			u32MinReservedTrafficRate(mMinimumReservedTrafficRate),
-			u8ServiceFlowSchedulingType(mServiceFlowSchedulingType),
-			u8RequesttransmissionPolicy(mRequestTransmissionPolicy),
-			u32ToleratedJitter(mToleratedJitter),
-			u32MaximumLatency(mMaximumLatency),
-			u8FixedLengthVSVariableLengthSDUIndicator
-			(mFixedLengthVSVariableLength),
-			u8SDUSize(mSDUSize),
-			u16TargetSAID(mTargetSAID),
-			u8ARQEnable(mARQEnable),
-			u16ARQWindowSize(mARQWindowSize),
-			u16ARQBlockLifeTime(mARQBlockLifeTime),
-			u16ARQSyncLossTimeOut(mARQSyncLossTimeOut),
-			u8ARQDeliverInOrder(mARQDeliverInOrder),
-			u16ARQRxPurgeTimeOut(mARQRXPurgeTimeOut),
-			//Add ARQ BLOCK SIZE, ARQ TX and RX delay initializations here
-			//after we move to only CORR2
-			u8RxARQAckProcessingTime(mRxARQAckProcessingTime),
-			u8CSSpecification(mCSSpecification),
-			u8TypeOfDataDeliveryService(mTypeOfDataDeliveryService),
-			u16SDUInterArrivalTime(mSDUInterArrivalTime),
-			u16TimeBase(mTimeBase),
-			u8PagingPreference(mPagingPreference),
-			u8MBSZoneIdentifierassignment(mMBSZoneIdentifierassignmentLength),
-			u8TrafficIndicationPreference(mTrafficIndicationPreference),
-			u8GlobalServicesClassNameLength(mGlobalServicesClassNameLength),
-			u8SNFeedbackEnabled(mSNFeedbackEnabled),
-			u8FSNSize(mFSNSize),
-			u8CIDAllocation4activeBSsLength(mCIDAllocation4activeBSsLength),
-			u16UnsolicitedGrantInterval(mUnsolicitedGrantInterval),
-			u16UnsolicitedPollingInterval(mUnsolicitedPollingInterval),
-			u8PDUSNExtendedSubheader4HarqReordering(mPDUSNExtendedSubheader4HarqReordering),
-			u8MBSContentsIDLength(mMBSContentsIDLength),
-			u8HARQServiceFlows(mHARQServiceFlows),
-			u8AuthTokenLength(mAuthTokenLength),
-			u8HarqChannelMappingLength(mHarqChannelMappingLength),
-			u8VendorSpecificQoSParamLength(mVendorSpecificQoSParamLength),
-            bValid(FALSE),
-	     u8TotalClassifiers()
-{
-//Remove the bolck after we move to Corr2 only code
-#ifdef ENABLE_CORRIGENDUM2_UPDATE
-	if((g_u32Corr2MacFlags & CORR_2_DSX)  ||  (g_u32Corr2MacFlags & CORR_2_ARQ))
-	{
-	/* IEEE Comment #627 / MTG Comment #426 */
-       	u16ARQBlockSize = mARQBlockSize;
-		if(g_u32Corr2MacFlags & CORR_2_ARQ) {
-			u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelay;
-			if(g_u32VENDOR_TYPE == VENDOR_ALCATEL) {
-				u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay_ALU;
-			} else {
-				u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay;
-			}
-		}
-		else
-		{
-			u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1;
-			u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1;
-		}
-	}
-	else
-#endif
-	{
-		u16ARQBlockSize = mARQBlockSizeCorr1;
-		u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1;
-		u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1;
-	}
-}
-
-	void ComputeMacOverhead(B_UINT8	u8SecOvrhead);
-	B_UINT16	GetMacOverhead() { return 	u16MacOverhead; }
-#else
 typedef struct _stServiceFlowParamSI{
-#endif //end of ifdef BECEEM_TARGET
 
      /**  32bitSFID Of The Service Flow*/
     B_UINT32                        u32SFID;
@@ -367,11 +188,6 @@
 
 	 /**  16bit ARQ Purge timeout */
     B_UINT16                        u16ARQRxPurgeTimeOut;
-#if 0 //def ENABLE_CORRIGENDUM2_UPDATE
-/* IEEE Comment #627 / MTG Comment #426 */
-    /// \brief Size of an ARQ block, changed from 2 bytes to 1
-    B_UINT8                        u8ARQBlockSize;
-#endif
 //TODO::Remove this once we move to a new CORR2 driver
     /// \brief Size of an ARQ block
     B_UINT16                        u16ARQBlockSize;
@@ -496,35 +312,18 @@
 	B_UINT8							bValid;	/**<  Validity flag */
 	B_UINT8				u8Padding;	 /**<  Padding byte*/
 
-#ifdef BECEEM_TARGET
-/**
-Structure for Convergence SubLayer Types with a maximum of 4 classifiers
-*/
-	CConvergenceSLTypes		cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
-#else
 /**
 Structure for Convergence SubLayer Types with a maximum of 4 classifiers
 */
 	stConvergenceSLTypes		cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
-#endif
 
-#ifdef BECEEM_TARGET
-};
-#else
 } stServiceFlowParamSI, *pstServiceFlowParamSI;
 typedef stServiceFlowParamSI CServiceFlowParamSI;
-#endif
 
 /**
 structure stLocalSFAddRequest
 */
 typedef struct _stLocalSFAddRequest{
-#ifdef BECEEM_TARGET
-	   _stLocalSFAddRequest( ) :
-	   	u8Type(0x00),  eConnectionDir(0x00),
-		u16TID(0x0000), u16CID(0x0000),  u16VCID(0x0000)
-	   		{}
-#endif
 
 	B_UINT8                         u8Type;	/**<  Type*/
 	B_UINT8      eConnectionDir;		/**<  Connection direction*/
@@ -535,19 +334,9 @@
 	/// \brief 16bitVCID
 	B_UINT16                        u16VCID;	/**<  16bit VCID*/
     /// \brief structure ParameterSet
-#ifdef BECEEM_SIGNALLING_INTERFACE_API
-	CServiceFlowParamSI sfParameterSet;
-#endif
 
-#ifdef BECEEM_TARGET
-    CServiceFlowParamSI              *psfParameterSet;
-#else
 	stServiceFlowParamSI	*psfParameterSet;	/**<  structure ParameterSet*/
-#endif
 
-#ifdef USING_VXWORKS
-    USE_DATA_MEMORY_MANAGER();
-#endif
 }stLocalSFAddRequest, *pstLocalSFAddRequest;
 
 
@@ -555,12 +344,6 @@
 structure stLocalSFAddIndication
 */
 typedef struct _stLocalSFAddIndication{
-#ifdef BECEEM_TARGET
-	   _stLocalSFAddIndication( ) :
-	   	u8Type(0x00),  eConnectionDir(0x00),
-		u16TID(0x0000), u16CID(0x0000),  u16VCID(0x0000)
-	   		{}
-#endif
 
 	B_UINT8                         u8Type;	/**<  Type*/
 	B_UINT8      eConnectionDir;	/**<  Connection Direction*/
@@ -571,37 +354,19 @@
     /// \brief 16bitVCID
     B_UINT16                        u16VCID;	 /**<  16bitVCID*/
 
-#ifdef 	BECEEM_SIGNALLING_INTERFACE_API
-	CServiceFlowParamSI              sfAuthorizedSet;
-    /// \brief structure AdmittedSet
-    CServiceFlowParamSI              sfAdmittedSet;
-    /// \brief structure ActiveSet
-    CServiceFlowParamSI              sfActiveSet;
-#endif
 
     /// \brief structure AuthorizedSet
-#ifdef BECEEM_TARGET
-    CServiceFlowParamSI              *psfAuthorizedSet;
-    /// \brief structure AdmittedSet
-    CServiceFlowParamSI              *psfAdmittedSet;
-    /// \brief structure ActiveSet
-    CServiceFlowParamSI              *psfActiveSet;
-#else
     /// \brief structure AuthorizedSet
     stServiceFlowParamSI              *psfAuthorizedSet;	/**<  AuthorizedSet of type stServiceFlowParamSI*/
     /// \brief structure AdmittedSet
     stServiceFlowParamSI              *psfAdmittedSet;	/**<  AdmittedSet of type stServiceFlowParamSI*/
     /// \brief structure ActiveSet
     stServiceFlowParamSI              *psfActiveSet;	/**<  sfActiveSet of type stServiceFlowParamSI*/
-#endif
 	B_UINT8				   u8CC;	/**<  Confirmation Code*/
 	B_UINT8				   u8Padd;		/**<  8-bit Padding */
 
     B_UINT16               u16Padd;	/**< 16 bit Padding */
 
-#ifdef USING_VXWORKS
-    USE_DATA_MEMORY_MANAGER();
-#endif
 }stLocalSFAddIndication;
 
 
@@ -619,33 +384,17 @@
 structure stLocalSFDeleteRequest
 */
 typedef struct _stLocalSFDeleteRequest{
-#ifdef BECEEM_TARGET
-	   _stLocalSFDeleteRequest( ) :
-	   	u8Type(0x00),  u8Padding(0x00),
-		u16TID(0x0000), u32SFID (0x00000000)
-	   		{}
-#endif
 	B_UINT8                         u8Type;	 /**< Type*/
 	B_UINT8                         u8Padding;	 /**<  Padding byte*/
 	B_UINT16			u16TID;		 /**<  TID*/
     /// \brief 32bitSFID
     B_UINT32                        u32SFID;	 /**<  SFID*/
-#ifdef USING_VXWORKS
-    USE_DATA_MEMORY_MANAGER();
-#endif
 }stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
 
 /**
 structure stLocalSFDeleteIndication
 */
 typedef struct stLocalSFDeleteIndication{
-#ifdef BECEEM_TARGET
-	   stLocalSFDeleteIndication( ) :
-	   	u8Type(0x00),  u8Padding(0x00),
-		u16TID(0x0000), u16CID(0x0000),
-		u16VCID(0x0000),u32SFID (0x00000000)
-	   		{}
-#endif
 	B_UINT8                         u8Type;	/**< Type */
 	B_UINT8                         u8Padding;	/**< Padding  */
 	B_UINT16			u16TID;			/**< TID */
@@ -658,9 +407,6 @@
 	/// \brief 8bit Confirmation code
 	B_UINT8                         u8ConfirmationCode;	/**< Confirmation code */
 	B_UINT8                         u8Padding1[3];		/**< 3 byte Padding  */
-#ifdef USING_VXWORKS
-    USE_DATA_MEMORY_MANAGER();
-#endif
 }stLocalSFDeleteIndication;
 
 typedef struct _stIM_SFHostNotify
diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h
index 9d4e3ac..473f11e 100644
--- a/drivers/staging/bcm/headers.h
+++ b/drivers/staging/bcm/headers.h
@@ -22,7 +22,6 @@
 #include <linux/etherdevice.h>
 #include <net/ip.h>
 #include <linux/wait.h>
-#include <linux/notifier.h>
 #include <linux/proc_fs.h>
 #include <linux/interrupt.h>
 
@@ -41,21 +40,7 @@
 #endif
 #include <linux/tcp.h>
 #include <linux/udp.h>
-#ifndef BCM_SHM_INTERFACE
 #include <linux/usb.h>
-#endif
-#ifdef BECEEM_TARGET
-
-#include <mac_common.h>
-#include <msg_Dsa.h>
-#include <msg_Dsc.h>
-#include <msg_Dsd.h>
-#include <sch_definitions.h>
-using namespace Beceem;
-#ifdef ENABLE_CORRIGENDUM2_UPDATE
-extern B_UINT32 g_u32Corr2MacFlags;
-#endif
-#endif
 
 #include "Typedefs.h"
 #include "Version.h"
@@ -71,39 +56,28 @@
 #include "CmHost.h"
 #include "DDRInit.h"
 #include "Debug.h"
-#include "HostMibs.h"
 #include "IPv6ProtocolHdr.h"
-#include "osal_misc.h"
 #include "PHSModule.h"
 #include "Protocol.h"
 #include "Prototypes.h"
 #include "Queue.h"
 #include "vendorspecificextn.h"
 
-#ifndef BCM_SHM_INTERFACE
 
 #include "InterfaceMacros.h"
 #include "InterfaceAdapter.h"
 #include "InterfaceIsr.h"
-#include "Interfacemain.h"
 #include "InterfaceMisc.h"
 #include "InterfaceRx.h"
 #include "InterfaceTx.h"
-#endif
 #include "InterfaceIdleMode.h"
 #include "InterfaceInit.h"
 
-#ifdef BCM_SHM_INTERFACE
-#include <linux/cpe_config.h>
-
-#ifdef GDMA_INTERFACE
-#include "GdmaInterface.h"
-#include "symphony.h"
-#else
-#include "virtual_interface.h"
-
-#endif
-
-#endif
+#define DRV_NAME	"beceem"
+#define DEV_NAME	"tarang"
+#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver"
+#define DRV_COPYRIGHT	"Copyright 2010. Beceem Communications Inc"
+#define DRV_VERSION	VER_FILEVERSION_STR
+#define PFX		DRV_NAME " "
 
 #endif
diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c
index e9da513..c13ea5c 100644
--- a/drivers/staging/bcm/hostmibs.c
+++ b/drivers/staging/bcm/hostmibs.c
@@ -10,12 +10,8 @@
  */
 #include "headers.h"
 
-INT  ProcessGetHostMibs(PMINI_ADAPTER Adapter,
-						  PVOID ioBuffer,
-						  ULONG inputBufferLength)
+INT  ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
 {
-
-	S_MIBS_HOST_STATS_MIBS *pstHostMibs         = NULL;
 	S_SERVICEFLOW_ENTRY    *pstServiceFlowEntry = NULL;
 	S_PHS_RULE             *pstPhsRule          = NULL;
 	S_CLASSIFIER_TABLE     *pstClassifierTable  = NULL;
@@ -30,15 +26,6 @@
 		return STATUS_FAILURE;
 	}
 
-	if(ioBuffer == NULL)
-	{
-		return -EINVAL;
-	}
-	memset(ioBuffer,0,sizeof(S_MIBS_HOST_STATS_MIBS));
-
-	pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer;
-
-
 	//Copy the classifier Table
 	for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS;
 			nClassifierIndex++)
@@ -54,7 +41,7 @@
 	{
 	if(Adapter->PackInfo[nSfIndex].bValid)
 	{
-			OsalMemMove((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE));
+			memcpy((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE));
 	}
 	else
 	{
@@ -83,7 +70,7 @@
 
 			pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
 
-			OsalMemMove(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
+			memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
 						&pstPhsRule->u8PHSI,
 						sizeof(S_PHS_RULE));
 				nPhsTableIndex++;
@@ -95,12 +82,9 @@
 	}
 
 
-
 	//copy other Host Statistics parameters
-	pstHostMibs->stHostInfo.GoodTransmits =
-				atomic_read(&Adapter->TxTotalPacketCount);
-	pstHostMibs->stHostInfo.GoodReceives =
-				atomic_read(&Adapter->GoodRxPktCount);
+	pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets;
+	pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets;
 	pstHostMibs->stHostInfo.CurrNumFreeDesc =
 			atomic_read(&Adapter->CurrNumFreeTxDesc);
 	pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
@@ -115,13 +99,10 @@
 }
 
 
-INT GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang)
+VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, const PPER_TARANG_DATA pTarang)
 {
-	S_MIBS_HOST_STATS_MIBS *pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer;
-
-	memcpy((PVOID)&(pstHostMibs->stDroppedAppCntrlMsgs),(PVOID)&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
-
-	return STATUS_SUCCESS ;
+	memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
+	       &(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
 }
 
 
diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c
index 97adaae..16e939f 100644
--- a/drivers/staging/bcm/led_control.c
+++ b/drivers/staging/bcm/led_control.c
@@ -108,52 +108,16 @@
 	ulong timeout = 0;
 
 	/*Read initial value of packets sent/received */
-	Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
-	Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
+	Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
+	Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
+
 	/*Scale the rate of transfer to no of blinks.*/
 	num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
 	num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
 
 	while((Adapter->device_removed == FALSE))
 	{
-		#if 0
-		if(0 == num_of_time_tx && 0 == num_of_time_rx)
-		{
-			timeout = 1000;
-			Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
-				currdriverstate!= Adapter->DriverState || kthread_should_stop(),
-				msecs_to_jiffies (timeout));
-			if(kthread_should_stop())
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
-				Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
-				return EVENT_SIGNALED;
-			}
-			if(Status)
-				return EVENT_SIGNALED;
-
-		}
-		#endif
-
 		timeout = 50;
-		#if 0
-		/*Turn on LED if Tx is high bandwidth*/
-		if(num_of_time_tx > MAX_NUM_OF_BLINKS)
-		{
-			TURN_ON_LED(1<<GPIO_Num_tx, uiTxLedIndex);
-			num_of_time_tx = 0;
-			bBlinkBothLED = FALSE;
-			num_of_time = num_of_time_rx;
-		}
-			/*Turn on LED if Rx is high bandwidth*/
-		if(num_of_time_rx > MAX_NUM_OF_BLINKS)
-		{
-			TURN_ON_LED(1<<GPIO_Num_rx, uiRxLedIndex);
-			num_of_time_rx = 0;
-			bBlinkBothLED = FALSE;
-			num_of_time = num_of_time_tx;
-		}
-		#endif
 		/*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
 		if(bBlinkBothLED)
 		{
@@ -249,9 +213,10 @@
  		 * Read the Tx & Rx packets transmission after 1 second and
  		 * calculate rate of transfer
  		 */
-		Final_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
+		Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
+		Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
+
 		rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
-		Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
 		rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
 
 		/*Read initial value of packets sent/received */
@@ -293,7 +258,7 @@
 
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
 
-	puBuffer = OsalMemAlloc(usParamLen,"!MEM");
+	puBuffer = kmalloc(usParamLen, GFP_KERNEL);
 	if(!puBuffer)
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
@@ -341,10 +306,7 @@
 	}
 
 exit:
-	if(puBuffer)
-	{
-		OsalMemFree(puBuffer, usParamLen);
-	}
+	kfree(puBuffer);
 	return Status;
 }
 
@@ -497,12 +459,10 @@
 {
 	int Status = STATUS_SUCCESS;
 	UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
-#ifndef BCM_SHM_INTERFACE
 	UINT uiIndex = 0;
 	UINT uiNum_of_LED_Type = 0;
 	PUCHAR puCFGData	= NULL;
 	UCHAR bData = 0;
-#endif
 	memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
 
 	if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
@@ -524,10 +484,6 @@
 		*bEnableThread = FALSE;
 		return Status;
 	}
-#ifdef BCM_SHM_INTERFACE
-	*bEnableThread = FALSE;
-	return Status ;
-#else
   /*
      * CONFIG file read successfully. Deallocate the memory of
      * uiFileNameBufferSize
@@ -578,23 +534,7 @@
 	}
 	if(uiNum_of_LED_Type >= NUM_OF_LEDS)
 		*bEnableThread = FALSE;
-#endif
 
-#if 0
-	for(uiIndex=0; uiIndex<NUM_OF_LEDS; uiIndex++)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Type = %x\n", uiIndex,
-			Adapter->LEDInfo.LEDState[uiIndex].LED_Type);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_On_State = %x\n", uiIndex,
-			Adapter->LEDInfo.LEDState[uiIndex].LED_On_State);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Blink_State = %x\n", uiIndex,
-			Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].GPIO_Num = %x\n", uiIndex,
-			Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
-	}
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Polarity = %d\n",
-			Adapter->LEDInfo.BitPolarty);
-#endif
 	return Status;
 }
 //--------------------------------------------------------------------------
@@ -721,20 +661,6 @@
 			TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
 			return ;//STATUS_FAILURE;
 		}
-	#if 0
-		if(Adapter->device_removed)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Device removed hence exiting from Led Thread..");
-			return ; //-ENODEV;
-		}
-	#endif
-		#if 0
-		if((GPIO_num != DISABLE_GPIO_NUM) &&
-			((currdriverstate != FW_DOWNLOAD) &&
-			(currdriverstate != NORMAL_OPERATION) &&
-			(currdriverstate != IDLEMODE_EXIT)))
-			TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
-		#endif
 
 		if(GPIO_num != DISABLE_GPIO_NUM)
 		{
@@ -752,10 +678,6 @@
 			case DRIVER_INIT:
 			{
 				currdriverstate = DRIVER_INIT;//Adapter->DriverState;
-	#if 0
-				LedGpioInit(Adapter);
-				Adapter->LEDInfo.bLedInitDone = TRUE;
-	#endif
 				BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
 
 				if(GPIO_num  != DISABLE_GPIO_NUM)
@@ -768,13 +690,6 @@
 			{
 				//BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
 				currdriverstate = FW_DOWNLOAD;
-			#if 0
-				if(Adapter->LEDInfo.bLedInitDone == FALSE)
-				{
-					LedGpioInit(Adapter);
-					Adapter->LEDInfo.bLedInitDone = TRUE;
-				}
-			#endif
 				BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,  &uiLedIndex, &dummyIndex, currdriverstate);
 
 				if(GPIO_num != DISABLE_GPIO_NUM)
@@ -796,12 +711,6 @@
 			break;
 
 			case SHUTDOWN_EXIT:
-			#if 0
-			if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN)
-			{
-				LedGpioInit(Adapter);
-			}
-			#endif
 			//no break, continue to NO_NETWORK_ENTRY state as well.
 
 			case NO_NETWORK_ENTRY:
@@ -875,34 +784,6 @@
 			break;
 			case IDLEMODE_EXIT:
 			{
-#if 0
-				UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
-				UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
-				UCHAR uiTxLedIndex = 0;
-				UCHAR uiRxLedIndex = 0;
-
-				currdriverstate  = IDLEMODE_EXIT;
-				if(DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN == Adapter->ulPowerSaveMode)
-				{
-					LedGpioInit(Adapter);
-				}
-				BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiTxLedIndex,&uiRxLedIndex,currdriverstate);
-
-				Adapter->LEDInfo.bIdle_led_off =  FALSE;
-
-				if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
-				{
-					GPIO_num = DISABLE_GPIO_NUM ;
-				}
-				else
-				{
-					timeout = 50;
-					if(Adapter->LEDInfo.bIdleMode_tx_from_host)
-						LED_Blink(Adapter, 1<<GPIO_num_tx, uiTxLedIndex, timeout, -1,currdriverstate);
-					else
-						LED_Blink(Adapter, 1<<GPIO_num_rx, uiRxLedIndex, timeout, -1,currdriverstate);
-				}
-#endif
 			}
 			break;
 			case DRIVER_HALT:
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
index 41c9ab8..c729237 100644
--- a/drivers/staging/bcm/nvm.c
+++ b/drivers/staging/bcm/nvm.c
@@ -1,6 +1,56 @@
 #include "headers.h"
 
 #define DWORD unsigned int
+
+static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
+static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
+static INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
+static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
+static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
+static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
+
+static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
+static INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
+static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
+static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
+
+static INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+
+static B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
+static INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
+static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
+
+static INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
+static INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
+static INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
+static INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
+
+static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
+static INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
+static INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, PUINT pBuff,
+					  FLASH2X_SECTION_VAL eFlash2xSectionVal,
+					  UINT uiOffset, UINT uiNumBytes);
+static FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
+static FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
+
+static INT BeceemFlashBulkRead(
+	PMINI_ADAPTER Adapter,
+	PUINT pBuffer,
+	UINT uiOffset,
+	UINT uiNumBytes);
+
+static INT BeceemFlashBulkWrite(
+	PMINI_ADAPTER Adapter,
+	PUINT pBuffer,
+	UINT uiOffset,
+	UINT uiNumBytes,
+	BOOLEAN bVerify);
+
+static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
+
+static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
+
 // Procedure:	ReadEEPROMStatusRegister
 //
 // Description: Reads the standard EEPROM Status Register.
@@ -228,213 +278,27 @@
 		ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
 	}
 
-	OsalMemMove( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);
+	memcpy( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);
 
 	return STATUS_SUCCESS;
 } /* ReadBeceemEEPROM() */
 
 
-#if 0
-//-----------------------------------------------------------------------------
-// Procedure:	IsEEPROMWriteDone
-//
-// Description: Reads the SPI status to see the status of previous write.
-//
-// Arguments:
-//		Adapter    - ptr to Adapter object instance
-//
-// Returns:
-//		BOOLEAN - TRUE  - write went through
-//              - FALSE - Write Failed.
-//-----------------------------------------------------------------------------
-
-BOOLEAN IsEEPROMWriteDone(PMINI_ADAPTER Adapter)
-{
-	UINT uiRetries = 16;
-	//UINT uiStatus  = 0;
-	UINT value;
-
-	//sleep for 1.2ms ..worst case EEPROM write can take up to 1.2ms.
-	mdelay(2);
-
-	value = 0;
-	rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
-
-	while(((value >> 14) & 1) == 1)
-	{
-		// EEPROM_SPI_Q_STATUS1_REG will be cleared only if write back to that.
-		value = (0x1 << 14);
-		wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
-		udelay(1000);
-		uiRetries--;
-		if(uiRetries == 0)
-		{
-			return FALSE;
-		}
-		value = 0;
-		rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
-	}
-	return TRUE;
-
-
-}
-
-
-//-----------------------------------------------------------------------------
-// Procedure:	ReadBeceemEEPROMBulk
-//
-// Description: This routine reads 16Byte data from EEPROM
-//
-// Arguments:
-//		Adapter     - ptr to Adapter object instance
-//          dwAddress - EEPROM Offset to read the data from.
-//          pdwData    - Pointer to double word where data needs to be stored in.
-//
-// Returns:
-//		OSAL_STATUS_CODE:
-//-----------------------------------------------------------------------------
-
-INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData)
-{
-	DWORD dwRetries = 16;
-	DWORD dwIndex = 0;
-	UINT value, tmpVal;
-
-
-	value = 0;
-	rdmalt (Adapter, 0x0f003008, &value, sizeof(value));
-
-	//read 0x0f003020 untill  bit 1 of 0x0f003008 is set.
-	while(((value >> 1) & 1) == 0)
-	{
-
-		rdmalt (Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal));
-		dwRetries--;
-		if(dwRetries == 0)
-		{
-			return -1;
-		}
-		value = 0;
-		rdmalt (Adapter, 0x0f003008, &value, sizeof(value));
-	}
-
-	value = dwAddress | 0xfb000000;
-	wrmalt (Adapter, 0x0f003018, &value, sizeof(value));
-
-	udelay(1000);
-	value = 0;
-	for(dwIndex = 0;dwIndex < 4 ; dwIndex++)
-	{
-		value = 0;
-		rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
-		pdwData[dwIndex] = value;
-
-		value = 0;
-		rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
-		pdwData[dwIndex] |= (value << 8);
-
-		value = 0;
-		rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
-		pdwData[dwIndex] |= (value << 16);
-
-		value = 0;
-		rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
-		pdwData[dwIndex] |= (value << 24);
-
-	}
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Procedure:	ReadBeceemEEPROM
-//
-// Description: This routine reads 4Byte data from EEPROM
-//
-// Arguments:
-//		Adapter     - ptr to Adapter object instance
-//          dwAddress - EEPROM Offset to read the data from.
-//          pdwData    - Pointer to double word where data needs to be stored in.
-//
-// Returns:
-//		OSAL_STATUS_CODE:
-//-----------------------------------------------------------------------------
-
-INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData)
-{
-
-	DWORD dwReadValue = 0;
-	DWORD dwRetries = 16, dwCompleteWord = 0;
-	UINT	value, tmpVal;
-
-	rdmalt(Adapter, 0x0f003008, &value, sizeof(value));
-	while (((value >> 1) & 1) == 0) {
-		rdmalt(Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal));
-
-		if (dwRetries == 0) {
-			return -1;
-		}
-		rdmalt(Adapter, 0x0f003008, &value, sizeof(value));
-	}
-
-
-	//wrm (0x0f003018, 0xNbXXXXXX)      // N is the number of bytes u want to read  (0 means 1, f means 16,   b is the opcode for page read)
-	//     Follow it up by N executions of  rdm(0x0f003020) to read the rxed bytes from rx queue.
-	dwAddress |= 0x3b000000;
-	wrmalt(Adapter, 0x0f003018,&dwAddress,4);
-	mdelay(10);
-	rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
-	dwCompleteWord=dwReadValue;
-	rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
-	dwCompleteWord|=(dwReadValue<<8);
-	rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
-	dwCompleteWord|=(dwReadValue<<16);
-	rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
-	dwCompleteWord|=(dwReadValue<<24);
-
-	*pdwData = dwCompleteWord;
-
-	return 0;
-}
-#endif
 
 INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter)
 {
-	INT Status=0, i;
-	unsigned char puMacAddr[6] = {0};
-	INT AllZeroMac = 0;
-	INT AllFFMac = 0;
+	INT Status;
+	unsigned char puMacAddr[6];
 
 	Status = BeceemNVMRead(Adapter,
 			(PUINT)&puMacAddr[0],
 			INIT_PARAMS_1_MACADDRESS_ADDRESS,
 			MAC_ADDRESS_SIZE);
 
-	if(Status != STATUS_SUCCESS)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Error in Reading the mac Addres with status :%d", Status);
-		return Status;
-	}
-
-	memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Modem MAC Addr :");
-    BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_PRINTK, 0, DBG_LVL_ALL,&Adapter->dev->dev_addr[0],MAC_ADDRESS_SIZE);
-	for(i=0;i<MAC_ADDRESS_SIZE;i++)
-	{
-
-		if(Adapter->dev->dev_addr[i] == 0x00)
-			AllZeroMac++;
-		if(Adapter->dev->dev_addr[i] == 0xFF)
-			AllFFMac++;
-
-	}
-	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\n");
-	if(AllZeroMac == MAC_ADDRESS_SIZE)
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all 00's");
-	if(AllFFMac == MAC_ADDRESS_SIZE)
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all FF's");
+	if(Status == STATUS_SUCCESS)
+		memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
 
 	return Status;
-
 }
 
 //-----------------------------------------------------------------------------
@@ -476,7 +340,7 @@
 		ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4);
 		if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes))
 		{
-			OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes);
+			memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes);
 
 			uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
 			uiIndex += (MAX_RW_SIZE - uiExtraBytes);
@@ -484,7 +348,7 @@
 		}
 		else
 		{
-			OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
+			memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
 			uiIndex += uiBytesRemaining;
 			uiOffset += uiBytesRemaining;
 			uiBytesRemaining = 0;
@@ -508,7 +372,7 @@
 			 * We read 4 Dwords of data */
 			if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4))
 			{
-				OsalMemMove(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
+				memcpy(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
 				uiOffset += MAX_RW_SIZE;
 				uiBytesRemaining -= MAX_RW_SIZE;
 				uiIndex += MAX_RW_SIZE;
@@ -523,7 +387,7 @@
 		{
 			if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
 			{
-				OsalMemMove(pcBuff+uiIndex,&uiData[0],4);
+				memcpy(pcBuff+uiIndex,&uiData[0],4);
 				uiOffset += 4;
 				uiBytesRemaining -= 4;
 				uiIndex +=4;
@@ -540,7 +404,7 @@
 			pCharBuff += uiIndex;
 			if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
 			{
-				OsalMemMove(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
+				memcpy(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
 				uiBytesRemaining = 0;
 			}
 			else
@@ -571,7 +435,7 @@
 //		<FAILURE>			- if failed.
 //-----------------------------------------------------------------------------
 
-INT BeceemFlashBulkRead(
+static INT BeceemFlashBulkRead(
 	PMINI_ADAPTER Adapter,
 	PUINT pBuffer,
 	UINT uiOffset,
@@ -653,16 +517,8 @@
 //
 //-----------------------------------------------------------------------------
 
-UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
+static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
 {
-#if 0
-	if(Adapter->bDDRInitDone)
-	{
-		return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT|FLASH_SIZE_ADDR);
-	}
-
-	return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT|FLASH_SIZE_ADDR);
-#endif
 	if(IsFlash2x(Adapter))
 		return 	(Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
 	else
@@ -684,7 +540,7 @@
 //
 //-----------------------------------------------------------------------------
 
-UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
+static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
 {
 	UINT uiData = 0;
 	UINT uiIndex = 0;
@@ -733,60 +589,6 @@
 	return 0;
 }
 
-#if 0
-/***********************************************************************************/
-//
-//  WriteBeceemEEPROM: Writes 4 byte data to EEPROM offset.
-//
-//                     uiEEPROMOffset - Offset to be written to.
-//                     uiData         - Data to be written.
-//
-/***********************************************************************************/
-
-INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData)
-{
-	INT Status = 0;
-	ULONG ulRdBk = 0;
-	ULONG ulRetryCount = 3;
-	UINT value;
-
-	if(uiEEPROMOffset > EEPROM_END)
-	{
-
-		return -1;
-	}
-
-	uiData = htonl(uiData);
-	while(ulRetryCount--)
-	{
-		value = 0x06000000;
-		wrmalt(Adapter, 0x0F003018,&value, sizeof(value));//flush the EEPROM FIFO.
-		wrmalt(Adapter, 0x0F00301C,&uiData, sizeof(uiData));
-		value = 0x3A000000 | uiEEPROMOffset;
-		wrmalt(Adapter, 0x0F003018,&value, sizeof(value));
-		__udelay(100000);
-		//read back and verify.
-		Status = ReadBeceemEEPROM(Adapter,uiEEPROMOffset,(UINT *)&ulRdBk);
-		if(Status == 0)
-		{
-			if(ulRdBk == uiData)
-			{
-				return Status;
-			}
-			else
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback does not match\n");
-			}
-		}
-		else
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback failed\n");
-		}
-	}
-
-	return 0;
-}
-#endif
 
 //-----------------------------------------------------------------------------
 // Procedure:	FlashSectorErase
@@ -973,7 +775,7 @@
 // need not write 0xFFFFFFFF because write requires an erase and erase will
 // make whole sector 0xFFFFFFFF.
 //
-	if (!OsalMemCompare(pData, uiErasePattern, MAX_RW_SIZE))
+	if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
 	{
 		return 0;
 	}
@@ -1138,7 +940,7 @@
 // need not write 0xFFFFFFFF because write requires an erase and erase will
 // make whole sector 0xFFFFFFFF.
 //
-	if (!OsalMemCompare(pData,uiErasePattern,MAX_RW_SIZE))
+	if (!memcmp(pData,uiErasePattern,MAX_RW_SIZE))
 	{
 		return 0;
 	}
@@ -1332,7 +1134,7 @@
 //
 //-----------------------------------------------------------------------------
 
-INT BeceemFlashBulkWrite(
+static INT BeceemFlashBulkWrite(
 	PMINI_ADAPTER Adapter,
 	PUINT pBuffer,
 	UINT uiOffset,
@@ -1353,15 +1155,6 @@
 	UINT uiTemp 				= 0;
 	UINT index 					= 0;
 	UINT uiPartOffset 			= 0;
-	#if 0
-	struct timeval tv1 = {0};
-	struct timeval tv2 = {0};
-
-	struct timeval tr = {0};
-	struct timeval te = {0};
-	struct timeval tw = {0};
-	struct timeval twv = {0};
-	#endif
 
 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
   Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
@@ -1377,12 +1170,9 @@
 	uiCurrSectOffsetAddr	= uiOffset & (Adapter->uiSectorSize - 1);
 	uiSectBoundary	  		= uiSectAlignAddr + Adapter->uiSectorSize;
 
-	//pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN');
-	pTempBuff = OsalMemAlloc(Adapter->uiSectorSize ,"!MVN");
+	pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
 	if(NULL == pTempBuff)
-	{
 		goto BeceemFlashBulkWrite_EXIT;
-	}
 //
 // check if the data to be written is overlapped accross sectors
 //
@@ -1399,7 +1189,6 @@
 			uiNumSectTobeRead++;
 		}
 	}
-	#if 1
 	//Check whether Requested sector is writable or not in case of flash2x write. But if  write call is
 	// for DSD calibration, allow it without checking of sector permission
 
@@ -1420,7 +1209,6 @@
 			 index = index + 1 ;
 		}
 	}
-	#endif
 	Adapter->SelectedChip = RESET_CHIP_SELECT;
 	while(uiNumSectTobeRead)
 	{
@@ -1448,13 +1236,13 @@
 		if(uiNumSectTobeRead > 1)
 		{
 
-			OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+			memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
 			pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
 			uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
 		}
 		else
 		{
-				OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
+				memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
 		}
 
 		if(IsFlash2x(Adapter))
@@ -1503,7 +1291,7 @@
 				}
 				else
 				{
-					if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
+					if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
 					{
 						if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
 						{
@@ -1541,10 +1329,8 @@
 	{
 		BcmRestoreBlockProtectStatus(Adapter,ulStatus);
 	}
-	if(pTempBuff)
-	{
-		OsalMemFree(pTempBuff,Adapter->uiSectorSize);
-	}
+	
+	kfree(pTempBuff);
 
 	Adapter->SelectedChip = RESET_CHIP_SELECT;
 	return Status;
@@ -1599,14 +1385,10 @@
 	uiCurrSectOffsetAddr	= uiOffset & (Adapter->uiSectorSize - 1);
 	uiSectBoundary			= uiSectAlignAddr + Adapter->uiSectorSize;
 
-
-
-//	pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN');
-	pTempBuff = OsalMemAlloc(Adapter->uiSectorSize,"!MVN");
+	pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
 	if(NULL == pTempBuff)
-	{
 		goto BeceemFlashBulkWriteStatus_EXIT;
-	}
+
 //
 // check if the data to be written is overlapped accross sectors
 //
@@ -1662,13 +1444,13 @@
 		if(uiNumSectTobeRead > 1)
 		{
 
-			OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+			memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
 			pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
 			uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
 		}
 		else
 		{
-			OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
+			memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
 		}
 
 		if(IsFlash2x(Adapter))
@@ -1698,25 +1480,10 @@
 		{
 			for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
 			{
-#if 0
-				if(0 == BeceemFlashBulkRead(Adapter,uiReadBk,uiOffsetFromSectStart+uiIndex + Adapter->ulFlashCalStart ,MAX_RW_SIZE))
-				{
-					for(uiReadIndex = 0;uiReadIndex < 4; uiReadIndex++)
-					{
-						if(*((PUINT)&pTempBuff[uiIndex+uiReadIndex*4]) != uiReadBk[uiReadIndex])
-						{
-							Status = -1;
-							goto BeceemFlashBulkWriteStatus_EXIT;
-
-						}
-					}
-
-				}
-#endif
 
 				if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
 				{
-					if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
+					if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
 					{
 						Status = STATUS_FAILURE;
 						goto BeceemFlashBulkWriteStatus_EXIT;
@@ -1747,10 +1514,8 @@
 	{
 		BcmRestoreBlockProtectStatus(Adapter,ulStatus);
 	}
-	if(pTempBuff)
-	{
-		OsalMemFree(pTempBuff,Adapter->uiSectorSize);
-	}
+
+	kfree(pTempBuff);
 	Adapter->SelectedChip = RESET_CHIP_SELECT;
 	return Status;
 
@@ -1771,7 +1536,7 @@
 
 INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter)
 {
-	PCHAR pBuff = OsalMemAlloc(BUFFER_4K,"3MVN");
+	PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
 	UINT uiEepromSize = 0;
 	UINT uiIndex = 0;
 	UINT uiBytesToCopy = 0;
@@ -1787,14 +1552,14 @@
 	if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4))
 	{
 
-		OsalMemFree(pBuff,BUFFER_4K);
+		kfree(pBuff);
 		return -1;
 	}
 
 	uiEepromSize >>= 16;
 	if(uiEepromSize > 1024*1024)
 	{
-		OsalMemFree(pBuff,BUFFER_4K);
+		kfree(pBuff);
 		return -1;
 	}
 
@@ -1820,7 +1585,7 @@
 	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value));
 	value = 0xbeadbead;
 	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value));
-	OsalMemFree(pBuff,MAX_RW_SIZE);
+	kfree(pBuff);
 
 	return Status;
 
@@ -1873,16 +1638,13 @@
 		return -1;
 	}
 
-	pBuff = OsalMemAlloc(uiEepromSize, 0);
-
+	pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
 	if ( pBuff == NULL )
-	{
 		return -1;
-	}
 
 	if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize))
 	{
-		OsalMemFree(pBuff, 0);
+		kfree(pBuff);
 		return -1;
 	}
 
@@ -1905,7 +1667,7 @@
 		uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
 	}
 
-	OsalMemFree(pBuff, 0);
+	kfree(pBuff);
 	return Status;
 
 }
@@ -1947,14 +1709,14 @@
 		{// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster.
 			BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
 
-			if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
+			if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
 			{
 				// re-write
 				BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE);
 				mdelay(3);
 				BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
 
-				if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
+				if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
 				{
 					return -1;
 				}
@@ -1986,7 +1748,7 @@
 		else
 		{ // Handle the reads less than 4 bytes...
 			uiData = 0;
-			OsalMemMove(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
+			memcpy(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
 			BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4);
 
 			if(memcmp(&uiData, &uiRdbk, uiNumBytes))
@@ -2186,7 +1948,7 @@
 
 		if(uiBytesToCopy >= (16 -uiExtraBytes))
 		{
-			OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes);
+			memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes);
 
 			if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
 					return STATUS_FAILURE;
@@ -2197,7 +1959,7 @@
 		}
 		else
 		{
-			OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy);
+			memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy);
 
 			if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
 					return STATUS_FAILURE;
@@ -2233,7 +1995,7 @@
 	// To program non 16byte aligned data, read 16byte and then update.
 	//
 			BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16);
-			OsalMemMove(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);
+			memcpy(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);
 
 
 			if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) )
@@ -2535,7 +2297,7 @@
 //
 //-----------------------------------------------------------------------------
 
-UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
+static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
 {
 	UINT uiSectorSize = 0;
 	UINT uiSectorSig = 0;
@@ -2642,20 +2404,8 @@
 
 INT BcmInitNVM(PMINI_ADAPTER ps_adapter)
 {
-#ifdef BCM_SHM_INTERFACE
-#ifdef FLASH_DIRECT_ACCESS
-	unsigned int data,data1,data2 = 1;
-	wrm(ps_adapter, PAD_SELECT_REGISTER, &data2, 4);
-	data1 = rdm(ps_adapter,SYS_CFG,&data,4);
-	data1 = rdm(ps_adapter,SYS_CFG,&data,4);
-	data2 = (data | 0x80 | 0x8000);
-	wrm(ps_adapter,SYS_CFG, &data2,4); // over-write as Flash boot mode
-#endif
-	ps_adapter->eNVMType = NVM_FLASH;
-#else
 	BcmValidateNvmType(ps_adapter);
 	BcmInitEEPROMQueues(ps_adapter);
-#endif
 
 	if(ps_adapter->eNVMType == NVM_AUTODETECT)
 	{
@@ -2684,7 +2434,7 @@
 */
 /***************************************************************************/
 
-INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
+static INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
 {
 	if(Adapter->eNVMType == NVM_EEPROM)
 	{
@@ -2708,7 +2458,7 @@
 // Returns:
 //		<VOID>
 //-----------------------------------------------------------------------------
-VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
+static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
 {
 
 	//
@@ -2775,7 +2525,7 @@
 	if(psAdapter->psFlash2xCSInfo == NULL)
 	{
 		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
-		bcm_kfree(psAdapter->psFlashCSInfo);
+		kfree(psAdapter->psFlashCSInfo);
 		return -ENOMEM;
 	}
 
@@ -2783,8 +2533,8 @@
 	if(psAdapter->psFlash2xVendorInfo == NULL)
 	{
 		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
-		bcm_kfree(psAdapter->psFlashCSInfo);
-		bcm_kfree(psAdapter->psFlash2xCSInfo);
+		kfree(psAdapter->psFlashCSInfo);
+		kfree(psAdapter->psFlash2xCSInfo);
 		return -ENOMEM;
 	}
 
@@ -2798,9 +2548,9 @@
 		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
 		return -EINVAL;
 	}
-	bcm_kfree(psAdapter->psFlashCSInfo);
-	bcm_kfree(psAdapter->psFlash2xCSInfo);
-	bcm_kfree(psAdapter->psFlash2xVendorInfo);
+	kfree(psAdapter->psFlashCSInfo);
+	kfree(psAdapter->psFlash2xCSInfo);
+	kfree(psAdapter->psFlash2xVendorInfo);
 	return STATUS_SUCCESS ;
 }
 
@@ -2954,7 +2704,7 @@
 	return STATUS_SUCCESS;
 }
 
-INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
+static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
 {
  	return ( Adapter->uiVendorExtnFlag &&
  		(Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
@@ -3052,7 +2802,7 @@
 //		<VOID>
 //-----------------------------------------------------------------------------
 
-INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
+static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
 {
 	//FLASH_CS_INFO sFlashCsInfo = {0};
 
@@ -3070,7 +2820,6 @@
 	memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
 	memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));
 
-#ifndef BCM_SHM_INTERFACE
 	if(!Adapter->bDDRInitDone)
 	{
 		{
@@ -3079,7 +2828,6 @@
 		}
 	}
 
-#endif
 
 	// Reading first 8 Bytes to get the Flash Layout
 	// MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
@@ -3147,9 +2895,7 @@
 			return STATUS_FAILURE;
 		}
 		ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
-#ifndef BCM_SHM_INTERFACE
 		BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
-#endif
 		if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
 		   (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
 		   (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
@@ -3181,21 +2927,10 @@
 	Concerns: what if CS sector size does not match with this sector size ???
 	what is the indication of AccessBitMap  in CS in flash 2.x ????
 	*/
-#ifndef BCM_SHM_INTERFACE
 	Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
-#endif
 
 	Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
 
-	#if 0
-	if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
-	{
-	//
-	// 1MB flash has been selected. we have to use 64K as sector size no matter what is kept in FLASH_CS.
-	//
-		Adapter->uiSectorSize = 0x10000;
-	}
-	#endif
 
 	return STATUS_SUCCESS ;
 }
@@ -3214,7 +2949,7 @@
 //
 //-----------------------------------------------------------------------------
 
-NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
+static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
 {
 	UINT uiData = 0;
 
@@ -3569,39 +3304,6 @@
 }
 
 /**
-*	ReadDSDHeader : Read the DSD map for the DSD Section val provided in Argument.
-*	@Adapter : Beceem Private Data Structure
-*	@psDSDHeader :Pointer of the buffer where header has to be read
-*	@dsd :value of the Dyanmic DSD like DSD0 of DSD1 or DSD2
-*
-*	Return Value:-
-*		if suceeds return STATUS_SUCCESS or negative error code.
-**/
-INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd)
-{
-	INT Status = STATUS_SUCCESS;
-
-	Status =BcmFlash2xBulkRead(Adapter,
-						    (PUINT)psDSDHeader,
-							dsd,
-							Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader,
-							sizeof(DSD_HEADER));
-	if(Status == STATUS_SUCCESS)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageMagicNumber :0X%x", ntohl(psDSDHeader->DSDImageMagicNumber));
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageSize :0X%x ",ntohl(psDSDHeader->DSDImageSize));
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageCRC :0X%x",ntohl(psDSDHeader->DSDImageCRC));
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImagePriority :0X%x",ntohl(psDSDHeader->DSDImagePriority));
-	}
-	else
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DSD Header read is failed with status :%d", Status);
-	}
-
-	return Status;
-}
-
-/**
 *	BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
 *	@Adapter :-Drivers private Data Structure
 *
@@ -3609,7 +3311,7 @@
 *		Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code
 *
 **/
-INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
+static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
 {
 	FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
 
@@ -3647,39 +3349,6 @@
 	return STATUS_SUCCESS;
 }
 
-/**
-*	ReadISOUnReservedBytes : Read the ISO map for the ISO Section val provided in Argument.
-*	@Adapter : Driver Private Data Structure
-*	@psISOHeader :Pointer of the location where header has to be read
-*	@IsoImage :value of the Dyanmic ISO like ISO_IMAGE1 of ISO_IMAGE2
-*
-*	Return Value:-
-*		if suceeds return STATUS_SUCCESS or negative error code.
-**/
-
-INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage)
-{
-	INT Status = STATUS_SUCCESS;
-
-	Status = BcmFlash2xBulkRead(Adapter,
-					    (PUINT)psISOHeader,
-						IsoImage,
-						0,
-						sizeof(ISO_HEADER));
-
-	if(Status == STATUS_SUCCESS)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageMagicNumber :0X%x", ntohl(psISOHeader->ISOImageMagicNumber));
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageSize :0X%x ",ntohl(psISOHeader->ISOImageSize));
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageCRC :0X%x",ntohl(psISOHeader->ISOImageCRC));
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImagePriority :0X%x",ntohl(psISOHeader->ISOImagePriority));
-	}
-	else
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ISO Header Read failed");
-	}
-	return Status;
-}
 
 /**
 *	BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
@@ -3691,7 +3360,7 @@
 *
 **/
 
-INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
+static INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
 {
 
 	INT HighestPriISO = 0 ;
@@ -4588,7 +4257,7 @@
 
 	}
 
-	bcm_kfree(Buff);
+	kfree(Buff);
 
 	return Status;
 }
@@ -4789,7 +4458,7 @@
 	Success :- Base Address of the Flash
 **/
 
-INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
+static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
 {
 
 	UINT uiBaseAddr = 0;
@@ -4866,20 +4535,6 @@
 		return  -EINVAL;
 	}
 
-	#if 0
-	else
-	{
-		if((SrcSection == VSA0) || (SrcSection == VSA1) || (SrcSection == VSA2))
-		{
-			if((DstSection != VSA0) && (DstSection != VSA1) && (DstSection != VSA2))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Source and Destion secton is not of same type");
-				return -EINVAL;
-			}
-		}
-
-	}
-	#endif
 	//if offset zero means have to copy complete secton
 
 	if(numOfBytes == 0)
@@ -4954,7 +4609,7 @@
 				BytesToBeCopied = numOfBytes;
 		}
 	}while(numOfBytes > 0) ;
-	bcm_kfree(pBuff);
+	kfree(pBuff);
 	Adapter->bHeaderChangeAllowed = FALSE ;
 	return Status;
 }
@@ -4979,14 +4634,6 @@
 	UINT uiSectAlignAddr = 0;
 	UINT sig = 0;
 
-	#if 0
-	//if Chenges in Header is allowed, Return back
-	if(Adapter->bHeaderChangeAllowed == TRUE)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Header Change is allowed");
-		return STATUS_SUCCESS ;
-	}
-	#endif
 	//making the offset sector alligned
 	uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
 
@@ -5024,7 +4671,7 @@
 		//Replace Buffer content with Header
 		memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);
 
-		bcm_kfree(pTempBuff);
+		kfree(pTempBuff);
 	}
 	if(bHasHeader && Adapter->bSigCorrupted)
 	{
@@ -5044,29 +4691,7 @@
 
 	return STATUS_SUCCESS ;
 }
-INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset)
-{
-	UINT GPIOConfig = 0 ;
 
-
-	if(Adapter->bFlashRawRead == FALSE)
-	{
-		//Applicable for Flash2.x
-		if(IsFlash2x(Adapter) == FALSE)
-			return STATUS_SUCCESS;
-	}
-
-	if(offset/FLASH_PART_SIZE)
-	{
-		//bit[14..12] -> will select make Active CS1, CS2 or CS3
-		// Select CS1, CS2 and CS3 (CS0 is dedicated pin)
-		rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
-		GPIOConfig |= (7 << 12);
-		wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
-	}
-
-	return STATUS_SUCCESS ;
-}
 /**
 BcmDoChipSelect : This will selcet the appropriate chip for writing.
 @Adapater :- Bcm Driver Private Data Structure
@@ -5074,7 +4699,7 @@
 OutPut:-
 	Select the Appropriate chip and retrn status Sucess
 **/
-INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
+static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
 {
 	UINT FlashConfig = 0;
 	INT ChipNum = 0;
@@ -5365,39 +4990,6 @@
 	return Status;
 }
 
-#if 0
-UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType)
-{
-
-	UINT numOfWRSubSec = 0;
-	switch(secType)
-	{
-		case ISO :
-			if(IsSectionWritable(Adapter,ISO_IMAGE1))
-				numOfWRSubSec = numOfWRSubSec + 1;
-			if(IsSectionWritable(Adapter,ISO_IMAGE2))
-				numOfWRSubSec = numOfWRSubSec + 1;
-			break;
-
-		case DSD :
-			if(IsSectionWritable(Adapter,DSD2))
-				numOfWRSubSec = numOfWRSubSec + 1;
-			if(IsSectionWritable(Adapter,DSD1))
-				numOfWRSubSec = numOfWRSubSec + 1;
-			if(IsSectionWritable(Adapter,DSD0))
-				numOfWRSubSec = numOfWRSubSec + 1;
-			break ;
-
-		case VSA :
-				//for VSA Add code Here
-		 default :
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Invalid secton<%d> is passed", secType);\
-			numOfWRSubSec = 0;
-
-	}
-	return numOfWRSubSec;
-}
-#endif
 BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
 {
 
@@ -5479,7 +5071,7 @@
 		return Status ;
 }
 
-INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
 {
 
 	PUCHAR pBuff = NULL;
@@ -5543,16 +5135,16 @@
 	else
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
-		bcm_kfree(pBuff);
+		kfree(pBuff);
 		return STATUS_FAILURE;
 	}
 
-	bcm_kfree(pBuff);
+	kfree(pBuff);
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
 	return STATUS_SUCCESS ;
 }
 
-INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
 {
 
 	PUCHAR pBuff = NULL;
@@ -5593,14 +5185,14 @@
 	else
 	{
 		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
-		bcm_kfree(pBuff);
+		kfree(pBuff);
 		return STATUS_FAILURE;
 	}
 
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
 	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
 
-	bcm_kfree(pBuff);
+	kfree(pBuff);
 	return STATUS_SUCCESS ;
 }
 
diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h
index 6ec6ca8..651b5a4 100644
--- a/drivers/staging/bcm/nvm.h
+++ b/drivers/staging/bcm/nvm.h
@@ -323,15 +323,6 @@
 
 
 
-#ifdef BCM_SHM_INTERFACE
-
-#define FLASH_ADDR_MASK                          0x1F000000
-extern int bcmflash_raw_read(unsigned int flash_id, unsigned int offset, unsigned char *inbuf, unsigned int len);
-extern int bcmflash_raw_write(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len);
-extern int bcmflash_raw_writenoerase(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len);
-
-
-#endif
 
 #define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT   0x1C000000
 #define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT  0x1F000000
@@ -414,76 +405,5 @@
 
 #define FIELD_OFFSET_IN_HEADER(HeaderPointer,Field) ((PUCHAR)&((HeaderPointer)(NULL))->Field - (PUCHAR)(NULL))
 
-#if 0
-INT BeceemEEPROMBulkRead(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes);
-
-
-INT BeceemFlashBulkRead(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes);
-
-UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
-
-UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
-
-UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter);
-
-
-
-INT BeceemFlashBulkWrite(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes,
-	BOOLEAN bVerify);
-
-INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
-
-INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
-
-
-INT BeceemEEPROMBulkWrite(
-	PMINI_ADAPTER Adapter,
-	PUCHAR pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes,
-	BOOLEAN bVerify);
-
-
-INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
-
-NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
-
-INT BeceemNVMRead(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes);
-
-INT BeceemNVMWrite(
-	PMINI_ADAPTER Adapter,
-	PUINT pBuffer,
-	UINT uiOffset,
-	UINT uiNumBytes,
-	BOOLEAN bVerify);
-
-INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter);
-
-INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
-
-INT BcmInitNVM(PMINI_ADAPTER Adapter);
-
-VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
-
-VOID BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
-
-#endif
-
 #endif
 
diff --git a/drivers/staging/bcm/osal_misc.h b/drivers/staging/bcm/osal_misc.h
deleted file mode 100644
index ff4adde..0000000
--- a/drivers/staging/bcm/osal_misc.h
+++ /dev/null
@@ -1,49 +0,0 @@
-	/*++
-
-	Copyright (c) Beceem Communications Inc.
-
-	Module Name:
-		OSAL_Misc.h
-
-	Abstract:
-		Provides the OS Abstracted macros to access:
-			Linked Lists
-			Dispatcher Objects(Events,Semaphores,Spin Locks and the like)
-			Files
-
-
-	Revision History:
-		Who         When        What
-		--------    --------    ----------------------------------------------
-		Name		Date		Created/reviewed/modified
-		Rajeev		24/1/08		Created
-	Notes:
-
-	--*/
-#ifndef _OSAL_MISC_H_
-#define _OSAL_MISC_H_
-//OSAL Macros
-//OSAL Primitives
-typedef PUCHAR  POSAL_NW_PACKET  ;		//Nw packets
-
-
-#define OsalMemAlloc(n,t) kmalloc(n,GFP_KERNEL)
-
-#define OsalMemFree(x,n) bcm_kfree(x)
-
-#define OsalMemMove(dest, src, len)		\
-{										\
-			memcpy(dest,src, len);		\
-}
-
-#define OsalZeroMemory(pDest, Len)		\
-{										\
-			memset(pDest,0,Len);		\
-}
-
-//#define OsalMemSet(pSrc,Char,Len) memset(pSrc,Char,Len)
-
-bool OsalMemCompare(void *dest, void *src, UINT len);
-
-#endif
-
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
index 4c613da..6738983 100644
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
@@ -16,13 +16,14 @@
 /* ****************** BCMSDH Interface Functions *************************** */
 
 #include <linux/types.h>
+#include <linux/netdevice.h>
 #include <bcmdefs.h>
 #include <bcmdevs.h>
 #include <bcmendian.h>
+#include <osl.h>
 #include <bcmutils.h>
 #include <hndsoc.h>
 #include <siutils.h>
-#include <osl.h>
 
 #include <bcmsdh.h>		/* BRCM API for SDIO
 			 clients (such as wl, dhd) */
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
index 9028cd0..be33696 100644
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
@@ -20,8 +20,7 @@
 
 #define __UNDEF_NO_VERSION__
 
-#include <linuxver.h>
-
+#include <linux/netdevice.h>
 #include <linux/pci.h>
 #include <linux/completion.h>
 
@@ -189,7 +188,7 @@
 	}
 #endif				/* defined(OOB_INTR_ONLY) */
 	/* allocate SDIO Host Controller state info */
-	osh = osl_attach(dev, PCI_BUS, false);
+	osh = osl_attach(dev, PCI_BUS);
 	if (!osh) {
 		SDLX_MSG(("%s: osl_attach failed\n", __func__));
 		goto err;
@@ -385,7 +384,7 @@
 
 		SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n",
 			  __func__));
-		osh = osl_attach(pdev, PCI_BUS, false);
+		osh = osl_attach(pdev, PCI_BUS);
 		if (!osh) {
 			SDLX_MSG(("%s: osl_attach failed\n", __func__));
 			goto err;
@@ -420,7 +419,7 @@
 	 */
 
 	/* allocate SDIO Host Controller state info */
-	osh = osl_attach(pdev, PCI_BUS, false);
+	osh = osl_attach(pdev, PCI_BUS);
 	if (!osh) {
 		SDLX_MSG(("%s: osl_attach failed\n", __func__));
 		goto err;
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index f6c9c45..039f114 100644
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -14,11 +14,12 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <linux/types.h>
+#include <linux/netdevice.h>
 #include <bcmdefs.h>
 #include <bcmdevs.h>
 #include <bcmendian.h>
-#include <bcmutils.h>
 #include <osl.h>
+#include <bcmutils.h>
 #include <sdio.h>		/* SDIO Device and Protocol Specs */
 #include <sdioh.h>		/* SDIO Host Controller Specification */
 #include <bcmsdbus.h>		/* bcmsdh to/from specific controller APIs */
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
index ae7b566..14f73fd 100644
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
@@ -15,7 +15,9 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>	/* request_irq() */
+#include <linux/netdevice.h>
 #include <bcmdefs.h>
+#include <osl.h>
 #include <bcmutils.h>
 #include <sdio.h>		/* SDIO Specs */
 #include <bcmsdbus.h>		/* bcmsdh to/from specific controller APIs */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
index bcbaac9..0d14f6c 100644
--- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
@@ -15,6 +15,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/netdevice.h>
 #include <bcmdefs.h>
 #include <osl.h>
 
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
index 703188f..f7ffea6 100644
--- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <bcmdefs.h>
+#include <linux/netdevice.h>
 #include <osl.h>
 #include <bcmutils.h>
 #include <bcmendian.h>
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
index f647034..bb3c7b8 100644
--- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
@@ -14,7 +14,7 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <linuxver.h>
+#include <linux/netdevice.h>
 #include <osl.h>
 #include <bcmutils.h>
 
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
index 9335f02..48f0e6c 100644
--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
@@ -32,7 +32,6 @@
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <bcmdefs.h>
-#include <linuxver.h>
 #include <osl.h>
 #include <bcmutils.h>
 #include <bcmendian.h>
@@ -1190,7 +1189,7 @@
 		/* Process special event packets and then discard them */
 		if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM)
 			dhd_wl_host_event(dhd, &ifidx,
-					  skb->mac_header,
+					  skb_mac_header(skb),
 					  &event, &data);
 
 		ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
@@ -1621,6 +1620,51 @@
 	return 0;
 }
 
+static s16 linuxbcmerrormap[] = { 0,	/* 0 */
+	-EINVAL,		/* BCME_ERROR */
+	-EINVAL,		/* BCME_BADARG */
+	-EINVAL,		/* BCME_BADOPTION */
+	-EINVAL,		/* BCME_NOTUP */
+	-EINVAL,		/* BCME_NOTDOWN */
+	-EINVAL,		/* BCME_NOTAP */
+	-EINVAL,		/* BCME_NOTSTA */
+	-EINVAL,		/* BCME_BADKEYIDX */
+	-EINVAL,		/* BCME_RADIOOFF */
+	-EINVAL,		/* BCME_NOTBANDLOCKED */
+	-EINVAL,		/* BCME_NOCLK */
+	-EINVAL,		/* BCME_BADRATESET */
+	-EINVAL,		/* BCME_BADBAND */
+	-E2BIG,			/* BCME_BUFTOOSHORT */
+	-E2BIG,			/* BCME_BUFTOOLONG */
+	-EBUSY,			/* BCME_BUSY */
+	-EINVAL,		/* BCME_NOTASSOCIATED */
+	-EINVAL,		/* BCME_BADSSIDLEN */
+	-EINVAL,		/* BCME_OUTOFRANGECHAN */
+	-EINVAL,		/* BCME_BADCHAN */
+	-EFAULT,		/* BCME_BADADDR */
+	-ENOMEM,		/* BCME_NORESOURCE */
+	-EOPNOTSUPP,		/* BCME_UNSUPPORTED */
+	-EMSGSIZE,		/* BCME_BADLENGTH */
+	-EINVAL,		/* BCME_NOTREADY */
+	-EPERM,			/* BCME_NOTPERMITTED */
+	-ENOMEM,		/* BCME_NOMEM */
+	-EINVAL,		/* BCME_ASSOCIATED */
+	-ERANGE,		/* BCME_RANGE */
+	-EINVAL,		/* BCME_NOTFOUND */
+	-EINVAL,		/* BCME_WME_NOT_ENABLED */
+	-EINVAL,		/* BCME_TSPEC_NOTFOUND */
+	-EINVAL,		/* BCME_ACM_NOTSUPPORTED */
+	-EINVAL,		/* BCME_NOT_WME_ASSOCIATION */
+	-EIO,			/* BCME_SDIO_ERROR */
+	-ENODEV,		/* BCME_DONGLE_DOWN */
+	-EINVAL,		/* BCME_VERSION */
+	-EIO,			/* BCME_TXFAIL */
+	-EIO,			/* BCME_RXFAIL */
+	-EINVAL,		/* BCME_NODEVICE */
+	-EINVAL,		/* BCME_NMODE_DISABLED */
+	-ENODATA,		/* BCME_NONRESIDENT */
+};
+
 static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
 {
 	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
@@ -1742,7 +1786,12 @@
 	if (buf)
 		kfree(buf);
 
-	return OSL_ERROR(bcmerror);
+	if (bcmerror > 0)
+		bcmerror = 0;
+	else if (bcmerror < BCME_LAST)
+		bcmerror = BCME_ERROR;
+
+	return linuxbcmerrormap[-bcmerror];
 }
 
 static int dhd_stop(struct net_device *net)
@@ -1816,7 +1865,7 @@
 
 osl_t *dhd_osl_attach(void *pdev, uint bustype)
 {
-	return osl_attach(pdev, bustype, true);
+	return osl_attach(pdev, bustype);
 }
 
 void dhd_osl_detach(osl_t *osh)
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
index bf8df98..c66f1c2 100644
--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linuxver.h>
 
 int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
 {
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
index b2281d9..66884d4 100644
--- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
@@ -16,6 +16,7 @@
 
 #include <linux/types.h>
 #include <bcmdefs.h>
+#include <linux/netdevice.h>
 #include <osl.h>
 #include <bcmsdh.h>
 
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
index ea08252..b907376 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
@@ -16,7 +16,6 @@
 
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
-#include <linuxver.h>
 #include <osl.h>
 
 #include <bcmutils.h>
@@ -705,7 +704,7 @@
 
 	if (ssid && ssid->SSID_len)
 		params_size += sizeof(struct wlc_ssid);
-	params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
+	params = kzalloc(params_size, GFP_KERNEL);
 	if (unlikely(!params))
 		return -ENOMEM;
 	memset(params, 0, params_size);
@@ -2794,53 +2793,52 @@
 
 static s32 wl_init_priv_mem(struct wl_priv *wl)
 {
-	wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
+	wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
 	if (unlikely(!wl->scan_results)) {
 		WL_ERR(("Scan results alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
+	wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
 	if (unlikely(!wl->conf)) {
 		WL_ERR(("wl_conf alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
+	wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
 	if (unlikely(!wl->profile)) {
 		WL_ERR(("wl_profile alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+	wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
 	if (unlikely(!wl->bss_info)) {
 		WL_ERR(("Bss information alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->scan_req_int =
-	    (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
+	wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
 	if (unlikely(!wl->scan_req_int)) {
 		WL_ERR(("Scan req alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+	wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
 	if (unlikely(!wl->ioctl_buf)) {
 		WL_ERR(("Ioctl buf alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+	wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
 	if (unlikely(!wl->extra_buf)) {
 		WL_ERR(("Extra buf alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
+	wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
 	if (unlikely(!wl->iscan)) {
 		WL_ERR(("Iscan buf alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
+	wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
 	if (unlikely(!wl->fw)) {
 		WL_ERR(("fw object alloc failed\n"));
 		goto init_priv_mem_out;
 	}
-	wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
+	wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
 	if (unlikely(!wl->pmk_list)) {
 		WL_ERR(("pmk list alloc failed\n"));
 		goto init_priv_mem_out;
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c
index 979a494..d583b9d 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c
+++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c
@@ -16,7 +16,7 @@
 
 #include <linux/kthread.h>
 #include <bcmdefs.h>
-#include <linuxver.h>
+#include <linux/netdevice.h>
 #include <osl.h>
 #include <wlioctl.h>
 
@@ -3690,8 +3690,7 @@
 		return -ENOMEM;
 	memset(iscan, 0, sizeof(iscan_info_t));
 
-	iscan->iscan_ex_params_p =
-	    (wl_iscan_params_t *) kmalloc(params_size, GFP_KERNEL);
+	iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL);
 	if (!iscan->iscan_ex_params_p)
 		return -ENOMEM;
 	iscan->iscan_ex_param_size = params_size;
@@ -3723,9 +3722,7 @@
 	priv_dev = dev;
 	MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub);
 #endif
-	g_scan = NULL;
-
-	g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL);
+	g_scan = kmalloc(G_SCAN_RESULTS, GFP_KERNEL);
 	if (!g_scan)
 		return -ENOMEM;
 
diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h
index dc52e9db..ae6a65a 100644
--- a/drivers/staging/brcm80211/include/bcmdefs.h
+++ b/drivers/staging/brcm80211/include/bcmdefs.h
@@ -42,9 +42,6 @@
 #define BCMFASTPATH
 #endif
 
-/* Put some library data/code into ROM to reduce RAM requirements */
-#define BCMROMFN(_fn)		_fn
-
 /* Bus types */
 #define	SI_BUS			0	/* SOC Interconnect */
 #define	PCI_BUS			1	/* PCI target */
@@ -54,35 +51,10 @@
 #define SPI_BUS			6	/* gSPI target */
 #define RPC_BUS			7	/* RPC target */
 
-/* Allows size optimization for single-bus image */
-#ifdef BCMBUSTYPE
-#define BUSTYPE(bus) 	(BCMBUSTYPE)
-#else
 #define BUSTYPE(bus) 	(bus)
-#endif
-
-/* Allows size optimization for single-backplane image */
-#ifdef BCMCHIPTYPE
-#define CHIPTYPE(bus) 	(BCMCHIPTYPE)
-#else
 #define CHIPTYPE(bus) 	(bus)
-#endif
-
-/* Allows size optimization for SPROM support */
-#define SPROMBUS	(PCI_BUS)
-
-/* Allows size optimization for single-chip image */
-#ifdef BCMCHIPID
-#define CHIPID(chip)	(BCMCHIPID)
-#else
 #define CHIPID(chip)	(chip)
-#endif
-
-#ifdef BCMCHIPREV
-#define CHIPREV(rev)	(BCMCHIPREV)
-#else
 #define CHIPREV(rev)	(rev)
-#endif
 
 /* Defines for DMA Address Width - Shared between OSL and HNDDMA */
 #define DMADDR_MASK_32 0x0	/* Address mask for 32-bits */
@@ -146,31 +118,11 @@
 
 #define BCMEXTRAHDROOM 172
 
-/* Headroom required for dongle-to-host communication.  Packets allocated
- * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
- * leave this much room in front for low-level message headers which may
- * be needed to get across the dongle bus to the host.  (These messages
- * don't go over the network, so room for the full WL header above would
- * be a waste.).
-*/
-#define BCMDONGLEHDRSZ 12
-#define BCMDONGLEPADSZ 16
-
-#define BCMDONGLEOVERHEAD	(BCMDONGLEHDRSZ + BCMDONGLEPADSZ)
-
 #ifdef BCMDBG
-
-#define BCMDBG_ERR
-
 #ifndef BCMDBG_ASSERT
 #define BCMDBG_ASSERT
-#endif				/* BCMDBG_ASSERT */
-
-#endif				/* BCMDBG */
-
-#if defined(BCMDBG_ASSERT)
-#define BCMASSERT_SUPPORT
-#endif
+#endif	/* BCMDBG_ASSERT */
+#endif	/* BCMDBG */
 
 /* Macros for doing definition and get/set of bitfields
  * Usage example, e.g. a three-bit field (bits 4-6):
@@ -190,10 +142,6 @@
 		(((val) & (~(field ## _M << field ## _S))) | \
 		 ((unsigned)(bits) << field ## _S))
 
-/* define BCMSMALL to remove misc features for memory-constrained environments */
-#define	BCMSPACE
-#define bcmspace	true	/* if (bcmspace) code is retained */
-
 /* Max. nvram variable table size */
 #define	MAXSZ_NVRAM_VARS	4096
 
diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h
index b533159..7f1d334 100644
--- a/drivers/staging/brcm80211/include/bcmutils.h
+++ b/drivers/staging/brcm80211/include/bcmutils.h
@@ -30,7 +30,6 @@
 	};
 
 /* ** driver-only section ** */
-#include <osl.h>
 
 #define GPIO_PIN_NOTDEFINED 	0x20	/* Pin not defined */
 
diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h
index c07548c..be2d497 100644
--- a/drivers/staging/brcm80211/include/d11.h
+++ b/drivers/staging/brcm80211/include/d11.h
@@ -17,13 +17,6 @@
 #ifndef	_D11_H
 #define	_D11_H
 
-#include <bcmdefs.h>
-#include <bcmdevs.h>
-#include <hndsoc.h>
-#include <sbhndpio.h>
-#include <sbhnddma.h>
-#include <proto/802.11.h>
-
 /* This marks the start of a packed structure section. */
 #include <packed_section_start.h>
 
diff --git a/drivers/staging/brcm80211/include/epivers.h b/drivers/staging/brcm80211/include/epivers.h
deleted file mode 100644
index 2e6b519..0000000
--- a/drivers/staging/brcm80211/include/epivers.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _epivers_h_
-#define _epivers_h_
-
-#define	EPI_MAJOR_VERSION	5
-
-#define	EPI_MINOR_VERSION	75
-
-#define	EPI_RC_NUMBER		11
-
-#define	EPI_INCREMENTAL_NUMBER	0
-
-#define EPI_BUILD_NUMBER	1
-
-#define	EPI_VERSION		{ 5, 75, 11, 0 }
-
-#ifdef BCMSDIO
-/* EPI_VERSION_NUM must match FW version */
-#define	EPI_VERSION_NUM		0x054b0c00
-#else
-#define	EPI_VERSION_NUM		0x054b0b00
-#endif
-
-#define EPI_VERSION_DEV		5.75.11
-
-/* Driver Version String, ASCII, 32 chars max */
-#define	EPI_VERSION_STR		"5.75.11"
-
-#endif				/* _epivers_h_ */
diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h
index c9c860b..586e652 100644
--- a/drivers/staging/brcm80211/include/linux_osl.h
+++ b/drivers/staging/brcm80211/include/linux_osl.h
@@ -18,13 +18,7 @@
 #define _linux_osl_h_
 
 
-/* Linux Kernel: File Operations: start */
-extern void *osl_os_open_image(char *filename);
-extern int osl_os_get_image_block(char *buf, int len, void *image);
-extern void osl_os_close_image(void *image);
-/* Linux Kernel: File Operations: end */
-
-extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
+extern osl_t *osl_attach(void *pdev, uint bustype);
 extern void osl_detach(osl_t *osh);
 
 extern u32 g_assert_type;
@@ -62,7 +56,6 @@
 
 /* Pkttag flag should be part of public information */
 typedef struct {
-	bool pkttag;
 	uint pktalloced;	/* Number of allocated packet buffers */
 	bool mmbus;		/* Bus supports memory-mapped register accesses */
 	pktfree_cb_fn_t tx_fn;	/* Callback function for PKTFREE */
@@ -91,8 +84,6 @@
 
 #define BUS_SWAP32(v)		(v)
 
-#define	DMA_CONSISTENT_ALIGN	osl_dma_consistent_align()
-extern uint osl_dma_consistent_align(void);
 extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align,
 				      uint *tot, unsigned long *pap);
 
@@ -142,9 +133,6 @@
 #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
 #endif
 
-#define OSL_ERROR(bcmerror)	osl_error(bcmerror)
-extern int osl_error(int bcmerror);
-
 /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
 #define	PKTBUFSZ	2048	/* largest reasonable packet buffer, driver uses for ethernet MTU */
 
@@ -271,22 +259,6 @@
 #define OSL_CACHED(va)		((void *)va)
 #endif				/* mips */
 
-#if defined(mips)
-#define	OSL_GETCYCLES(x)	((x) = read_c0_count() * 2)
-#elif defined(__i386__)
-#define	OSL_GETCYCLES(x)	rdtscl((x))
-#else
-#define OSL_GETCYCLES(x)	((x) = 0)
-#endif				/* defined(mips) */
-
-/* dereference an address that may cause a bus exception */
-#ifdef mips
-#define	BUSPROBE(val, addr)	get_dbe((val), (addr))
-#include <asm/paccess.h>
-#else
-#define	BUSPROBE(val, addr)	({ (val) = R_REG(NULL, (addr)); 0; })
-#endif				/* mips */
-
 /* map/unmap physical to virtual I/O */
 #if !defined(CONFIG_MMC_MSM7X00A)
 #define	REG_MAP(pa, size)	ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
@@ -299,10 +271,6 @@
 #define	W_SM(r, v)		(*(r) = (v))
 #define	BZERO_SM(r, len)	memset((r), '\0', (len))
 
-#ifdef BRCM_FULLMAC
-#include <linuxver.h>		/* use current 2.4.x calling conventions */
-#endif
-
 /* packet primitives */
 #define	PKTGET(osh, len, send)		osl_pktget((osh), (len))
 #define	PKTFREE(osh, skb, send)		osl_pktfree((osh), (skb), (send))
@@ -316,7 +284,6 @@
 #define	PKTSETLEN(skb, len)	__skb_trim((struct sk_buff *)(skb), (len))
 #define	PKTPUSH(skb, bytes)	skb_push((struct sk_buff *)(skb), (bytes))
 #define	PKTPULL(skb, bytes)	skb_pull((struct sk_buff *)(skb), (bytes))
-#define	PKTTAG(skb)		((void *)(((struct sk_buff *)(skb))->cb))
 #define PKTALLOCED(osh)		(((osl_pubinfo_t *)(osh))->pktalloced)
 #define PKTSETPOOL(osh, skb, x, y)	do {} while (0)
 #define PKTPOOL(osh, skb)		false
@@ -332,9 +299,6 @@
 {
 	struct sk_buff *nskb;
 
-	if (osh->pkttag)
-		bzero((void *)skb->cb, OSL_PKTTAG_SZ);
-
 	for (nskb = skb; nskb; nskb = nskb->next)
 		osh->pktalloced++;
 
@@ -348,9 +312,6 @@
 {
 	struct sk_buff *nskb;
 
-	if (osh->pkttag)
-		bzero(((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ);
-
 	for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next)
 		osh->pktalloced--;
 
diff --git a/drivers/staging/brcm80211/include/linuxver.h b/drivers/staging/brcm80211/include/linuxver.h
deleted file mode 100644
index dc72141..0000000
--- a/drivers/staging/brcm80211/include/linuxver.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _linuxver_h_
-#define _linuxver_h_
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/ieee80211.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-
-#undef IP_TOS
-#include <asm/io.h>
-
-#endif				/* _linuxver_h_ */
diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h
index c0ebb3d..bcb56aa 100644
--- a/drivers/staging/brcm80211/include/osl.h
+++ b/drivers/staging/brcm80211/include/osl.h
@@ -21,8 +21,6 @@
 typedef struct osl_info osl_t;
 typedef struct osl_dmainfo osldma_t;
 
-#define OSL_PKTTAG_SZ	32	/* Size of PktTag */
-
 /* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */
 typedef void (*pktfree_cb_fn_t) (void *ctx, void *pkt, unsigned int status);
 
diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h
index 96866fb..45e02e5 100644
--- a/drivers/staging/brcm80211/include/wlioctl.h
+++ b/drivers/staging/brcm80211/include/wlioctl.h
@@ -33,82 +33,9 @@
 #define BWL_DEFAULT_PACKING
 #include <packed_section_start.h>
 
-/* Legacy structure to help keep backward compatible wl tool and tray app */
-
-#define	LEGACY_WL_BSS_INFO_VERSION	107	/* older version of wl_bss_info struct */
-
-typedef struct wl_bss_info_107 {
-	u32 version;		/* version field */
-	u32 length;		/* byte length of data in this record,
-				 * starting at version and including IEs
-				 */
-	struct ether_addr BSSID;
-	u16 beacon_period;	/* units are Kusec */
-	u16 capability;	/* Capability information */
-	u8 SSID_len;
-	u8 SSID[32];
-	struct {
-		uint count;	/* # rates in this set */
-		u8 rates[16];	/* rates in 500kbps units w/hi bit set if basic */
-	} rateset;		/* supported rates */
-	u8 channel;		/* Channel no. */
-	u16 atim_window;	/* units are Kusec */
-	u8 dtim_period;	/* DTIM period */
-	s16 RSSI;		/* receive signal strength (in dBm) */
-	s8 phy_noise;		/* noise (in dBm) */
-	u32 ie_length;	/* byte length of Information Elements */
-	/* variable length Information Elements */
-} wl_bss_info_107_t;
-
-/*
- * Per-BSS information structure.
- */
-
-#define	LEGACY2_WL_BSS_INFO_VERSION	108	/* old version of wl_bss_info struct */
-
-/* BSS info structure
- * Applications MUST CHECK ie_offset field and length field to access IEs and
- * next bss_info structure in a vector (in wl_scan_results_t)
- */
-typedef struct wl_bss_info_108 {
-	u32 version;		/* version field */
-	u32 length;		/* byte length of data in this record,
-				 * starting at version and including IEs
-				 */
-	struct ether_addr BSSID;
-	u16 beacon_period;	/* units are Kusec */
-	u16 capability;	/* Capability information */
-	u8 SSID_len;
-	u8 SSID[32];
-	struct {
-		uint count;	/* # rates in this set */
-		u8 rates[16];	/* rates in 500kbps units w/hi bit set if basic */
-	} rateset;		/* supported rates */
-	chanspec_t chanspec;	/* chanspec for bss */
-	u16 atim_window;	/* units are Kusec */
-	u8 dtim_period;	/* DTIM period */
-	s16 RSSI;		/* receive signal strength (in dBm) */
-	s8 phy_noise;		/* noise (in dBm) */
-
-	u8 n_cap;		/* BSS is 802.11N Capable */
-	u32 nbss_cap;	/* 802.11N BSS Capabilities (based on HT_CAP_*) */
-	u8 ctl_ch;		/* 802.11N BSS control channel number */
-	u32 reserved32[1];	/* Reserved for expansion of BSS properties */
-	u8 flags;		/* flags */
-	u8 reserved[3];	/* Reserved for expansion of BSS properties */
-	u8 basic_mcs[MCSSET_LEN];	/* 802.11N BSS required MCS set */
-
-	u16 ie_offset;	/* offset at which IEs start, from beginning */
-	u32 ie_length;	/* byte length of Information Elements */
-	/* Add new fields here */
-	/* variable length Information Elements */
-} wl_bss_info_108_t;
-
 #ifdef BRCM_FULLMAC
+
 #define	WL_BSS_INFO_VERSION	108	/* current ver of wl_bss_info struct */
-#else
-#define	WL_BSS_INFO_VERSION	109	/* current ver of wl_bss_info struct */
-#endif
 
 /* BSS info structure
  * Applications MUST CHECK ie_offset field and length field to access IEs and
@@ -148,12 +75,14 @@
 	/* Add new fields here */
 	/* variable length Information Elements */
 } wl_bss_info_t;
+#endif /* BRCM_FULLMAC */
 
 typedef struct wlc_ssid {
 	u32 SSID_len;
 	unsigned char SSID[32];
 } wlc_ssid_t;
 
+#ifdef BRCM_FULLMAC
 typedef struct chan_scandata {
 	u8 txpower;
 	u8 pad;
@@ -308,6 +237,7 @@
 	struct ether_addr bssid;
 	struct ether_addr mac;
 } wl_probe_params_t;
+#endif /* BRCM_FULLMAC */
 
 #define WL_NUMRATES		16	/* max # of rates in a rateset */
 typedef struct wl_rateset {
@@ -315,6 +245,7 @@
 	u8 rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
 } wl_rateset_t;
 
+#ifdef BRCM_FULLMAC
 typedef struct wl_rateset_args {
 	u32 count;		/* # rates in this set */
 	u8 rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
@@ -352,6 +283,8 @@
 } wl_join_params_t;
 #define WL_JOIN_PARAMS_FIXED_SIZE 	(sizeof(wl_join_params_t) - sizeof(chanspec_t))
 
+#endif /* BRCM_FULLMAC */
+
 /* defines used by the nrate iovar */
 #define NRATE_MCS_INUSE	0x00000080	/* MSC in use,indicates b0-6 holds an mcs */
 #define NRATE_RATE_MASK 0x0000007f	/* rate/mcs value */
@@ -391,6 +324,7 @@
 
 #define HIGHEST_SINGLE_STREAM_MCS	7	/* MCS values greater than this enable multiple streams */
 
+#ifdef BRCM_FULLMAC
 #define MAX_CCA_CHANNELS 38	/* Max number of 20 Mhz wide channels */
 #define MAX_CCA_SECS     60	/* CCA keeps this many seconds history */
 
@@ -428,8 +362,11 @@
 	cca_congest_t secs[1];	/* Data */
 } cca_congest_channel_req_t;
 
+#endif /* BRCM_FULLMAC */
+
 #define WLC_CNTRY_BUF_SZ	4	/* Country string is 3 bytes + NUL */
 
+#ifdef BRCM_FULLMAC
 typedef struct wl_country {
 	char country_abbrev[WLC_CNTRY_BUF_SZ];	/* nul-terminated country code used in
 						 * the Country IE
@@ -516,6 +453,7 @@
 	wl_rm_rep_elt_t rep[1];	/* variable length block of reports */
 } wl_rm_rep_t;
 #define WL_RM_REP_FIXED_LEN	8
+#endif /* BRCM_FULLMAC */
 
 /* Enumerate crypto algorithms */
 #define	CRYPTO_ALGO_OFF			0
@@ -621,27 +559,6 @@
 	u8 activehi;
 } wl_led_info_t;
 
-/* flags */
-#define WLC_ASSOC_REQ_IS_REASSOC 0x01	/* assoc req was actually a reassoc */
-
-/* srom read/write struct passed through ioctl */
-typedef struct {
-	uint byteoff;		/* byte offset */
-	uint nbytes;		/* number of bytes */
-	u16 buf[1];
-} srom_rw_t;
-
-/* similar cis (srom or otp) struct [iovar: may not be aligned] */
-typedef struct {
-	u32 source;		/* cis source */
-	u32 byteoff;		/* byte offset */
-	u32 nbytes;		/* number of bytes */
-	/* data follows here */
-} cis_rw_t;
-
-#define WLC_CIS_DEFAULT	0	/* built-in default */
-#define WLC_CIS_SROM	1	/* source is sprom */
-#define WLC_CIS_OTP	2	/* source is otp */
 
 /* R_REG and W_REG struct passed through ioctl */
 typedef struct {
@@ -651,102 +568,14 @@
 	uint band;		/* band (optional) */
 } rw_reg_t;
 
-/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */
-/* PCL - Power Control Loop */
-/* current gain setting is replaced by user input */
-#define WL_ATTEN_APP_INPUT_PCL_OFF	0	/* turn off PCL, apply supplied input */
-#define WL_ATTEN_PCL_ON			1	/* turn on PCL */
-/* current gain setting is maintained */
-#define WL_ATTEN_PCL_OFF		2	/* turn off PCL. */
 
-typedef struct {
-	u16 auto_ctrl;	/* WL_ATTEN_XX */
-	u16 bb;		/* Baseband attenuation */
-	u16 radio;		/* Radio attenuation */
-	u16 txctl1;		/* Radio TX_CTL1 value */
-} atten_t;
-
-/* Per-AC retry parameters */
-struct wme_tx_params_s {
-	u8 short_retry;
-	u8 short_fallback;
-	u8 long_retry;
-	u8 long_fallback;
-	u16 max_rate;	/* In units of 512 Kbps */
-};
-
-typedef struct wme_tx_params_s wme_tx_params_t;
-
-#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT)
-
-/* defines used by poweridx iovar - it controls power in a-band */
-/* current gain setting is maintained */
-#define WL_PWRIDX_PCL_OFF	-2	/* turn off PCL.  */
-#define WL_PWRIDX_PCL_ON	-1	/* turn on PCL */
-#define WL_PWRIDX_LOWER_LIMIT	-2	/* lower limit */
-#define WL_PWRIDX_UPPER_LIMIT	63	/* upper limit */
-/* value >= 0 causes
- *	- input to be set to that value
- *	- PCL to be off
- */
-
-/* Used to get specific link/ac parameters */
-typedef struct {
-	int ac;
-	u8 val;
-	struct ether_addr ea;
-} link_val_t;
-
-#define BCM_MAC_STATUS_INDICATION	(0x40010200L)
-
-typedef struct {
-	u16 ver;		/* version of this struct */
-	u16 len;		/* length in bytes of this structure */
-	u16 cap;		/* sta's advertised capabilities */
-	u32 flags;		/* flags defined below */
-	u32 idle;		/* time since data pkt rx'd from sta */
-	struct ether_addr ea;	/* Station address */
-	wl_rateset_t rateset;	/* rateset in use */
-	u32 in;		/* seconds elapsed since associated */
-	u32 listen_interval_inms;	/* Min Listen interval in ms for this STA */
-	u32 tx_pkts;		/* # of packets transmitted */
-	u32 tx_failures;	/* # of packets failed */
-	u32 rx_ucast_pkts;	/* # of unicast packets received */
-	u32 rx_mcast_pkts;	/* # of multicast packets received */
-	u32 tx_rate;		/* Rate of last successful tx frame */
-	u32 rx_rate;		/* Rate of last successful rx frame */
-	u32 rx_decrypt_succeeds;	/* # of packet decrypted successfully */
-	u32 rx_decrypt_failures;	/* # of packet decrypted unsuccessfully */
-} sta_info_t;
-
-#define WL_OLD_STAINFO_SIZE	offsetof(sta_info_t, tx_pkts)
-
-#define WL_STA_VER		3
-
-/* Flags for sta_info_t indicating properties of STA */
-#define WL_STA_BRCM		0x1	/* Running a Broadcom driver */
-#define WL_STA_WME		0x2	/* WMM association */
-#define WL_STA_ABCAP		0x4
-#define WL_STA_AUTHE		0x8	/* Authenticated */
-#define WL_STA_ASSOC		0x10	/* Associated */
-#define WL_STA_AUTHO		0x20	/* Authorized */
-#define WL_STA_WDS		0x40	/* Wireless Distribution System */
-#define WL_STA_WDS_LINKUP	0x80	/* WDS traffic/probes flowing properly */
-#define WL_STA_PS		0x100	/* STA is in power save mode from AP's viewpoint */
-#define WL_STA_APSD_BE		0x200	/* APSD delv/trigger for AC_BE is default enabled */
-#define WL_STA_APSD_BK		0x400	/* APSD delv/trigger for AC_BK is default enabled */
-#define WL_STA_APSD_VI		0x800	/* APSD delv/trigger for AC_VI is default enabled */
-#define WL_STA_APSD_VO		0x1000	/* APSD delv/trigger for AC_VO is default enabled */
-#define WL_STA_N_CAP		0x2000	/* STA 802.11n capable */
-#define WL_STA_SCBSTATS		0x4000	/* Per STA debug stats */
-
-#define WL_WDS_LINKUP		WL_STA_WDS_LINKUP	/* deprecated */
-
+#ifdef BRCM_FULLMAC
 /* Used to get specific STA parameters */
 typedef struct {
 	u32 val;
 	struct ether_addr ea;
 } scb_val_t;
+#endif /* BRCM_FULLMAC */
 
 /* channel encoding */
 typedef struct channel_info {
@@ -770,6 +599,7 @@
 	uint rx_ocast_good_pkt;	/* unicast packets destined for others */
 } get_pktcnt_t;
 
+#ifdef BRCM_FULLMAC
 /* Linux network driver ioctl encoding */
 typedef struct wl_ioctl {
 	uint cmd;		/* common ioctl definition */
@@ -779,11 +609,8 @@
 	uint used;		/* bytes read or written (optional) */
 	uint needed;		/* bytes needed (optional) */
 } wl_ioctl_t;
+#endif /* BRCM_FULLMAC */
 
-/* reference to wl_ioctl_t struct used by usermode driver */
-#define ioctl_subtype	set	/* subtype param */
-#define ioctl_pid	used	/* pid param */
-#define ioctl_status	needed	/* status param */
 
 /*
  * Structure for passing hardware and software
@@ -810,45 +637,11 @@
 
 #define WL_REV_INFO_LEGACY_LENGTH	48
 
-#define WL_BRAND_MAX 10
-typedef struct wl_instance_info {
-	uint instance;
-	char brand[WL_BRAND_MAX];
-} wl_instance_info_t;
-
-/* structure to change size of tx fifo */
-typedef struct wl_txfifo_sz {
-	u16 magic;
-	u16 fifo;
-	u16 size;
-} wl_txfifo_sz_t;
-/* magic pattern used for mismatch driver and wl */
-#define WL_TXFIFO_SZ_MAGIC	0xa5a5
-
-/* Transfer info about an IOVar from the driver */
-/* Max supported IOV name size in bytes, + 1 for nul termination */
-#define WLC_IOV_NAME_LEN 30
-typedef struct wlc_iov_trx_s {
-	u8 module;
-	u8 type;
-	char name[WLC_IOV_NAME_LEN];
-} wlc_iov_trx_t;
-
-/* check this magic number */
-#define WLC_IOCTL_MAGIC		0x14e46c77
-
-#define PROC_ENTRY_NAME "brcm_debug"
-/* bump this number if you change the ioctl interface */
-#define WLC_IOCTL_VERSION	1
-
 #ifdef BRCM_FULLMAC
-#define	WLC_IOCTL_MAXLEN	8192
-#else
-#define	WLC_IOCTL_MAXLEN		3072	/* max length ioctl buffer required */
-#endif
 #define	WLC_IOCTL_SMLEN			256	/* "small" length ioctl buffer required */
 #define WLC_IOCTL_MEDLEN		1536	/* "med" length ioctl buffer required */
-#define WLC_SAMPLECOLLECT_MAXLEN	10240	/* Max Sample Collect buffer for two cores */
+#define	WLC_IOCTL_MAXLEN	8192
+#endif
 
 /* common ioctl definitions */
 #define WLC_GET_MAGIC				0
@@ -1399,23 +1192,6 @@
 #define WL_TX_POWER_MCS40_FIRST	        28
 #define WL_TX_POWER_MCS40_NUM	        17
 
-typedef struct {
-	u32 flags;
-	chanspec_t chanspec;	/* txpwr report for this channel */
-	chanspec_t local_chanspec;	/* channel on which we are associated */
-	u8 local_max;	/* local max according to the AP */
-	u8 local_constraint;	/* local constraint according to the AP */
-	s8 antgain[2];	/* Ant gain for each band - from SROM */
-	u8 rf_cores;		/* count of RF Cores being reported */
-	u8 est_Pout[4];	/* Latest tx power out estimate per RF
-				 * chain without adjustment
-				 */
-	u8 est_Pout_cck;	/* Latest CCK tx power out estimate */
-	u8 user_limit[WL_TX_POWER_RATES_LEGACY];	/* User limit */
-	u8 reg_limit[WL_TX_POWER_RATES_LEGACY];	/* Regulatory power limit */
-	u8 board_limit[WL_TX_POWER_RATES_LEGACY];	/* Max power board can support (SROM) */
-	u8 target[WL_TX_POWER_RATES_LEGACY];	/* Latest target power */
-} tx_power_legacy2_t;
 
 #define WL_TX_POWER_RATES	       101
 #define WL_TX_POWER_CCK_FIRST	       0
@@ -1848,63 +1624,6 @@
 	u8 retry;		/* retry value */
 };
 
-/* structure for addts arguments */
-/* For ioctls that take a list of TSPEC */
-struct tslist {
-	int count;		/* number of tspecs */
-	struct tsinfo_arg tsinfo[1];	/* variable length array of tsinfo */
-};
-
-/* structure for addts/delts arguments */
-typedef struct tspec_arg {
-	u16 version;		/* see definition of TSPEC_ARG_VERSION */
-	u16 length;		/* length of entire structure */
-	uint flag;		/* bit field */
-	/* TSPEC Arguments */
-	struct tsinfo_arg tsinfo;	/* TS Info bit field */
-	u16 nom_msdu_size;	/* (Nominal or fixed) MSDU Size (bytes) */
-	u16 max_msdu_size;	/* Maximum MSDU Size (bytes) */
-	uint min_srv_interval;	/* Minimum Service Interval (us) */
-	uint max_srv_interval;	/* Maximum Service Interval (us) */
-	uint inactivity_interval;	/* Inactivity Interval (us) */
-	uint suspension_interval;	/* Suspension Interval (us) */
-	uint srv_start_time;	/* Service Start Time (us) */
-	uint min_data_rate;	/* Minimum Data Rate (bps) */
-	uint mean_data_rate;	/* Mean Data Rate (bps) */
-	uint peak_data_rate;	/* Peak Data Rate (bps) */
-	uint max_burst_size;	/* Maximum Burst Size (bytes) */
-	uint delay_bound;	/* Delay Bound (us) */
-	uint min_phy_rate;	/* Minimum PHY Rate (bps) */
-	u16 surplus_bw;	/* Surplus Bandwidth Allowance (range 1.0 to 8.0) */
-	u16 medium_time;	/* Medium Time (32 us/s periods) */
-	u8 dialog_token;	/* dialog token */
-} tspec_arg_t;
-
-/* tspec arg for desired station */
-typedef struct tspec_per_sta_arg {
-	struct ether_addr ea;
-	struct tspec_arg ts;
-} tspec_per_sta_arg_t;
-
-/* structure for max bandwidth for each access category */
-typedef struct wme_max_bandwidth {
-	u32 ac[AC_COUNT];	/* max bandwidth for each access category */
-} wme_max_bandwidth_t;
-
-#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t))
-
-/* current version of wl_tspec_arg_t struct */
-#define	TSPEC_ARG_VERSION		2	/* current version of wl_tspec_arg_t struct */
-#define TSPEC_ARG_LENGTH		55	/* argument length from tsinfo to medium_time */
-#define TSPEC_DEFAULT_DIALOG_TOKEN	42	/* default dialog token */
-#define TSPEC_DEFAULT_SBW_FACTOR	0x3000	/* default surplus bw */
-
-/* define for flag */
-#define TSPEC_PENDING		0	/* TSPEC pending */
-#define TSPEC_ACCEPTED		1	/* TSPEC accepted */
-#define TSPEC_REJECTED		2	/* TSPEC rejected */
-#define TSPEC_UNKNOWN		3	/* TSPEC unknown */
-#define TSPEC_STATUS_MASK	7	/* TSPEC status mask */
 
 /* Software feature flag defines used by wlfeatureflag */
 #define WL_SWFL_NOHWRADIO	0x0004
@@ -1913,16 +1632,6 @@
 
 #define WL_LIFETIME_MAX 0xFFFF	/* Max value in ms */
 
-/*
- * Dongle pattern matching filter.
- */
-
-/* Packet filter types. Currently, only pattern matching is supported. */
-typedef enum wl_pkt_filter_type {
-	WL_PKT_FILTER_TYPE_PATTERN_MATCH	/* Pattern matching filter */
-} wl_pkt_filter_type_t;
-
-#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t
 
 /* Pattern matching filter. Specifies an offset within received packets to
  * start matching, the pattern to match, the size of the pattern, and a bitmask
@@ -1957,20 +1666,6 @@
 	u32 enable;		/* Enable/disable bool */
 } wl_pkt_filter_enable_t;
 
-/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */
-typedef struct wl_pkt_filter_list {
-	u32 num;		/* Number of installed packet filters */
-	wl_pkt_filter_t filter[1];	/* Variable array of packet filters. */
-} wl_pkt_filter_list_t;
-
-#define WL_PKT_FILTER_LIST_FIXED_LEN	  offsetof(wl_pkt_filter_list_t, filter)
-
-/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */
-typedef struct wl_pkt_filter_stats {
-	u32 num_pkts_matched;	/* # filter matches for specified filter id */
-	u32 num_pkts_forwarded;	/* # packets fwded from dongle to host for all filters */
-	u32 num_pkts_discarded;	/* # packets discarded by dongle for all filters */
-} wl_pkt_filter_stats_t;
 
 #define	WLC_RSSI_INVALID	 0	/* invalid RSSI value */
 
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c
index 82872611..9e6bbcd 100644
--- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c
+++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c
@@ -20,10 +20,14 @@
 #include <linux/string.h>
 #include <bcmdefs.h>
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <bcmendian.h>
 #include <bcmnvram.h>
 #include <sbchipc.h>
+#include <bcmdevs.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 
 #include <wlc_phy_int.h>
 #include <wlc_phyreg_n.h>
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c
index 3d3112e..1fde9d5 100644
--- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c
+++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c
@@ -20,10 +20,14 @@
 #include <wlc_cfg.h>
 #include <qmath.h>
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/pci.h>
 #include <siutils.h>
 #include <hndpmu.h>
 
+#include <bcmdevs.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+
 #include <wlc_phy_radio.h>
 #include <wlc_phy_int.h>
 #include <wlc_phy_lcn.h>
diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c
index 950008f..3e1ab57 100644
--- a/drivers/staging/brcm80211/phy/wlc_phy_n.c
+++ b/drivers/staging/brcm80211/phy/wlc_phy_n.c
@@ -18,13 +18,17 @@
 #include <linux/string.h>
 #include <bcmdefs.h>
 #include <wlc_cfg.h>
-#include <linuxver.h>
+#include <linux/pci.h>
 #include <osl.h>
 #include <siutils.h>
 #include <sbchipc.h>
 #include <hndpmu.h>
 #include <bcmendian.h>
 
+#include <bcmdevs.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+
 #include <wlc_phy_radio.h>
 #include <wlc_phy_int.h>
 #include <wlc_phyreg_n.h>
diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c
index 6ce9e5d..330b881 100644
--- a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c
+++ b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c
@@ -15,6 +15,9 @@
  */
 
 #include <linux/types.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <osl.h>
 #include <wlc_phy_int.h>
 #include <wlc_phytbl_lcn.h>
 
diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c
index 7cc2c56..a9fc193 100644
--- a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c
+++ b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c
@@ -16,6 +16,9 @@
 
 #include <linux/kernel.h>
 
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <osl.h>
 #include <wlc_phy_int.h>
 #include <wlc_phytbl_n.h>
 
diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c
index d060377..4b59e07 100644
--- a/drivers/staging/brcm80211/sys/wl_mac80211.c
+++ b/drivers/staging/brcm80211/sys/wl_mac80211.c
@@ -21,13 +21,14 @@
 #include <linux/string.h>
 #include <linux/pci_ids.h>
 #include <bcmdefs.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
 #include <osl.h>
 #define WLC_MAXBSSCFG		1	/* single BSS configs */
 
 #include <wlc_cfg.h>
 #include <net/mac80211.h>
-#include <epivers.h>
 #ifndef WLC_HIGH_ONLY
 #include <phy_version.h>
 #endif
@@ -35,6 +36,8 @@
 #include <pcicfg.h>
 #include <wlioctl.h>
 #include <wlc_key.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 #include <wlc_channel.h>
 #include <wlc_pub.h>
 #include <wlc_scb.h>
@@ -179,32 +182,6 @@
 #endif				/* WLC_HIGH_ONLY */
 #endif				/* BCMDBG */
 
-static int oneonly;
-module_param(oneonly, int, 0);
-
-static int piomode;
-module_param(piomode, int, 0);
-
-static int instance_base;	/* Starting instance number */
-module_param(instance_base, int, 0);
-
-#if defined(BCMDBG)
-static char *macaddr;
-module_param(macaddr, charp, S_IRUGO);
-#endif
-
-static int nompc = 1;
-module_param(nompc, int, 0);
-
-static char name[IFNAMSIZ] = "eth%d";
-module_param_string(name, name, IFNAMSIZ, 0);
-
-#ifndef	SRCBASE
-#define	SRCBASE "."
-#endif
-
-#define WL_MAGIC 	0xdeadbeef
-
 #define HW_TO_WL(hw)	 (hw->priv)
 #define WL_TO_HW(wl)	  (wl->pub->ieee_hw)
 #ifdef WLC_HIGH_ONLY
@@ -773,7 +750,7 @@
 	struct ieee80211_hw *hw;
 	u8 perm[ETH_ALEN];
 
-	unit = wl_found + instance_base;
+	unit = wl_found;
 	err = 0;
 
 	if (unit < 0) {
@@ -781,13 +758,7 @@
 		return NULL;
 	}
 
-	if (oneonly && (unit != instance_base)) {
-		WL_ERROR(("wl%d: wl_attach: oneonly is set, exiting\n", unit));
-		return NULL;
-	}
-
-	/* Requires pkttag feature */
-	osh = osl_attach(btparam, bustype, true);
+	osh = osl_attach(btparam, bustype);
 	ASSERT(osh);
 
 #ifdef WLC_HIGH_ONLY
@@ -806,7 +777,6 @@
 #endif
 	ASSERT(wl);
 
-	wl->magic = WL_MAGIC;
 	wl->osh = osh;
 	atomic_set(&wl->callbacks, 0);
 
@@ -840,9 +810,7 @@
 	base_addr = regs;
 
 	if (bustype == PCI_BUS) {
-		/* piomode can be overwritten by command argument */
-		wl->piomode = piomode;
-		WL_TRACE(("PCI/%s\n", wl->piomode ? "PIO" : "DMA"));
+		wl->piomode = false;
 	} else if (bustype == RPC_BUS) {
 		/* Do nothing */
 	} else {
@@ -890,8 +858,8 @@
 	wl_release_fw(wl);
 #endif
 	if (!wl->wlc) {
-		printf("%s: %s wlc_attach() failed with code %d\n",
-			KBUILD_MODNAME, EPI_VERSION_STR, err);
+		printf("%s: wlc_attach() failed with code %d\n",
+			KBUILD_MODNAME, err);
 		goto fail;
 	}
 	wl->pub = wlc_pub(wl->wlc);
@@ -909,11 +877,9 @@
 			  wl_rpc_down, NULL, NULL);
 #endif				/* WLC_HIGH_ONLY */
 
-	if (nompc) {
-		if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
-			WL_ERROR(("wl%d: Error setting MPC variable to 0\n",
-				  unit));
-		}
+	if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
+		WL_ERROR(("wl%d: Error setting MPC variable to 0\n",
+			  unit));
 	}
 #ifdef BCMSDIO
 	/* Set SDIO drive strength */
@@ -958,14 +924,14 @@
 	}
 #ifndef WLC_HIGH_ONLY
 	WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
-		  EPI_VERSION_STR " (" PHY_VERSION_STR ")", unit));
+		  " (" PHY_VERSION_STR ")", unit));
 #else
-	WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
-		  EPI_VERSION_STR, unit));
+	WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 Splitmac MAC80211 Driver "
+		  , unit));
 #endif
 
 #ifdef BCMDBG
-	printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")");
+	printf(" (Compiled at " __TIME__ " on " __DATE__ ")");
 #endif				/* BCMDBG */
 	printf("\n");
 
diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c
index 2dc89f9..8001dca 100644
--- a/drivers/staging/brcm80211/sys/wlc_alloc.c
+++ b/drivers/staging/brcm80211/sys/wlc_alloc.c
@@ -17,15 +17,20 @@
 #include <linux/string.h>
 #include <bcmdefs.h>
 #include <wlc_cfg.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <osl.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <wlioctl.h>
 #include <wlc_pub.h>
 #include <wlc_key.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_alloc.h>
+#include <wl_dbg.h>
 
 static wlc_pub_t *wlc_pub_malloc(osl_t *osh, uint unit, uint *err,
 				 uint devid);
diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c
index a4e49f3..0bd7069 100644
--- a/drivers/staging/brcm80211/sys/wlc_ampdu.c
+++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c
@@ -16,19 +16,19 @@
 #include <linux/kernel.h>
 #include <wlc_cfg.h>
 #include <bcmdefs.h>
-#include <linuxver.h>
-#include <bcmdefs.h>
 #include <osl.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <bcmendian.h>
 #include <wlioctl.h>
+#include <sbhndpio.h>
 #include <sbhnddma.h>
 #include <hnddma.h>
 #include <d11.h>
 #include <wlc_rate.h>
 #include <wlc_pub.h>
 #include <wlc_key.h>
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_phy_hal.h>
 #include <wlc_antsel.h>
@@ -36,6 +36,7 @@
 #include <net/mac80211.h>
 #include <wlc_ampdu.h>
 #include <wl_export.h>
+#include <wl_dbg.h>
 
 #ifdef WLC_HIGH_ONLY
 #include <bcm_rpc_tp.h>
diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c
index 5ff8831..ecc35de 100644
--- a/drivers/staging/brcm80211/sys/wlc_antsel.c
+++ b/drivers/staging/brcm80211/sys/wlc_antsel.c
@@ -19,18 +19,23 @@
 #ifdef WLANTSEL
 
 #include <linux/kernel.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <bcmdefs.h>
 #include <osl.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <wlioctl.h>
 
+#include <bcmdevs.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 #include <d11.h>
 #include <wlc_rate.h>
 #include <wlc_key.h>
 #include <wlc_pub.h>
 #include <wl_dbg.h>
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_bmac.h>
 #include <wlc_phy_hal.h>
diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c
index b70f9d0..fc5201d 100644
--- a/drivers/staging/brcm80211/sys/wlc_bmac.c
+++ b/drivers/staging/brcm80211/sys/wlc_bmac.c
@@ -20,7 +20,9 @@
 
 #include <linux/kernel.h>
 #include <wlc_cfg.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
 #include <bcmdefs.h>
 #include <osl.h>
 #include <proto/802.11.h>
@@ -42,12 +44,14 @@
 #include <wlc_channel.h>
 #include <bcmsrom.h>
 #include <wlc_key.h>
+#include <bcmdevs.h>
 /* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type
  * dependencies. Need to include these to files to allow a clean include of wlc.h
  * with WLC_HIGH defined.
  * At some point we may be able to skip the include of wlc.h and instead just
  * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle.
  */
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_bmac.h>
 #include <wlc_phy_shim.h>
@@ -69,6 +73,7 @@
 #include <pcie_core.h>
 
 #include <wlc_alloc.h>
+#include <wl_dbg.h>
 
 #define	TIMER_INTERVAL_WATCHDOG_BMAC	1000	/* watchdog timer, in unit of ms */
 
diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c
index 5092803..2fcdbc72 100644
--- a/drivers/staging/brcm80211/sys/wlc_channel.c
+++ b/drivers/staging/brcm80211/sys/wlc_channel.c
@@ -19,16 +19,21 @@
 #include <bcmdefs.h>
 #include <wlc_cfg.h>
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <bcmutils.h>
 #include <siutils.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 #include <wlioctl.h>
 #include <wlc_pub.h>
 #include <wlc_key.h>
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_bmac.h>
 #include <wlc_stf.h>
 #include <wlc_channel.h>
+#include <wl_dbg.h>
 
 typedef struct wlc_cm_band {
 	u8 locale_flags;	/* locale_info_t flags */
diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c
index 7e1bf0e..e4ab077 100644
--- a/drivers/staging/brcm80211/sys/wlc_event.c
+++ b/drivers/staging/brcm80211/sys/wlc_event.c
@@ -16,9 +16,13 @@
 
 #include <linux/kernel.h>
 #include <bcmdefs.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <osl.h>
 #include <bcmutils.h>
 #include <siutils.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 #include <wlioctl.h>
 #include <wlc_cfg.h>
 #include <wlc_pub.h>
@@ -32,6 +36,7 @@
 #ifdef MSGTRACE
 #include <msgtrace.h>
 #endif
+#include <wl_dbg.h>
 
 /* Local prototypes */
 static void wlc_timer_cb(void *arg);
diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c
index feaffcc..a9fa48a 100644
--- a/drivers/staging/brcm80211/sys/wlc_mac80211.c
+++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c
@@ -16,8 +16,8 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <bcmdefs.h>
+#include <bcmdevs.h>
 #include <wlc_cfg.h>
-#include <linuxver.h>
 #include <osl.h>
 #include <bcmutils.h>
 #include <bcmwifi.h>
@@ -27,7 +27,7 @@
 #include <pcicfg.h>
 #include <bcmsrom.h>
 #include <wlioctl.h>
-#include <epivers.h>
+#include <sbhndpio.h>
 #include <sbhnddma.h>
 #include <hnddma.h>
 #include <hndpmu.h>
@@ -37,6 +37,7 @@
 #include <wlc_key.h>
 #include <wlc_bsscfg.h>
 #include <wlc_channel.h>
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_bmac.h>
 #include <wlc_scb.h>
@@ -61,6 +62,7 @@
 #endif				/* WLC_HIGH_ONLY */
 #include <wlc_alloc.h>
 #include <net/mac80211.h>
+#include <wl_dbg.h>
 
 #ifdef WLC_HIGH_ONLY
 #undef R_REG
@@ -135,6 +137,8 @@
 
 #define SCAN_IN_PROGRESS(x)	0
 
+#define EPI_VERSION_NUM		0x054b0b00
+
 #ifdef BCMDBG
 /* pointer to most recently allocated wl/wlc */
 static wlc_info_t *wlc_info_dbg = (wlc_info_t *) (NULL);
@@ -667,7 +671,7 @@
 		 * may be either true or false due to the low level override.
 		 */
 		wake = STAY_AWAKE(wlc);
-		wake_ok = (wake && ((tmp & MCTL_WAKE) != 0)) || !wake;
+		wake_ok = ((tmp & MCTL_WAKE) != 0) || !wake;
 #endif
 		if (hps && !wake_ok) {
 			WL_ERROR(("wl%d: wake not sync, sw %d maccontrol 0x%x\n", wlc->pub->unit, wake, tmp));
@@ -1780,8 +1784,10 @@
 	ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN);
 	ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN);
 	ASSERT(sizeof(ht_cap_ie_t) == HT_CAP_IE_LEN);
+#ifdef BRCM_FULLMAC
 	ASSERT(offsetof(wl_scan_params_t, channel_list) ==
 	       WL_SCAN_PARAMS_FIXED_SIZE);
+#endif
 	ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32)));
 	ASSERT(ISPOWEROF2(MA_WINDOW_SZ));
 
diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h
index 6a77591..a3c6fb8 100644
--- a/drivers/staging/brcm80211/sys/wlc_mac80211.h
+++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h
@@ -17,19 +17,13 @@
 #ifndef _wlc_h_
 #define _wlc_h_
 
-#include <wlc_types.h>
-
-#include <wl_dbg.h>
 #include <wlioctl.h>
-#include <wlc_event.h>
 #include <wlc_phy_hal.h>
 #include <wlc_channel.h>
 #ifdef WLC_SPLIT
 #include <bcm_rpc.h>
 #endif
-
 #include <wlc_bsscfg.h>
-
 #include <wlc_scb.h>
 
 #define MA_WINDOW_SZ		8	/* moving average window size */
diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c
index bf8e2e1..201ecdb 100644
--- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c
+++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c
@@ -24,9 +24,10 @@
 #include <linux/kernel.h>
 #include <bcmdefs.h>
 #include <wlc_cfg.h>
-#include <linuxver.h>
-#include <bcmutils.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <osl.h>
+#include <bcmutils.h>
 
 #include <proto/802.11.h>
 #include <bcmwifi.h>
@@ -46,6 +47,7 @@
 #include <wlc_channel.h>
 #include <bcmsrom.h>
 #include <wlc_key.h>
+#include <wlc_event.h>
 
 #include <wlc_mac80211.h>
 
@@ -53,6 +55,7 @@
 #include <wlc_phy_shim.h>
 #include <wlc_phy_hal.h>
 #include <wl_export.h>
+#include <wl_dbg.h>
 
 /* PHY SHIM module specific state */
 struct wlc_phy_shim_info {
diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h
index a6a8c33..f6ac5e99 100644
--- a/drivers/staging/brcm80211/sys/wlc_pub.h
+++ b/drivers/staging/brcm80211/sys/wlc_pub.h
@@ -437,13 +437,9 @@
 #define EDCF_ENAB(pub) (WME_ENAB(pub))
 #define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
 
-#define MONITOR_ENAB(wlc)	(bcmspace && (wlc)->monitor)
+#define MONITOR_ENAB(wlc)	((wlc)->monitor)
 
-#define PROMISC_ENAB(wlc)	(bcmspace && (wlc)->promisc)
-
-extern void wlc_pkttag_info_move(wlc_pub_t *pub, void *pkt_from, void *pkt_to);
-
-#define WLPKTTAGSCB(p) (WLPKTTAG(p)->_scb)
+#define PROMISC_ENAB(wlc)	((wlc)->promisc)
 
 #define	WLC_PREC_COUNT		16	/* Max precedence level implemented */
 
diff --git a/drivers/staging/brcm80211/sys/wlc_rate.c b/drivers/staging/brcm80211/sys/wlc_rate.c
index d2d7256..e1199b23 100644
--- a/drivers/staging/brcm80211/sys/wlc_rate.c
+++ b/drivers/staging/brcm80211/sys/wlc_rate.c
@@ -17,12 +17,14 @@
 #include <bcmdefs.h>
 #include <wlc_cfg.h>
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <bcmendian.h>
 #include <wlioctl.h>
 
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 #include <proto/802.11.h>
 #include <d11.h>
 #include <wlc_rate.h>
diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c
index 4728ad9..2bca052 100644
--- a/drivers/staging/brcm80211/sys/wlc_stf.c
+++ b/drivers/staging/brcm80211/sys/wlc_stf.c
@@ -15,8 +15,8 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <wlc_cfg.h>
-#include <linuxver.h>
 #include <bcmdefs.h>
 #include <osl.h>
 #include <bcmutils.h>
@@ -25,17 +25,21 @@
 #include <proto/802.11.h>
 #include <wlioctl.h>
 #include <bcmwifi.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
 #include <d11.h>
 #include <wlc_rate.h>
 #include <wlc_pub.h>
 #include <wlc_key.h>
 #include <wlc_channel.h>
 #include <wlc_bsscfg.h>
+#include <wlc_event.h>
 #include <wlc_mac80211.h>
 #include <wlc_scb.h>
 #include <wl_export.h>
 #include <wlc_bmac.h>
 #include <wlc_stf.h>
+#include <wl_dbg.h>
 
 #define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \
 	NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c
index 75a7e3a..1d4e372 100644
--- a/drivers/staging/brcm80211/util/aiutils.c
+++ b/drivers/staging/brcm80211/util/aiutils.c
@@ -17,8 +17,12 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <bcmdefs.h>
+#ifdef BRCM_FULLMAC
+#include <linux/netdevice.h>
+#endif
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <hndsoc.h>
diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c
index c909832..9b1e6d9 100644
--- a/drivers/staging/brcm80211/util/bcmotp.c
+++ b/drivers/staging/brcm80211/util/bcmotp.c
@@ -18,7 +18,8 @@
 #include <linux/string.h>
 #include <bcmdefs.h>
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <bcmdevs.h>
 #include <bcmutils.h>
 #include <siutils.h>
diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c
index 1282ef7..4f3d3ca 100644
--- a/drivers/staging/brcm80211/util/bcmsrom.c
+++ b/drivers/staging/brcm80211/util/bcmsrom.c
@@ -17,7 +17,8 @@
 #include <linux/string.h>
 #include <bcmdefs.h>
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <stdarg.h>
 #include <bcmutils.h>
 #include <hndsoc.h>
diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c
index 9789ea4..869d34c 100644
--- a/drivers/staging/brcm80211/util/bcmutils.c
+++ b/drivers/staging/brcm80211/util/bcmutils.c
@@ -19,8 +19,10 @@
 #include <linux/string.h>
 #include <bcmdefs.h>
 #include <stdarg.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
 #include <osl.h>
-#include <linuxver.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <bcmnvram.h>
@@ -30,7 +32,6 @@
 #include <proto/802.1d.h>
 #include <proto/802.11.h>
 
-
 /* copy a buffer into a pkt buffer chain */
 uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, unsigned char *buf)
 {
diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c
index 1bb6c78..81e54bd 100644
--- a/drivers/staging/brcm80211/util/bcmwifi.c
+++ b/drivers/staging/brcm80211/util/bcmwifi.c
@@ -15,6 +15,10 @@
  */
 #include <linux/ctype.h>
 #include <linux/kernel.h>
+#ifdef BRCM_FULLMAC
+#include <linux/netdevice.h>
+#endif
+#include <osl.h>
 #include <bcmdefs.h>
 #include <bcmutils.h>
 #include <bcmwifi.h>
diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c
index fe503e7..b4dcb05 100644
--- a/drivers/staging/brcm80211/util/hnddma.c
+++ b/drivers/staging/brcm80211/util/hnddma.c
@@ -16,7 +16,8 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linuxver.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
 #include <bcmdefs.h>
 #include <bcmdevs.h>
 #include <osl.h>
diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c
index a8f3306..6fb256b 100644
--- a/drivers/staging/brcm80211/util/hndpmu.c
+++ b/drivers/staging/brcm80211/util/hndpmu.c
@@ -15,7 +15,11 @@
  */
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#ifdef BRCM_FULLMAC
+#include <linux/netdevice.h>
+#endif
 #include <bcmdefs.h>
 #include <osl.h>
 #include <bcmutils.h>
diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c
index 2bb5b87..7211f8a 100644
--- a/drivers/staging/brcm80211/util/linux_osl.c
+++ b/drivers/staging/brcm80211/util/linux_osl.c
@@ -20,7 +20,10 @@
 #include <asm/paccess.h>
 #endif				/* mips */
 #include <bcmendian.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
 #include <bcmdefs.h>
 #include <osl.h>
 #include <bcmutils.h>
@@ -36,82 +39,13 @@
 	osl_pubinfo_t pub;
 	uint magic;
 	void *pdev;
-	uint failed;
 	uint bustype;
 };
 
 /* Global ASSERT type flag */
 u32 g_assert_type;
 
-#ifdef BRCM_FULLMAC
-static s16 linuxbcmerrormap[] = { 0,	/* 0 */
-	-EINVAL,		/* BCME_ERROR */
-	-EINVAL,		/* BCME_BADARG */
-	-EINVAL,		/* BCME_BADOPTION */
-	-EINVAL,		/* BCME_NOTUP */
-	-EINVAL,		/* BCME_NOTDOWN */
-	-EINVAL,		/* BCME_NOTAP */
-	-EINVAL,		/* BCME_NOTSTA */
-	-EINVAL,		/* BCME_BADKEYIDX */
-	-EINVAL,		/* BCME_RADIOOFF */
-	-EINVAL,		/* BCME_NOTBANDLOCKED */
-	-EINVAL,		/* BCME_NOCLK */
-	-EINVAL,		/* BCME_BADRATESET */
-	-EINVAL,		/* BCME_BADBAND */
-	-E2BIG,			/* BCME_BUFTOOSHORT */
-	-E2BIG,			/* BCME_BUFTOOLONG */
-	-EBUSY,			/* BCME_BUSY */
-	-EINVAL,		/* BCME_NOTASSOCIATED */
-	-EINVAL,		/* BCME_BADSSIDLEN */
-	-EINVAL,		/* BCME_OUTOFRANGECHAN */
-	-EINVAL,		/* BCME_BADCHAN */
-	-EFAULT,		/* BCME_BADADDR */
-	-ENOMEM,		/* BCME_NORESOURCE */
-	-EOPNOTSUPP,		/* BCME_UNSUPPORTED */
-	-EMSGSIZE,		/* BCME_BADLENGTH */
-	-EINVAL,		/* BCME_NOTREADY */
-	-EPERM,			/* BCME_NOTPERMITTED */
-	-ENOMEM,		/* BCME_NOMEM */
-	-EINVAL,		/* BCME_ASSOCIATED */
-	-ERANGE,		/* BCME_RANGE */
-	-EINVAL,		/* BCME_NOTFOUND */
-	-EINVAL,		/* BCME_WME_NOT_ENABLED */
-	-EINVAL,		/* BCME_TSPEC_NOTFOUND */
-	-EINVAL,		/* BCME_ACM_NOTSUPPORTED */
-	-EINVAL,		/* BCME_NOT_WME_ASSOCIATION */
-	-EIO,			/* BCME_SDIO_ERROR */
-	-ENODEV,		/* BCME_DONGLE_DOWN */
-	-EINVAL,		/* BCME_VERSION */
-	-EIO,			/* BCME_TXFAIL */
-	-EIO,			/* BCME_RXFAIL */
-	-EINVAL,		/* BCME_NODEVICE */
-	-EINVAL,		/* BCME_NMODE_DISABLED */
-	-ENODATA,		/* BCME_NONRESIDENT */
-
-/* When an new error code is added to bcmutils.h, add os
- * spcecific error translation here as well
- */
-/* check if BCME_LAST changed since the last time this function was updated */
-#if BCME_LAST != -42
-#error "You need to add a OS error translation in the linuxbcmerrormap \
-	for new error code defined in bcmutils.h"
-#endif
-};
-
-/* translate bcmerrors into linux errors */
-int osl_error(int bcmerror)
-{
-	if (bcmerror > 0)
-		bcmerror = 0;
-	else if (bcmerror < BCME_LAST)
-		bcmerror = BCME_ERROR;
-
-	/* Array bounds covered by ASSERT in osl_attach */
-	return linuxbcmerrormap[-bcmerror];
-}
-#endif /* BRCM_FULLMAC */
-
-osl_t *osl_attach(void *pdev, uint bustype, bool pkttag)
+osl_t *osl_attach(void *pdev, uint bustype)
 {
 	osl_t *osh;
 
@@ -120,15 +54,8 @@
 
 	bzero(osh, sizeof(osl_t));
 
-#ifdef BRCM_FULLMAC
-	/* Check that error map has the right number of entries in it */
-	ASSERT(ABS(BCME_LAST) == (ARRAY_SIZE(linuxbcmerrormap) - 1));
-#endif /* BRCM_FULLMAC */
-
 	osh->magic = OS_HANDLE_MAGIC;
-	osh->failed = 0;
 	osh->pdev = pdev;
-	osh->pub.pkttag = pkttag;
 	osh->bustype = bustype;
 
 	switch (bustype) {
@@ -149,12 +76,6 @@
 		break;
 	}
 
-#if defined(BCMDBG) && !defined(BRCM_FULLMAC)
-	if (pkttag) {
-		struct sk_buff *skb;
-		ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb));
-	}
-#endif
 	return osh;
 }
 
@@ -167,7 +88,6 @@
 	kfree(osh);
 }
 
-/* Return a new packet. zero out pkttag */
 void *BCMFASTPATH osl_pktget(osl_t *osh, uint len)
 {
 	struct sk_buff *skb;
@@ -282,11 +202,6 @@
 	return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
 }
 
-uint osl_dma_consistent_align(void)
-{
-	return PAGE_SIZE;
-}
-
 void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align_bits,
 			       uint *alloced, unsigned long *pap)
 {
@@ -294,7 +209,7 @@
 
 	if (align_bits) {
 		u16 align = (1 << align_bits);
-		if (!IS_ALIGNED(DMA_CONSISTENT_ALIGN, align))
+		if (!IS_ALIGNED(PAGE_SIZE, align))
 			size += align;
 		*alloced = size;
 	}
diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c
index 23f86dd7..169a428 100644
--- a/drivers/staging/brcm80211/util/nicpci.c
+++ b/drivers/staging/brcm80211/util/nicpci.c
@@ -15,7 +15,7 @@
  */
 
 #include <linux/string.h>
-#include <linuxver.h>
+#include <linux/pci.h>
 #include <bcmdefs.h>
 #include <osl.h>
 #include <bcmutils.h>
diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c
index e4c0bab..82767e2 100644
--- a/drivers/staging/brcm80211/util/sbutils.c
+++ b/drivers/staging/brcm80211/util/sbutils.c
@@ -16,6 +16,9 @@
 
 #include <linux/types.h>
 #include <bcmdefs.h>
+#ifdef BRCM_FULLMAC
+#include <linux/netdevice.h>
+#endif
 #include <osl.h>
 #include <bcmutils.h>
 #include <siutils.h>
diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c
index f3ea7e1..3b99293 100644
--- a/drivers/staging/brcm80211/util/siutils.c
+++ b/drivers/staging/brcm80211/util/siutils.c
@@ -17,8 +17,12 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <bcmdefs.h>
+#ifdef BRCM_FULLMAC
+#include <linux/netdevice.h>
+#endif
 #include <osl.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
 #include <bcmutils.h>
 #include <siutils.h>
 #include <bcmdevs.h>
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 4a29ed7..ef24a53 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -470,10 +470,8 @@
 		struct page **pages = NULL;
 
 		async->buf_page_list =
-		    vmalloc(sizeof(struct comedi_buf_page) * n_pages);
+		    vzalloc(sizeof(struct comedi_buf_page) * n_pages);
 		if (async->buf_page_list) {
-			memset(async->buf_page_list, 0,
-			       sizeof(struct comedi_buf_page) * n_pages);
 			pages = vmalloc(sizeof(struct page *) * n_pages);
 		}
 		if (pages) {
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index 93d7c05..76f2483 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -2710,10 +2710,10 @@
 			} else {
 				outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
 			}
-			/*  Enable the interrupt for the controler */
+			/*  Enable the interrupt for the controller */
 			dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
 			outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
-			printk("\nEnable the interrupt for the controler");
+			printk("\nEnable the interrupt for the controller");
 		}
 		printk("\nRead Eeprom");
 		i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip,
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
index 912bc0f..a76ed25 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -225,7 +225,7 @@
 
 	devpriv->s_BoardInfos.b_BoardVersion = 1;
 
-	/*  Enable the interrupt for the controler */
+	/*  Enable the interrupt for the controller */
 	dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38);
 	outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38);
 
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index b943a06..a93e234 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -3011,7 +3011,7 @@
 
 	outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
 
-	/*  Enable the interrupt for the controler */
+	/*  Enable the interrupt for the controller */
 	dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
 	outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
 	outl(0, devpriv->i_IobaseAddon);	/* Resets the output */
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 60ebfc3..aa8aeee 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -753,7 +753,7 @@
 	struct comedi_subdevice *s;
 	struct pci_dev *pcidev;
 	int ret;
-	resource_size_t physLas0;	/* configuation */
+	resource_size_t physLas0;	/* configuration */
 	resource_size_t physLas1;	/* data area */
 	resource_size_t physLcfg;	/* PLX9080 */
 #ifdef USE_DMA
diff --git a/drivers/staging/cptm1217/Kconfig b/drivers/staging/cptm1217/Kconfig
new file mode 100644
index 0000000..f90545d
--- /dev/null
+++ b/drivers/staging/cptm1217/Kconfig
@@ -0,0 +1,11 @@
+config TOUCHSCREEN_CLEARPAD_TM1217
+	tristate "Synaptics Clearpad TM1217"
+	depends on I2C
+	depends on GPIOLIB
+	help
+	  Say Y here if you have a Synaptics Clearpad TM1217 Controller
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called clearpad_tm1217.
diff --git a/drivers/staging/cptm1217/Makefile b/drivers/staging/cptm1217/Makefile
new file mode 100644
index 0000000..8961faf
--- /dev/null
+++ b/drivers/staging/cptm1217/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= clearpad_tm1217.o
+
diff --git a/drivers/staging/cptm1217/TODO b/drivers/staging/cptm1217/TODO
new file mode 100644
index 0000000..3039224
--- /dev/null
+++ b/drivers/staging/cptm1217/TODO
@@ -0,0 +1,5 @@
+- Wait for the official upstream general clearpad drivers as promised over
+  the past few months
+- Merge any device support needed from this driver into it
+- Delete this driver
+
diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c
new file mode 100644
index 0000000..269503f
--- /dev/null
+++ b/drivers/staging/cptm1217/clearpad_tm1217.c
@@ -0,0 +1,675 @@
+/*
+ * clearpad_tm1217.c - Touch Screen driver for Synaptics Clearpad
+ * TM1217 controller
+ *
+ * Copyright (C) 2008 Intel Corp
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; ifnot, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Questions/Comments/Bug fixes to Ramesh Agarwal (ramesh.agarwal@intel.com)
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/timer.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include "cp_tm1217.h"
+
+#define CPTM1217_DEVICE_NAME		"cptm1217"
+#define CPTM1217_DRIVER_NAME		CPTM1217_DEVICE_NAME
+
+#define MAX_TOUCH_SUPPORTED		2
+#define TOUCH_SUPPORTED			1
+#define SAMPLING_FREQ			80	/* Frequency in HZ */
+#define DELAY_BTWIN_SAMPLE		(1000 / SAMPLING_FREQ)
+#define WAIT_FOR_RESPONSE		5	/* 5msec just works */
+#define MAX_RETRIES			5	/* As above */
+#define INCREMENTAL_DELAY		5	/* As above */
+
+/* Regster Definitions */
+#define TMA1217_DEV_STATUS		0x13	/* Device Status */
+#define TMA1217_INT_STATUS		0x14	/* Interrupt Status */
+
+/* Controller can detect upto 2 possible finger touches.
+ * Each finger touch provides  12 bit X Y co-ordinates, the values are split
+ * across 2 registers, and an 8 bit  Z value */
+#define TMA1217_FINGER_STATE		0x18 /* Finger State */
+#define TMA1217_FINGER1_X_HIGHER8	0x19 /* Higher 8 bit of X coordinate */
+#define TMA1217_FINGER1_Y_HIGHER8	0x1A /* Higher 8 bit of Y coordinate */
+#define TMA1217_FINGER1_XY_LOWER4	0x1B /* Lower 4 bits of X and Y */
+#define TMA1217_FINGER1_Z_VALUE		0x1D /* 8 bit Z value for finger 1 */
+#define TMA1217_FINGER2_X_HIGHER8	0x1E /* Higher 8 bit of X coordinate */
+#define TMA1217_FINGER2_Y_HIGHER8	0x1F /* Higher 8 bit of Y coordinate */
+#define TMA1217_FINGER2_XY_LOWER4	0x20 /* Lower 4 bits of X and Y */
+#define TMA1217_FINGER2_Z_VALUE		0x22 /* 8 bit Z value for finger 2 */
+#define TMA1217_DEVICE_CTRL		0x23 /* Device Control */
+#define TMA1217_INTERRUPT_ENABLE	0x24 /* Interrupt Enable */
+#define TMA1217_REPORT_MODE		0x2B /* Reporting Mode */
+#define TMA1217_MAX_X_LOWER8		0x31 /* Bit 0-7 for Max X */
+#define TMA1217_MAX_X_HIGHER4		0x32 /* Bit 8-11 for Max X */
+#define TMA1217_MAX_Y_LOWER8		0x33 /* Bit 0-7 for Max Y */
+#define TMA1217_MAX_Y_HIGHER4		0x34 /* Bit 8-11 for Max Y */
+#define TMA1217_DEVICE_CMD_RESET	0x67 /* Device CMD reg for reset */
+#define TMA1217_DEVICE_CMD_REZERO	0x69 /* Device CMD reg for rezero */
+
+#define TMA1217_MANUFACTURER_ID		0x73 /* Manufacturer Id */
+#define TMA1217_PRODUCT_FAMILY		0x75 /* Product Family */
+#define TMA1217_FIRMWARE_REVISION	0x76 /* Firmware Revision */
+#define TMA1217_SERIAL_NO_HIGH		0x7C /* Bit 8-15 of device serial no. */
+#define TMA1217_SERIAL_NO_LOW		0x7D /* Bit 0-7 of device serial no. */
+#define TMA1217_PRODUCT_ID_START	0x7E /* Start address for 10 byte ID */
+#define TMA1217_DEVICE_CAPABILITY	0x8B /* Reporting capability */
+
+
+/*
+ * The touch position structure.
+ */
+struct touch_state {
+	int	x;
+	int	y;
+	bool button;
+};
+
+/* Device Specific info given by the controller */
+struct cp_dev_info {
+	u16	maxX;
+	u16	maxY;
+};
+
+/* Vendor related info given by the controller */
+struct cp_vendor_info {
+	u8	vendor_id;
+	u8	product_family;
+	u8	firmware_rev;
+	u16	serial_no;
+};
+
+/*
+ * Private structure to store the device details
+ */
+struct cp_tm1217_device {
+	struct i2c_client	*client;
+	struct device		*dev;
+	struct cp_vendor_info	vinfo;
+	struct cp_dev_info	dinfo;
+	struct input_dev_info {
+		char			phys[32];
+		char			name[128];
+		struct input_dev	*input;
+		struct touch_state	touch;
+	} cp_input_info[MAX_TOUCH_SUPPORTED];
+
+	int	thread_running;
+	struct mutex	thread_mutex;
+
+	int gpio;
+};
+
+
+/* The following functions are used to read/write registers on the device
+ * as per the RMI prorocol. Technically, a page select should be written
+ * before doing read/write but since the register offsets are below 0xFF
+ * we can use the default value of page which is 0x00
+ */
+static int cp_tm1217_read(struct cp_tm1217_device *ts,
+				u8 *req, int size)
+{
+	int i, retval;
+
+	/* Send the address */
+	retval = i2c_master_send(ts->client, &req[0], 1);
+	if (retval != 1) {
+		dev_err(ts->dev, "cp_tm1217: I2C send failed\n");
+		return retval;
+	}
+	msleep(WAIT_FOR_RESPONSE);
+	for (i = 0; i < MAX_RETRIES; i++) {
+		retval = i2c_master_recv(ts->client, &req[1], size);
+		if (retval == size) {
+			break;
+		} else {
+			msleep(INCREMENTAL_DELAY);
+			dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i);
+		}
+	}
+	if (retval != size)
+		dev_err(ts->dev, "cp_tm1217: Read from device failed\n");
+
+	return retval;
+}
+
+static int cp_tm1217_write(struct cp_tm1217_device *ts,
+				u8 *req, int size)
+{
+	int retval;
+
+	/* Send the address and the data to be written */
+	retval = i2c_master_send(ts->client, &req[0], size + 1);
+	if (retval != size + 1) {
+		dev_err(ts->dev, "cp_tm1217: I2C write  failed: %d\n", retval);
+		return retval;
+	}
+	/* Wait for the write to complete. TBD why this is required */
+	msleep(WAIT_FOR_RESPONSE);
+
+	return size;
+}
+
+static int cp_tm1217_mask_interrupt(struct cp_tm1217_device *ts)
+{
+	u8 req[2];
+	int retval;
+
+	req[0] = TMA1217_INTERRUPT_ENABLE;
+	req[1] = 0x0;
+	retval = cp_tm1217_write(ts, req, 1);
+	if (retval != 1)
+		return -EIO;
+
+	return 0;
+}
+
+static int cp_tm1217_unmask_interrupt(struct cp_tm1217_device *ts)
+{
+	u8 req[2];
+	int retval;
+
+	req[0] = TMA1217_INTERRUPT_ENABLE;
+	req[1] = 0xa;
+	retval = cp_tm1217_write(ts, req, 1);
+	if (retval != 1)
+		return -EIO;
+
+	return 0;
+}
+
+static void process_touch(struct cp_tm1217_device *ts, int index)
+{
+	int retval;
+	struct input_dev_info *input_info =
+		(struct input_dev_info *)&ts->cp_input_info[index];
+	u8 xy_data[6];
+
+	if (index == 0)
+		xy_data[0] = TMA1217_FINGER1_X_HIGHER8;
+	else
+		xy_data[0] = TMA1217_FINGER2_X_HIGHER8;
+
+	retval = cp_tm1217_read(ts, xy_data, 5);
+	if (retval < 5) {
+		dev_err(ts->dev, "cp_tm1217: XY read from device failed\n");
+		return;
+	}
+
+	/* Note: Currently not using the Z values but may be requried in
+	   the future. */
+	input_info->touch.x = (xy_data[1] << 4)
+					| (xy_data[3] & 0x0F);
+	input_info->touch.y = (xy_data[2] << 4)
+					| ((xy_data[3] & 0xF0) >> 4);
+	input_report_abs(input_info->input, ABS_X, input_info->touch.x);
+	input_report_abs(input_info->input, ABS_Y, input_info->touch.y);
+	input_sync(input_info->input);
+}
+
+static void cp_tm1217_get_data(struct cp_tm1217_device *ts)
+{
+	u8 req[2];
+	int retval, i, finger_touched = 0;
+
+	do {
+		req[0] = TMA1217_FINGER_STATE;
+		retval = cp_tm1217_read(ts, req, 1);
+		if (retval != 1) {
+			dev_err(ts->dev,
+				"cp_tm1217: Read from device failed\n");
+			continue;
+		}
+		finger_touched = 0;
+		/* Start sampling until the pressure is below
+		  threshold */
+		for (i = 0; i < TOUCH_SUPPORTED; i++) {
+			if (req[1] & 0x3) {
+				finger_touched++;
+				if (ts->cp_input_info[i].touch.button == 0) {
+					/* send the button touch event */
+					input_report_key(
+						ts->cp_input_info[i].input,
+						BTN_TOUCH, 1);
+					ts->cp_input_info[i].touch.button = 1;
+				}
+				process_touch(ts, i);
+			} else {
+				if (ts->cp_input_info[i].touch.button == 1) {
+					/* send the button release event */
+					input_report_key(
+						ts->cp_input_info[i].input,
+						BTN_TOUCH, 0);
+					input_sync(ts->cp_input_info[i].input);
+					ts->cp_input_info[i].touch.button = 0;
+				}
+			}
+			req[1] = req[1] >> 2;
+		}
+		msleep(DELAY_BTWIN_SAMPLE);
+	} while (finger_touched > 0);
+}
+
+static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle)
+{
+	struct cp_tm1217_device *ts = (struct cp_tm1217_device *) handle;
+	u8 req[2];
+	int retval;
+
+	/* Chedk if another thread is already running */
+	mutex_lock(&ts->thread_mutex);
+	if (ts->thread_running == 1) {
+		mutex_unlock(&ts->thread_mutex);
+		return IRQ_HANDLED;
+	} else {
+		ts->thread_running = 1;
+		mutex_unlock(&ts->thread_mutex);
+	}
+
+	/* Mask the interrupts */
+	retval = cp_tm1217_mask_interrupt(ts);
+
+	/* Read the Interrupt Status register to find the cause of the
+	   Interrupt */
+	req[0] = TMA1217_INT_STATUS;
+	retval = cp_tm1217_read(ts, req, 1);
+	if (retval != 1)
+		goto exit_thread;
+
+	if (!(req[1] & 0x8))
+		goto exit_thread;
+
+	cp_tm1217_get_data(ts);
+
+exit_thread:
+	/* Unmask the interrupts before going to sleep */
+	retval = cp_tm1217_unmask_interrupt(ts);
+
+	mutex_lock(&ts->thread_mutex);
+	ts->thread_running = 0;
+	mutex_unlock(&ts->thread_mutex);
+
+	return IRQ_HANDLED;
+}
+
+static int cp_tm1217_init_data(struct cp_tm1217_device *ts)
+{
+	int retval;
+	u8	req[2];
+
+	/* Read the vendor id/ fw revision etc. Ignoring return check as this
+	   is non critical info  */
+	req[0] = TMA1217_MANUFACTURER_ID;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->vinfo.vendor_id = req[1];
+
+	req[0] = TMA1217_PRODUCT_FAMILY;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->vinfo.product_family = req[1];
+
+	req[0] = TMA1217_FIRMWARE_REVISION;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->vinfo.firmware_rev = req[1];
+
+	req[0] = TMA1217_SERIAL_NO_HIGH;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->vinfo.serial_no = (req[1] << 8);
+
+	req[0] = TMA1217_SERIAL_NO_LOW;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->vinfo.serial_no = ts->vinfo.serial_no | req[1];
+
+	req[0] = TMA1217_MAX_X_HIGHER4;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->dinfo.maxX = (req[1] & 0xF) << 8;
+
+	req[0] = TMA1217_MAX_X_LOWER8;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->dinfo.maxX = ts->dinfo.maxX | req[1];
+
+	req[0] = TMA1217_MAX_Y_HIGHER4;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->dinfo.maxY = (req[1] & 0xF) << 8;
+
+	req[0] = TMA1217_MAX_Y_LOWER8;
+	retval = cp_tm1217_read(ts, req, 1);
+	ts->dinfo.maxY = ts->dinfo.maxY | req[1];
+
+	return 0;
+
+}
+
+/*
+ *	Set up a GPIO for use as the interrupt. We can't simply do this at
+ *	boot time because the GPIO drivers themselves may not be around at
+ *	boot/firmware set up time to do the work. Instead defer it to driver
+ *	detection.
+ */
+
+static int cp_tm1217_setup_gpio_irq(struct cp_tm1217_device *ts)
+{
+	int retval;
+
+	/* Hook up the irq handler */
+	retval = gpio_request(ts->gpio, "cp_tm1217_touch");
+	if (retval < 0) {
+		dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n",
+								retval);
+		return retval;
+	}
+
+	retval = gpio_direction_input(ts->gpio);
+	if (retval < 0) {
+		dev_err(ts->dev,
+		"cp_tm1217: GPIO direction configuration failed, error %d\n",
+								retval);
+		gpio_free(ts->gpio);
+		return retval;
+	}
+
+	retval = gpio_to_irq(ts->gpio);
+	if (retval < 0) {
+		dev_err(ts->dev, "cp_tm1217: GPIO to IRQ failedi,"
+		" error %d\n", retval);
+		gpio_free(ts->gpio);
+	}
+	dev_dbg(ts->dev,
+		"cp_tm1217: Got IRQ number is %d for GPIO %d\n",
+		retval, ts->gpio);
+	return retval;
+}
+
+static int cp_tm1217_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct cp_tm1217_device *ts;
+	struct input_dev *input_dev;
+	struct input_dev_info	*input_info;
+	struct cp_tm1217_platform_data *pdata;
+	u8 req[2];
+	int i, retval;
+
+	/* No pdata is fine - we then use "normal" IRQ mode */
+
+	pdata = client->dev.platform_data;
+
+	ts = kzalloc(sizeof(struct cp_tm1217_device), GFP_KERNEL);
+	if (!ts) {
+		dev_err(&client->dev,
+			"cp_tm1217: Private Device Struct alloc failed\n");
+		return -ENOMEM;
+	}
+
+	ts->client = client;
+	ts->dev = &client->dev;
+	i2c_set_clientdata(client, ts);
+
+	ts->thread_running = 0;
+	mutex_init(&ts->thread_mutex);
+
+	/* Reset the Controller */
+	req[0] = TMA1217_DEVICE_CMD_RESET;
+	req[1] = 0x1;
+	retval = cp_tm1217_write(ts, req, 1);
+	if (retval != 1) {
+		dev_err(ts->dev, "cp_tm1217: Controller reset failed\n");
+		kfree(ts);
+		return -EIO;
+	}
+
+	/* Clear up the interrupt status from reset. */
+	req[0] = TMA1217_INT_STATUS;
+	retval = cp_tm1217_read(ts, req, 1);
+
+	/* Mask all the interrupts */
+	retval = cp_tm1217_mask_interrupt(ts);
+
+	/* Read the controller information */
+	cp_tm1217_init_data(ts);
+
+	/* The following code will register multiple event devices when
+	   multi-pointer is enabled, the code has not been tested
+	   with MPX */
+	for (i = 0; i < TOUCH_SUPPORTED; i++) {
+		input_dev = input_allocate_device();
+		if (input_dev == NULL) {
+			kfree(ts);
+			dev_err(ts->dev,
+				"cp_tm1217:Input Device Struct alloc failed\n");
+			return -ENOMEM;
+		}
+		input_info = &ts->cp_input_info[i];
+		snprintf(input_info->name, sizeof(input_info->name),
+			"cp_tm1217_touchscreen_%d", i);
+		input_dev->name = input_info->name;
+		snprintf(input_info->phys, sizeof(input_info->phys),
+			"%s/input%d", dev_name(&client->dev), i);
+
+		input_dev->phys = input_info->phys;
+		input_dev->id.bustype = BUS_I2C;
+
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+		input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+		input_set_abs_params(input_dev, ABS_X, 0, ts->dinfo.maxX, 0, 0);
+		input_set_abs_params(input_dev, ABS_Y, 0, ts->dinfo.maxY, 0, 0);
+
+		retval = input_register_device(input_dev);
+		if (retval) {
+			dev_err(ts->dev,
+				"Input dev registration failed for %s\n",
+					input_dev->name);
+			goto fail;
+		}
+		input_info->input = input_dev;
+	}
+
+	/* Setup the reporting mode to send an interrupt only when
+	   finger arrives or departs. */
+	req[0] = TMA1217_REPORT_MODE;
+	req[1] = 0x02;
+	retval = cp_tm1217_write(ts, req, 1);
+
+	/* Setup the device to no sleep mode for now and make it configured */
+	req[0] = TMA1217_DEVICE_CTRL;
+	req[1] = 0x84;
+	retval = cp_tm1217_write(ts, req, 1);
+
+	/* Check for the status of the device */
+	req[0] = TMA1217_DEV_STATUS;
+	retval = cp_tm1217_read(ts, req, 1);
+	if (req[1] != 0) {
+		dev_err(ts->dev,
+			"cp_tm1217: Device Status 0x%x != 0: config failed\n",
+			req[1]);
+
+		retval = -EIO;
+		goto fail;
+	}
+
+	if (pdata && pdata->gpio) {
+		ts->gpio = pdata->gpio;
+		retval = cp_tm1217_setup_gpio_irq(ts);
+	} else
+		retval = client->irq;
+
+	if (retval < 0) {
+		dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n",
+								retval);
+		goto fail;
+	}
+
+	client->irq = retval;
+
+
+	retval = request_threaded_irq(client->irq,
+		NULL, cp_tm1217_sample_thread,
+		IRQF_TRIGGER_FALLING, "cp_tm1217_touch", ts);
+	if (retval < 0) {
+		dev_err(ts->dev, "cp_tm1217: Request IRQ error %d\n", retval);
+		goto fail_gpio;
+	}
+
+	/* Unmask the interrupts */
+	retval = cp_tm1217_unmask_interrupt(ts);
+	if (retval == 0)
+		return 0;
+
+	free_irq(client->irq, ts);
+fail_gpio:
+	if (ts->gpio)
+		gpio_free(ts->gpio);
+fail:
+	/* Clean up before returning failure */
+	for (i = 0; i < TOUCH_SUPPORTED; i++) {
+		if (ts->cp_input_info[i].input) {
+			input_unregister_device(ts->cp_input_info[i].input);
+			input_free_device(ts->cp_input_info[i].input);
+		}
+	}
+	kfree(ts);
+	return retval;
+
+}
+
+/*
+ * cp_tm1217 suspend
+ *
+ */
+static int cp_tm1217_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct cp_tm1217_device *ts = i2c_get_clientdata(client);
+	u8 req[2];
+	int retval;
+
+	/* Put the controller to sleep */
+	req[0] = TMA1217_DEVICE_CTRL;
+	retval = cp_tm1217_read(ts, req, 1);
+	req[1] = (req[1] & 0xF8) | 0x1;
+	retval = cp_tm1217_write(ts, req, 1);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(client->irq);
+
+	return 0;
+}
+
+/*
+ * cp_tm1217_resume
+ *
+ */
+static int cp_tm1217_resume(struct i2c_client *client)
+{
+	struct cp_tm1217_device *ts = i2c_get_clientdata(client);
+	u8 req[2];
+	int retval;
+
+	/* Take the controller out of sleep */
+	req[0] = TMA1217_DEVICE_CTRL;
+	retval = cp_tm1217_read(ts, req, 1);
+	req[1] = (req[1] & 0xF8) | 0x4;
+	retval = cp_tm1217_write(ts, req, 1);
+
+	/* Restore the register settings sinc the power to the
+	   could have been cut off */
+
+	/* Setup the reporting mode to send an interrupt only when
+	   finger arrives or departs. */
+	req[0] = TMA1217_REPORT_MODE;
+	req[1] = 0x02;
+	retval = cp_tm1217_write(ts, req, 1);
+
+	/* Setup the device to no sleep mode for now and make it configured */
+	req[0] = TMA1217_DEVICE_CTRL;
+	req[1] = 0x84;
+	retval = cp_tm1217_write(ts, req, 1);
+
+	/* Setup the interrupt mask */
+	retval = cp_tm1217_unmask_interrupt(ts);
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(client->irq);
+
+	return 0;
+}
+
+/*
+ * cp_tm1217_remove
+ *
+ */
+static int cp_tm1217_remove(struct i2c_client *client)
+{
+	struct cp_tm1217_device *ts = i2c_get_clientdata(client);
+	int i;
+
+	free_irq(client->irq, ts);
+	if (ts->gpio)
+		gpio_free(ts->gpio);
+	for (i = 0; i < TOUCH_SUPPORTED; i++)
+		input_unregister_device(ts->cp_input_info[i].input);
+	kfree(ts);
+	return 0;
+}
+
+static struct i2c_device_id cp_tm1217_idtable[] = {
+	{ CPTM1217_DEVICE_NAME, 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, cp_tm1217_idtable);
+
+static struct i2c_driver cp_tm1217_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= CPTM1217_DRIVER_NAME,
+	},
+	.id_table	= cp_tm1217_idtable,
+	.probe		= cp_tm1217_probe,
+	.remove		= cp_tm1217_remove,
+	.suspend    = cp_tm1217_suspend,
+	.resume     = cp_tm1217_resume,
+};
+
+static int __init clearpad_tm1217_init(void)
+{
+	return i2c_add_driver(&cp_tm1217_driver);
+}
+
+static void __exit clearpad_tm1217_exit(void)
+{
+	i2c_del_driver(&cp_tm1217_driver);
+}
+
+module_init(clearpad_tm1217_init);
+module_exit(clearpad_tm1217_exit);
+
+MODULE_AUTHOR("Ramesh Agarwal <ramesh.agarwal@intel.com>");
+MODULE_DESCRIPTION("Synaptics TM1217 TouchScreen Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/cptm1217/cp_tm1217.h b/drivers/staging/cptm1217/cp_tm1217.h
new file mode 100644
index 0000000..a0ce31d
--- /dev/null
+++ b/drivers/staging/cptm1217/cp_tm1217.h
@@ -0,0 +1,9 @@
+#ifndef __LINUX_I2C_CP_TM1217_H
+#define __LINUX_I2C_CP_TM1217_H
+
+struct cp_tm1217_platform_data
+{
+	int gpio;		/* If not set uses the IRQ resource 0 */
+};
+
+#endif
diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig
index 9d5fe4d..bd96f39 100644
--- a/drivers/staging/easycap/Kconfig
+++ b/drivers/staging/easycap/Kconfig
@@ -1,7 +1,6 @@
 config EASYCAP
 	tristate "EasyCAP USB ID 05e1:0408 support"
 	depends on USB && VIDEO_DEV
-	depends on BKL # please fix
 
 	---help---
 	  This is an integrated audio/video driver for EasyCAP cards with
diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile
index 8a3d911..f1f2fbe 100644
--- a/drivers/staging/easycap/Makefile
+++ b/drivers/staging/easycap/Makefile
@@ -10,4 +10,5 @@
 ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT
 ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H
 ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS
+ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL
 
diff --git a/drivers/staging/easycap/README b/drivers/staging/easycap/README
index 3775481..6b5ac0d 100644
--- a/drivers/staging/easycap/README
+++ b/drivers/staging/easycap/README
@@ -24,6 +24,9 @@
 BUILD OPTIONS AND DEPENDENCIES
 ------------------------------
 
+Unless EASYCAP_DEBUG is defined during compilation it will not be possible
+to select a debug level at the time of module installation.
+
 If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation
 the built module is entirely independent of the videodev module, and when
 the EasyCAP is physically plugged into a USB port the special files
@@ -33,41 +36,54 @@
 If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation
 the built easycap module is configured to register with the videodev module,
 in which case the special files created when the EasyCAP is plugged in are
-/dev/video0 and /dev/easysnd0.  Use of the easycap module as a client of
-the videodev module has received very little testing as of June 2010.
+/dev/video0 and /dev/easysnd0.
 
+During in-tree builds the following should should be defined whenever the
+parameter EASYCAP_IS_VIDEODEV_CLIENT is defined:
 
-KNOWN BUILD PROBLEMS
---------------------
+EASYCAP_NEEDS_V4L2_DEVICE_H
+EASYCAP_NEEDS_V4L2_FOPS
+EASYCAP_NEEDS_UNLOCKED_IOCTL
 
-(1) Recent gcc versions may generate the message:
-
-     warning: the frame size of .... bytes is larger than 1024 bytes
-
-This warning can be suppressed by specifying in the Makefile:
-
-     EXTRA_CFLAGS += -Wframe-larger-than=8192
-
-but it would be preferable to remove the cause of the warning.
+If the build is performed out-of-tree against older kernels the parameters
+to be defined depend on the kernel version in a way which will not be
+discussed here.
 
 
 KNOWN RUNTIME ISSUES
 --------------------
 
-(1) Randomly (maybe 5 to 10% of occasions) the driver fails to produce any
-output at start-up.  Closing mplayer (or whatever the user program is) and
-restarting it restores normal performance without any other remedial action
-being necessary.  The reason for this is not known.
+(1) Intentionally, this driver will not stream material which is unambiguously
+identified by the hardware as copy-protected.  Normal video output will be
+present for about a minute but will then freeze when this situation arises.
 
-(2) Intentionally, this driver will not stream material which is unambiguously
-identified by the hardware as copy-protected.  The video output will freeze
-within about a minute when this situation arises.
-
-(3) The controls for luminance, contrast, saturation, hue and volume may not
+(2) The controls for luminance, contrast, saturation, hue and volume may not
 always work properly.
 
-(4) Reduced-resolution S-Video seems to suffer from moire artefacts.  No
-attempt has yet been made to rememdy this.
+(3) Reduced-resolution S-Video seems to suffer from moire artefacts.
+
+
+INPUT NUMBERING
+---------------
+
+For the EasyCAP with S-VIDEO input cable the driver regards a request for
+inputs numbered 0 or 1 as referring to CVBS and a request for input
+numbered 5 as referring to S-VIDEO.
+
+For the EasyCAP with four CVBS inputs the driver expects to be asked for
+any one of inputs numbered 1,2,3,4.  If input 0 is asked for, it is
+interpreted as input 1.
+
+
+MODULE PARAMETERS
+-----------------
+
+Three module parameters are defined:
+
+debug      the easycap module is configured at diagnostic level n (0 to 9)
+gain       audio gain level n (0 to 31, default is 16)
+bars       0 =>  testcard bars when incoming video signal is lost
+           1 =>  testcard bars when incoming video signal is lost (default)
 
 
 SUPPORTED TV STANDARDS AND RESOLUTIONS
@@ -82,18 +98,29 @@
     PAL_60,       NTSC_443,
     PAL_M.
 
+In addition, the driver offers "custom" pseudo-standards with a framerate
+which is 20% of the usual framerate.  These pseudo-standards are named:
+
+    PAL_BGHIN_SLOW,    NTSC_N_443_SLOW,
+    PAL_Nc_SLOW,       NTSC_N_SLOW,
+    SECAM_SLOW,        NTSC_M_SLOW,        NTSC_M_JP_SLOW,
+    PAL_60_SLOW,       NTSC_443_SLOW,
+    PAL_M_SLOW.
+
+
 The available picture sizes are:
 
      at 25 frames per second:   720x576, 704x576, 640x480, 360x288, 320x240;
-     at 30 frames per second:   720x480, 640x480, 360x240, 320x240;
+     at 30 frames per second:   720x480, 640x480, 360x240, 320x240.
 
 
 WHAT'S TESTED AND WHAT'S NOT
 ----------------------------
 
-This driver is known to work with mplayer, mencoder, tvtime and sufficiently
-recent versions of vlc.  An interface to ffmpeg is implemented, but serious
-audio-video synchronization problems remain.
+This driver is known to work with mplayer, mencoder, tvtime, zoneminder,
+xawtv, gstreamer and sufficiently recent versions of vlc.  An interface
+to ffmpeg is implemented, but serious audio-video synchronization problems
+remain.
 
 The driver is designed to support all the TV standards accepted by the
 hardware, but as yet it has actually been tested on only a few of these.
@@ -101,10 +128,7 @@
 I have been unable to test and calibrate the S-video input myself because I
 do not possess any equipment with S-video output.
 
-This driver does not understand the V4L1 IOCTL commands, so programs such
-as camorama are not compatible.  There are reports that the driver does
-work with sufficiently recent (V4L2) versions of zoneminder, but I have not
-attempted to confirm this myself.
+This driver does not understand the V4L1 IOCTL commands.
 
 
 UDEV RULES
@@ -120,6 +144,17 @@
 LABEL="easycap_rules_end"
 
 
+MODPROBE CONFIGURATION
+----------------------
+
+The easycap module is in competition with the module snd-usb-audio for the
+EasyCAP's audio channel, and its installation can be aided by providing a
+file in directory /etc/modprobe.d with content:
+
+options easycap  gain=16 bars=1
+install easycap /sbin/rmmod snd-usb-audio; /sbin/modprobe --ignore-install easycap
+
+
 ACKNOWLEGEMENTS AND REFERENCES
 ------------------------------
 This driver makes use of information contained in the Syntek Semicon DC-1125
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h
index f3c827e..cc8e8c5 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/easycap/easycap.h
@@ -33,6 +33,7 @@
  *                EASYCAP_NEEDS_USBVIDEO_H
  *                EASYCAP_NEEDS_V4L2_DEVICE_H
  *                EASYCAP_NEEDS_V4L2_FOPS
+ *                EASYCAP_NEEDS_UNLOCKED_IOCTL
  *
  *  IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
  *  OPTIONS.
@@ -42,35 +43,24 @@
 #if (!defined(EASYCAP_H))
 #define EASYCAP_H
 
-#if defined(EASYCAP_DEBUG)
-#if (9 < EASYCAP_DEBUG)
-#error Debug levels 0 to 9 are okay.\
-  To achieve higher levels, remove this trap manually from easycap.h
-#endif
-#endif /*EASYCAP_DEBUG*/
+/*---------------------------------------------------------------------------*/
+/*
+ *  THESE ARE NORMALLY DEFINED
+ */
+/*---------------------------------------------------------------------------*/
+#define  PATIENCE  500
+#undef   PREFER_NTSC
+#define  PERSEVERE
 /*---------------------------------------------------------------------------*/
 /*
  *  THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED:
  */
 /*---------------------------------------------------------------------------*/
-#undef  PREFER_NTSC
 #undef  EASYCAP_TESTCARD
 #undef  EASYCAP_TESTTONE
-#undef  LOCKFRAME
 #undef  NOREADBACK
 #undef  AUDIOTIME
 /*---------------------------------------------------------------------------*/
-/*
- *
- *  DEFINE   BRIDGER   TO ACTIVATE THE ROUTINE FOR BRIDGING VIDEOTAPE DROPOUTS.
- *
- *             *** UNDER DEVELOPMENT/TESTING - NOT READY YET!***
- *
- */
-/*---------------------------------------------------------------------------*/
-#undef  BRIDGER
-/*---------------------------------------------------------------------------*/
-
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -92,25 +82,14 @@
 
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
-#if (!defined(__OLD_VIDIOC_))
-#define __OLD_VIDIOC_
-#endif /* !defined(__OLD_VIDIOC_) */
-
 #include <media/v4l2-dev.h>
-
 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
 #include <media/v4l2-device.h>
 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
-#if (!defined(__OLD_VIDIOC_))
-#define __OLD_VIDIOC_
-#endif /* !defined(__OLD_VIDIOC_) */
 #include <linux/videodev2.h>
-
 #include <linux/soundcard.h>
-
 #if defined(EASYCAP_NEEDS_USBVIDEO_H)
 #include <config/video/usbvideo.h>
 #endif /*EASYCAP_NEEDS_USBVIDEO_H*/
@@ -121,7 +100,6 @@
 
 #define STRINGIZE_AGAIN(x) #x
 #define STRINGIZE(x) STRINGIZE_AGAIN(x)
-
 /*---------------------------------------------------------------------------*/
 /*  VENDOR, PRODUCT:  Syntek Semiconductor Co., Ltd
  *
@@ -135,12 +113,12 @@
 #define USB_EASYCAP_VENDOR_ID	0x05e1
 #define USB_EASYCAP_PRODUCT_ID	0x0408
 
-#define EASYCAP_DRIVER_VERSION "0.8.21"
+#define EASYCAP_DRIVER_VERSION "0.8.41"
 #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
 
 #define USB_SKEL_MINOR_BASE     192
-#define VIDEO_DEVICE_MANY 8
-
+#define DONGLE_MANY 8
+#define INPUT_MANY 6
 /*---------------------------------------------------------------------------*/
 /*
  *  DEFAULT LUMINANCE, CONTRAST, SATURATION AND HUE
@@ -164,6 +142,8 @@
 #if (USB_2_0_MAXPACKETSIZE > PAGE_SIZE)
 #error video_isoc_buffer[.] will not be big enough
 #endif
+#define VIDEO_JUNK_TOLERATE VIDEO_ISOC_BUFFER_MANY
+#define VIDEO_LOST_TOLERATE 50
 /*---------------------------------------------------------------------------*/
 /*
  *  VIDEO BUFFERS
@@ -210,7 +190,17 @@
 #define  NTSC_M_JP      5
 #define  PAL_60         7
 #define  PAL_M          9
-#define  STANDARD_MANY 10
+#define  PAL_BGHIN_SLOW    10
+#define  PAL_Nc_SLOW       12
+#define  SECAM_SLOW        14
+#define  NTSC_N_SLOW       16
+#define  NTSC_N_443_SLOW   18
+#define  NTSC_M_SLOW       11
+#define  NTSC_443_SLOW     13
+#define  NTSC_M_JP_SLOW    15
+#define  PAL_60_SLOW       17
+#define  PAL_M_SLOW        19
+#define  STANDARD_MANY 20
 /*---------------------------------------------------------------------------*/
 /*
  *  ENUMS
@@ -238,7 +228,6 @@
 enum {
 FIELD_NONE,
 FIELD_INTERLACED,
-FIELD_ALTERNATE,
 INTERLACE_MANY
 };
 #define SETTINGS_MANY	(STANDARD_MANY * \
@@ -251,11 +240,18 @@
  *  STRUCTURE DEFINITIONS
  */
 /*---------------------------------------------------------------------------*/
+struct easycap_dongle {
+struct easycap *peasycap;
+struct mutex mutex_video;
+struct mutex mutex_audio;
+};
+/*---------------------------------------------------------------------------*/
 struct data_buffer {
 struct list_head list_head;
 void *pgo;
 void *pto;
 __u16 kount;
+__u16 input;
 };
 /*---------------------------------------------------------------------------*/
 struct data_urb {
@@ -274,6 +270,22 @@
 char name[128];
 struct v4l2_format v4l2_format;
 };
+struct inputset {
+int input;
+int input_ok;
+int standard_offset;
+int standard_offset_ok;
+int format_offset;
+int format_offset_ok;
+int brightness;
+int brightness_ok;
+int contrast;
+int contrast_ok;
+int saturation;
+int saturation_ok;
+int hue;
+int hue_ok;
+};
 /*---------------------------------------------------------------------------*/
 /*
  *   easycap.ilk == 0   =>  CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=256
@@ -282,6 +294,19 @@
  */
 /*---------------------------------------------------------------------------*/
 struct easycap {
+#define TELLTALE "expectedstring"
+char telltale[16];
+int isdongle;
+
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+struct video_device video_device;
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+struct v4l2_device v4l2_device;
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+int status;
 unsigned int audio_pages_per_fragment;
 unsigned int audio_bytes_per_fragment;
 unsigned int audio_buffer_page_many;
@@ -291,26 +316,14 @@
 __s16 oldaudio;
 #endif /*UPSAMPLE*/
 
-struct easycap_format easycap_format[1 + SETTINGS_MANY];
-
 int ilk;
 bool microphone;
 
-/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
-#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
-struct video_device *pvideo_device;
-#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
 struct usb_device *pusb_device;
 struct usb_interface *pusb_interface;
 
 struct kref kref;
 
-struct mutex mutex_mmap_video[FRAME_BUFFER_MANY];
-struct mutex mutex_timeval0;
-struct mutex mutex_timeval1;
-
 int queued[FRAME_BUFFER_MANY];
 int done[FRAME_BUFFER_MANY];
 
@@ -321,16 +334,24 @@
 int polled;
 int standard_offset;
 int format_offset;
+struct inputset inputset[INPUT_MANY];
 
+bool ntsc;
 int fps;
 int usec;
 int tolerate;
+int skip;
+int skipped;
+int lost[INPUT_MANY];
 int merit[180];
 
 struct timeval timeval0;
 struct timeval timeval1;
 struct timeval timeval2;
+struct timeval timeval3;
+struct timeval timeval6;
 struct timeval timeval7;
+struct timeval timeval8;
 long long int dnbydt;
 
 int    video_interface;
@@ -347,8 +368,6 @@
 int    video_eof;
 int    video_junk;
 
-int    fudge;
-
 struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY];
 struct data_buffer \
 	     field_buffer[FIELD_BUFFER_MANY][(FIELD_BUFFER_SIZE/PAGE_SIZE)];
@@ -358,6 +377,13 @@
 struct list_head urb_video_head;
 struct list_head *purb_video_head;
 
+__u8 cache[8];
+__u8 *pcache;
+int video_mt;
+int audio_mt;
+long long audio_bytes;
+__u32 isequence;
+
 int vma_many;
 
 /*---------------------------------------------------------------------------*/
@@ -383,7 +409,6 @@
  */
 /*---------------------------------------------------------------------------*/
 __u32                   pixelformat;
-__u32                   field;
 int                     width;
 int                     height;
 int                     bytesperpixel;
@@ -463,8 +488,10 @@
 void             easycap_complete(struct urb *);
 int              easycap_open(struct inode *, struct file *);
 int              easycap_release(struct inode *, struct file *);
-long             easycap_ioctl(struct file *, unsigned int,  unsigned long);
-
+long             easycap_ioctl_noinode(struct file *, unsigned int, \
+								unsigned long);
+int              easycap_ioctl(struct inode *, struct file *, unsigned int, \
+								unsigned long);
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
 int              easycap_open_noinode(struct file *);
@@ -489,12 +516,10 @@
 int              field2frame(struct easycap *);
 int              redaub(struct easycap *, void *, void *, \
 						int, int, __u8, __u8, bool);
-void             debrief(struct easycap *);
-void             sayreadonly(struct easycap *);
 void             easycap_testcard(struct easycap *, int);
-int              explain_ioctl(__u32);
-int              explain_cid(__u32);
 int              fillin_formats(void);
+int              reset(struct easycap *);
+int              newinput(struct easycap *, int);
 int              adjust_standard(struct easycap *, v4l2_std_id);
 int              adjust_format(struct easycap *, __u32, __u32, __u32, \
 								int, bool);
@@ -512,7 +537,10 @@
 ssize_t          easysnd_read(struct file *, char __user *, size_t, loff_t *);
 int              easysnd_open(struct inode *, struct file *);
 int              easysnd_release(struct inode *, struct file *);
-long             easysnd_ioctl(struct file *, unsigned int,  unsigned long);
+long             easysnd_ioctl_noinode(struct file *, unsigned int, \
+								unsigned long);
+int              easysnd_ioctl(struct inode *, struct file *, unsigned int, \
+								unsigned long);
 unsigned int     easysnd_poll(struct file *, poll_table *);
 void             easysnd_delete(struct kref *);
 int              submit_audio_urbs(struct easycap *);
@@ -532,11 +560,11 @@
 int              confirm_resolution(struct usb_device *);
 int              confirm_stream(struct usb_device *);
 
-int              setup_stk(struct usb_device *);
-int              setup_saa(struct usb_device *);
+int              setup_stk(struct usb_device *, bool);
+int              setup_saa(struct usb_device *, bool);
 int              setup_vt(struct usb_device *);
-int              check_stk(struct usb_device *);
-int              check_saa(struct usb_device *);
+int              check_stk(struct usb_device *, bool);
+int              check_saa(struct usb_device *, bool);
 int              ready_saa(struct usb_device *);
 int              merit_saa(struct usb_device *);
 int              check_vt(struct usb_device *);
@@ -554,12 +582,9 @@
 int              write_300(struct usb_device *);
 int              read_vt(struct usb_device *, __u16);
 int              write_vt(struct usb_device *, __u16, __u16);
-
-int              set2to78(struct usb_device *);
-int              set2to93(struct usb_device *);
-
 int              regset(struct usb_device *, __u16, __u16);
 int              regget(struct usb_device *, __u16, void *);
+int		isdongle(struct easycap *);
 /*---------------------------------------------------------------------------*/
 struct signed_div_result {
 long long int quotient;
@@ -587,24 +612,41 @@
 	} \
 } while (0)
 /*---------------------------------------------------------------------------*/
-
+/*
+ *  MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH
+ *  THE IDENTITY OF THE DONGLE TO WHICH IT APPLIES, BUT IF INVOKED WHEN THE
+ *  POINTER peasycap IS INVALID AN Oops IS LIKELY, AND ITS CAUSE MAY NOT BE
+ *  IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE.  BEWARE.
+*/
+/*---------------------------------------------------------------------------*/
 #define SAY(format, args...) do { \
-	printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \
+	printk(KERN_DEBUG "easycap:: %s: " \
+			format, __func__, ##args); \
 } while (0)
-
+#define SAM(format, args...) do { \
+	printk(KERN_DEBUG "easycap::%i%s: " \
+			format, peasycap->isdongle, __func__, ##args);\
+} while (0)
 
 #if defined(EASYCAP_DEBUG)
 #define JOT(n, format, args...) do { \
-	if (n <= easycap_debug) { \
-		printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \
+	if (n <= debug) { \
+		printk(KERN_DEBUG "easycap:: %s: " \
+			format, __func__, ##args);\
 	} \
 } while (0)
+#define JOM(n, format, args...) do { \
+	if (n <= debug) { \
+		printk(KERN_DEBUG "easycap::%i%s: " \
+			format, peasycap->isdongle, __func__, ##args);\
+	} \
+} while (0)
+
 #else
 #define JOT(n, format, args...) do {} while (0)
+#define JOM(n, format, args...) do {} while (0)
 #endif /*EASYCAP_DEBUG*/
 
-#define POUT JOT(8, ":-(in file %s line %4i\n", __FILE__, __LINE__)
-
 #define MICROSECONDS(X, Y) \
 			((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \
 					(long long int)(X.tv_usec - Y.tv_usec))
diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h
index 1d10d7e..518392e 100644
--- a/drivers/staging/easycap/easycap_debug.h
+++ b/drivers/staging/easycap/easycap_debug.h
@@ -24,4 +24,6 @@
  *
 */
 /*****************************************************************************/
-extern int easycap_debug;
+extern int debug;
+extern int gain;
+extern struct easycap_dongle easycap_dongle[];
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c
index 9a42ae0..447953a 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/easycap/easycap_ioctl.c
@@ -36,53 +36,101 @@
  *  UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
  *  FOLLOWING:
  *          peasycap->standard_offset
+ *          peasycap->inputset[peasycap->input].standard_offset
  *          peasycap->fps
  *          peasycap->usec
  *          peasycap->tolerate
+ *          peasycap->skip
  */
 /*---------------------------------------------------------------------------*/
 int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
 {
 struct easycap_standard const *peasycap_standard;
 __u16 reg, set;
-int ir, rc, need;
+int ir, rc, need, k;
 unsigned int itwas, isnow;
+bool resubmit;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 peasycap_standard = &easycap_standard[0];
 while (0xFFFF != peasycap_standard->mask) {
-	if (std_id & peasycap_standard->v4l2_standard.id)
+	if (std_id == peasycap_standard->v4l2_standard.id)
 		break;
 	peasycap_standard++;
 }
 if (0xFFFF == peasycap_standard->mask) {
-	SAY("ERROR: 0x%08X=std_id: standard not found\n", \
+	peasycap_standard = &easycap_standard[0];
+	while (0xFFFF != peasycap_standard->mask) {
+		if (std_id & peasycap_standard->v4l2_standard.id)
+			break;
+		peasycap_standard++;
+	}
+}
+if (0xFFFF == peasycap_standard->mask) {
+	SAM("ERROR: 0x%08X=std_id: standard not found\n", \
 							(unsigned int)std_id);
 	return -EINVAL;
 }
-SAY("user requests standard: %s\n", \
+SAM("selected standard: %s\n", \
 			&(peasycap_standard->v4l2_standard.name[0]));
 if (peasycap->standard_offset == \
 			(int)(peasycap_standard - &easycap_standard[0])) {
-	SAY("requested standard already in effect\n");
+	SAM("requested standard already in effect\n");
 	return 0;
 }
 peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]);
+for (k = 0; k < INPUT_MANY;  k++) {
+	if (!peasycap->inputset[k].standard_offset_ok) {
+			peasycap->inputset[k].standard_offset = \
+						peasycap->standard_offset;
+	}
+}
+if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
+	peasycap->inputset[peasycap->input].standard_offset = \
+						peasycap->standard_offset;
+	peasycap->inputset[peasycap->input].standard_offset_ok = 1;
+} else
+	JOM(8, "%i=peasycap->input\n", peasycap->input);
 peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \
 		peasycap_standard->v4l2_standard.frameperiod.numerator;
-if (!peasycap->fps) {
-	SAY("MISTAKE: frames-per-second is zero\n");
-	return -EFAULT;
+switch (peasycap->fps) {
+case 6:
+case 30: {
+	peasycap->ntsc = true;
+	break;
 }
-JOT(8, "%i frames-per-second\n", peasycap->fps);
-peasycap->usec = 1000000 / (2 * peasycap->fps);
-peasycap->tolerate = 1000 * (25 / peasycap->fps);
-
-kill_video_urbs(peasycap);
-
+case 5:
+case 25: {
+	peasycap->ntsc = false;
+	break;
+}
+default: {
+	SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
+	return -ENOENT;
+}
+}
+JOM(8, "%i frames-per-second\n", peasycap->fps);
+if (0x8000 & peasycap_standard->mask) {
+	peasycap->skip = 5;
+	peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
+	peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
+} else {
+	peasycap->skip = 0;
+	peasycap->usec = 1000000 / (2 * peasycap->fps);
+	peasycap->tolerate = 1000 * (25 / peasycap->fps);
+}
+if (peasycap->video_isoc_streaming) {
+	resubmit = true;
+	kill_video_urbs(peasycap);
+} else
+	resubmit = false;
 /*--------------------------------------------------------------------------*/
 /*
  *  SAA7113H DATASHEET PAGE 44, TABLE 42
@@ -94,55 +142,41 @@
 	reg = 0x0A;  set = 0x95;
 	ir = read_saa(peasycap->pusb_device, reg);
 	if (0 > ir)
-		SAY("ERROR: cannot read SAA register 0x%02X\n", reg);
+		SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
 	else
 		itwas = (unsigned int)ir;
-
-
-	set2to78(peasycap->pusb_device);
-
-
 	rc = write_saa(peasycap->pusb_device, reg, set);
 	if (0 != rc)
-		SAY("ERROR: failed to set SAA register " \
+		SAM("ERROR: failed to set SAA register " \
 			"0x%02X to 0x%02X for JP standard\n", reg, set);
 	else {
 		isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
 		if (0 > ir)
-			JOT(8, "SAA register 0x%02X changed " \
+			JOM(8, "SAA register 0x%02X changed " \
 				"to 0x%02X\n", reg, isnow);
 		else
-			JOT(8, "SAA register 0x%02X changed " \
+			JOM(8, "SAA register 0x%02X changed " \
 				"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
-
-		set2to78(peasycap->pusb_device);
-
 	}
 
 	reg = 0x0B;  set = 0x48;
 	ir = read_saa(peasycap->pusb_device, reg);
 	if (0 > ir)
-		SAY("ERROR: cannot read SAA register 0x%02X\n", reg);
+		SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
 	else
 		itwas = (unsigned int)ir;
-
-	set2to78(peasycap->pusb_device);
-
 	rc = write_saa(peasycap->pusb_device, reg, set);
 	if (0 != rc)
-		SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X " \
+		SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \
 						"for JP standard\n", reg, set);
 	else {
 		isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
 		if (0 > ir)
-			JOT(8, "SAA register 0x%02X changed " \
+			JOM(8, "SAA register 0x%02X changed " \
 				"to 0x%02X\n", reg, isnow);
 		else
-			JOT(8, "SAA register 0x%02X changed " \
+			JOM(8, "SAA register 0x%02X changed " \
 				"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
-
-		set2to78(peasycap->pusb_device);
-
 	}
 /*--------------------------------------------------------------------------*/
 /*
@@ -176,23 +210,20 @@
 if (need) {
 	ir = read_saa(peasycap->pusb_device, reg);
 	if (0 > ir)
-		SAY("ERROR: failed to read SAA register 0x%02X\n", reg);
+		SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
 	else
 		itwas = (unsigned int)ir;
-
-	set2to78(peasycap->pusb_device);
-
 	rc = write_saa(peasycap->pusb_device, reg, set);
 	if (0 != write_saa(peasycap->pusb_device, reg, set)) {
-		SAY("ERROR: failed to set SAA register " \
+		SAM("ERROR: failed to set SAA register " \
 			"0x%02X to 0x%02X for table 42\n", reg, set);
 	} else {
 		isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
 		if (0 > ir)
-			JOT(8, "SAA register 0x%02X changed " \
+			JOM(8, "SAA register 0x%02X changed " \
 				"to 0x%02X\n", reg, isnow);
 		else
-			JOT(8, "SAA register 0x%02X changed " \
+			JOM(8, "SAA register 0x%02X changed " \
 				"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
 	}
 }
@@ -204,7 +235,7 @@
 reg = 0x08;
 ir = read_saa(peasycap->pusb_device, reg);
 if (0 > ir)
-	SAY("ERROR: failed to read SAA register 0x%02X " \
+	SAM("ERROR: failed to read SAA register 0x%02X " \
 						"so cannot reset\n", reg);
 else {
 	itwas = (unsigned int)ir;
@@ -212,19 +243,18 @@
 		set = itwas | 0x40 ;
 	else
 		set = itwas & ~0x40 ;
-
-set2to78(peasycap->pusb_device);
-
-rc  = write_saa(peasycap->pusb_device, reg, set);
-if (0 != rc)
-	SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set);
-else {
-	isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
-	if (0 > ir)
-		JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow);
-	else
-		JOT(8, "SAA register 0x%02X changed " \
-			"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+	rc  = write_saa(peasycap->pusb_device, reg, set);
+	if (0 != rc)
+		SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
+								reg, set);
+	else {
+		isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+		if (0 > ir)
+			JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \
+								reg, isnow);
+		else
+			JOM(8, "SAA register 0x%02X changed " \
+				"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
 	}
 }
 /*--------------------------------------------------------------------------*/
@@ -235,7 +265,7 @@
 reg = 0x40;
 ir = read_saa(peasycap->pusb_device, reg);
 if (0 > ir)
-	SAY("ERROR: failed to read SAA register 0x%02X " \
+	SAM("ERROR: failed to read SAA register 0x%02X " \
 						"so cannot reset\n", reg);
 else {
 	itwas = (unsigned int)ir;
@@ -243,19 +273,18 @@
 		set = itwas | 0x80 ;
 	else
 		set = itwas & ~0x80 ;
-
-set2to78(peasycap->pusb_device);
-
-rc = write_saa(peasycap->pusb_device, reg, set);
-if (0 != rc)
-	SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set);
-else {
-	isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
-	if (0 > ir)
-		JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow);
-	else
-		JOT(8, "SAA register 0x%02X changed " \
-			"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
+	rc = write_saa(peasycap->pusb_device, reg, set);
+	if (0 != rc)
+		SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
+								reg, set);
+	else {
+		isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
+		if (0 > ir)
+			JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \
+								reg, isnow);
+		else
+			JOM(8, "SAA register 0x%02X changed " \
+				"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
 	}
 }
 /*--------------------------------------------------------------------------*/
@@ -266,41 +295,39 @@
 reg = 0x5A;
 ir = read_saa(peasycap->pusb_device, reg);
 if (0 > ir)
-	SAY("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
+	SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
 	itwas = (unsigned int)ir;
 	if (peasycap_standard->mask & 0x0001)
 		set = 0x0A ;
 	else
 		set = 0x07 ;
-
-	set2to78(peasycap->pusb_device);
-
 	if (0 != write_saa(peasycap->pusb_device, reg, set))
-		SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
+		SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \
 								reg, set);
 	else {
 		isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
 		if (0 > ir)
-			JOT(8, "SAA register 0x%02X changed "
+			JOM(8, "SAA register 0x%02X changed "
 				"to 0x%02X\n", reg, isnow);
 		else
-			JOT(8, "SAA register 0x%02X changed "
+			JOM(8, "SAA register 0x%02X changed "
 				"from 0x%02X to 0x%02X\n", reg, itwas, isnow);
 	}
-	if (0 != check_saa(peasycap->pusb_device))
-		SAY("ERROR: check_saa() failed\n");
+if (true == resubmit)
+	submit_video_urbs(peasycap);
 return 0;
 }
 /*****************************************************************************/
 /*--------------------------------------------------------------------------*/
 /*
- *  THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL DEPENDS ON THE
- *  CURRENT VALUE OF peasycap->standard_offset.
+ *  THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
+ *  A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
+ *
  *  PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
  *  THIS ROUTINE UPDATES THE FOLLOWING:
  *          peasycap->format_offset
+ *          peasycap->inputset[peasycap->input].format_offset
  *          peasycap->pixelformat
- *          peasycap->field
  *          peasycap->height
  *          peasycap->width
  *          peasycap->bytesperpixel
@@ -321,39 +348,93 @@
 struct easycap_format *peasycap_format, *peasycap_best_format;
 __u16 mask;
 struct usb_device *p;
-int miss, multiplier, best;
-char bf[5], *pc;
+int miss, multiplier, best, k;
+char bf[5], fo[32], *pc;
 __u32 uc;
+bool resubmit;
 
-if ((struct easycap *)NULL == peasycap) {
+if (NULL == peasycap) {
 	SAY("ERROR: peasycap is NULL\n");
 	return -EFAULT;
 }
+if (0 > peasycap->standard_offset) {
+	JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
+	return -EBUSY;
+}
 p = peasycap->pusb_device;
 if ((struct usb_device *)NULL == p) {
-	SAY("ERROR: peaycap->pusb_device is NULL\n");
+	SAM("ERROR: peaycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 pc = &bf[0];
-uc = pixelformat;  memcpy((void *)pc, (void *)(&uc), 4);  bf[4] = 0;
-mask = easycap_standard[peasycap->standard_offset].mask;
-SAY("sought:    %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
+uc = pixelformat;
+memcpy((void *)pc, (void *)(&uc), 4);
+bf[4] = 0;
+mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
+SAM("sought:    %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \
 				width, height, pc, pixelformat, field, mask);
+switch (field) {
+case V4L2_FIELD_ANY: {
+	strcpy(&fo[0], "V4L2_FIELD_ANY ");
+	break;
+}
+case V4L2_FIELD_NONE: {
+	strcpy(&fo[0], "V4L2_FIELD_NONE");
+	break;
+}
+case V4L2_FIELD_TOP: {
+	strcpy(&fo[0], "V4L2_FIELD_TOP");
+	break;
+}
+case V4L2_FIELD_BOTTOM: {
+	strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
+	break;
+}
+case V4L2_FIELD_INTERLACED: {
+	strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
+	break;
+}
+case V4L2_FIELD_SEQ_TB: {
+	strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
+	break;
+}
+case V4L2_FIELD_SEQ_BT: {
+	strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
+	break;
+}
+case V4L2_FIELD_ALTERNATE: {
+	strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
+	break;
+}
+case V4L2_FIELD_INTERLACED_TB: {
+	strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
+	break;
+}
+case V4L2_FIELD_INTERLACED_BT: {
+	strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
+	break;
+}
+default: {
+	strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN  ");
+	break;
+}
+}
+SAM("sought:    %s\n", &fo[0]);
 if (V4L2_FIELD_ANY == field) {
-	field = V4L2_FIELD_INTERLACED;
-	SAY("prefer:    V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n");
+	field = V4L2_FIELD_NONE;
+	SAM("prefer:    V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
 }
 peasycap_best_format = (struct easycap_format *)NULL;
 peasycap_format = &easycap_format[0];
 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
-	JOT(16, ".> %i %i 0x%08X %ix%i\n", \
+	JOM(16, ".> %i %i 0x%08X %ix%i\n", \
 		peasycap_format->mask & 0x01,
 		peasycap_format->v4l2_format.fmt.pix.field,
 		peasycap_format->v4l2_format.fmt.pix.pixelformat,
 		peasycap_format->v4l2_format.fmt.pix.width,
 		peasycap_format->v4l2_format.fmt.pix.height);
 
-	if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
+	if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
 		(peasycap_format->v4l2_format.fmt.pix.field == field) && \
 		(peasycap_format->v4l2_format.fmt.pix.pixelformat == \
 							pixelformat) && \
@@ -365,11 +446,11 @@
 	peasycap_format++;
 }
 if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
-	SAY("cannot do: %ix%i with standard mask 0x%02X\n", \
+	SAM("cannot do: %ix%i with standard mask 0x%02X\n", \
 							width, height, mask);
 	peasycap_format = &easycap_format[0];  best = -1;
 	while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
-		if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
+		if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \
 				 (peasycap_format->v4l2_format.fmt.pix\
 						.field == field) && \
 				 (peasycap_format->v4l2_format.fmt.pix\
@@ -386,16 +467,16 @@
 		peasycap_format++;
 	}
 	if (-1 == best) {
-		SAY("cannot do %ix... with standard mask 0x%02X\n", \
+		SAM("cannot do %ix... with standard mask 0x%02X\n", \
 								width, mask);
-		SAY("cannot do ...x%i with standard mask 0x%02X\n", \
+		SAM("cannot do ...x%i with standard mask 0x%02X\n", \
 								height, mask);
-		SAY("           %ix%i unmatched\n", width, height);
+		SAM("           %ix%i unmatched\n", width, height);
 		return peasycap->format_offset;
 	}
 }
 if ((struct easycap_format *)NULL == peasycap_best_format) {
-	SAY("MISTAKE: peasycap_best_format is NULL");
+	SAM("MISTAKE: peasycap_best_format is NULL");
 	return -EINVAL;
 }
 peasycap_format = peasycap_best_format;
@@ -406,23 +487,43 @@
 /*...........................................................................*/
 
 if (false != try) {
-	SAY("MISTAKE: true==try where is should be false\n");
+	SAM("MISTAKE: true==try where is should be false\n");
 	return -EINVAL;
 }
-SAY("actioning: %ix%i %s\n", \
+SAM("actioning: %ix%i %s\n", \
 			peasycap_format->v4l2_format.fmt.pix.width, \
 			peasycap_format->v4l2_format.fmt.pix.height,
 			&peasycap_format->name[0]);
 peasycap->height        = peasycap_format->v4l2_format.fmt.pix.height;
 peasycap->width         = peasycap_format->v4l2_format.fmt.pix.width;
 peasycap->pixelformat   = peasycap_format->v4l2_format.fmt.pix.pixelformat;
-peasycap->field         = peasycap_format->v4l2_format.fmt.pix.field;
 peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]);
-peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ;
+
+
+for (k = 0; k < INPUT_MANY; k++) {
+	if (!peasycap->inputset[k].format_offset_ok) {
+		peasycap->inputset[k].format_offset = \
+						peasycap->format_offset;
+	}
+}
+if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
+	peasycap->inputset[peasycap->input].format_offset = \
+						peasycap->format_offset;
+	peasycap->inputset[peasycap->input].format_offset_ok = 1;
+} else
+	JOM(8, "%i=peasycap->input\n", peasycap->input);
+
+
+
+peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
 if (0x0100 & peasycap_format->mask)
 	peasycap->byteswaporder = true;
 else
 	peasycap->byteswaporder = false;
+if (0x0200 & peasycap_format->mask)
+	peasycap->skip = 5;
+else
+	peasycap->skip = 0;
 if (0x0800 & peasycap_format->mask)
 	peasycap->decimatepixel = true;
 else
@@ -439,27 +540,11 @@
 					multiplier * peasycap->height;
 peasycap->frame_buffer_used = peasycap->bytesperpixel * \
 					peasycap->width * peasycap->height;
-
-if (true == peasycap->offerfields) {
-	SAY("WARNING: %i=peasycap->field is untested: " \
-				"please report problems\n", peasycap->field);
-
-
-/*
- *    FIXME ---- THIS IS UNTESTED, MAY BE (AND PROBABLY IS) INCORRECT:
- *
- *    peasycap->frame_buffer_used = peasycap->frame_buffer_used / 2;
- *
- *    SO DO NOT RISK IT YET.
- *
- */
-
-
-
-}
-
-kill_video_urbs(peasycap);
-
+if (peasycap->video_isoc_streaming) {
+	resubmit = true;
+	kill_video_urbs(peasycap);
+} else
+	resubmit = false;
 /*---------------------------------------------------------------------------*/
 /*
  *  PAL
@@ -474,13 +559,13 @@
 			(288 == \
 			peasycap_format->v4l2_format.fmt.pix.height))) {
 		if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
-			SAY("ERROR: set_resolution() failed\n");
+			SAM("ERROR: set_resolution() failed\n");
 			return -EINVAL;
 		}
 	} else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \
 			(576 == peasycap_format->v4l2_format.fmt.pix.height)) {
 		if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
-			SAY("ERROR: set_resolution() failed\n");
+			SAM("ERROR: set_resolution() failed\n");
 			return -EINVAL;
 		}
 	} else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
@@ -491,11 +576,11 @@
 			(240 == \
 			peasycap_format->v4l2_format.fmt.pix.height))) {
 		if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
-			SAY("ERROR: set_resolution() failed\n");
+			SAM("ERROR: set_resolution() failed\n");
 			return -EINVAL;
 		}
 	} else {
-		SAY("MISTAKE: bad format, cannot set resolution\n");
+		SAM("MISTAKE: bad format, cannot set resolution\n");
 		return -EINVAL;
 	}
 /*---------------------------------------------------------------------------*/
@@ -512,7 +597,7 @@
 			(240 == \
 			peasycap_format->v4l2_format.fmt.pix.height))) {
 		if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
-			SAY("ERROR: set_resolution() failed\n");
+			SAM("ERROR: set_resolution() failed\n");
 			return -EINVAL;
 		}
 	} else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \
@@ -523,28 +608,31 @@
 			(240 == \
 			peasycap_format->v4l2_format.fmt.pix.height))) {
 		if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
-			SAY("ERROR: set_resolution() failed\n");
+			SAM("ERROR: set_resolution() failed\n");
 			return -EINVAL;
 		}
 	} else {
-		SAY("MISTAKE: bad format, cannot set resolution\n");
+		SAM("MISTAKE: bad format, cannot set resolution\n");
 		return -EINVAL;
 	}
 }
 /*---------------------------------------------------------------------------*/
-
-check_stk(peasycap->pusb_device);
-
+if (true == resubmit)
+	submit_video_urbs(peasycap);
 return (int)(peasycap_best_format - &easycap_format[0]);
 }
 /*****************************************************************************/
 int adjust_brightness(struct easycap *peasycap, int value)
 {
 unsigned int mood;
-int i1;
+int i1, k;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 i1 = 0;
@@ -553,37 +641,56 @@
 		if ((easycap_control[i1].minimum > value) || \
 					(easycap_control[i1].maximum < value))
 			value = easycap_control[i1].default_value;
+
+		if ((easycap_control[i1].minimum <= peasycap->brightness) && \
+					(easycap_control[i1].maximum >= \
+						peasycap->brightness)) {
+			if (peasycap->brightness == value) {
+				SAM("unchanged brightness at  0x%02X\n", \
+								value);
+				return 0;
+			}
+		}
 		peasycap->brightness = value;
+		for (k = 0; k < INPUT_MANY; k++) {
+			if (!peasycap->inputset[k].brightness_ok)
+				peasycap->inputset[k].brightness = \
+							peasycap->brightness;
+		}
+		if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
+			peasycap->inputset[peasycap->input].brightness = \
+							peasycap->brightness;
+			peasycap->inputset[peasycap->input].brightness_ok = 1;
+		} else
+			JOM(8, "%i=peasycap->input\n", peasycap->input);
 		mood = 0x00FF & (unsigned int)peasycap->brightness;
-
-		set2to78(peasycap->pusb_device);
-
 		if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
-			SAY("adjusting brightness to  0x%02X\n", mood);
+			SAM("adjusting brightness to  0x%02X\n", mood);
 			return 0;
 		} else {
-			SAY("WARNING: failed to adjust brightness " \
+			SAM("WARNING: failed to adjust brightness " \
 							"to 0x%02X\n", mood);
 			return -ENOENT;
 		}
-
-		set2to78(peasycap->pusb_device);
-
 		break;
 	}
 	i1++;
 }
-SAY("WARNING: failed to adjust brightness: control not found\n");
+SAM("WARNING: failed to adjust brightness: control not found\n");
 return -ENOENT;
 }
 /*****************************************************************************/
 int adjust_contrast(struct easycap *peasycap, int value)
 {
 unsigned int mood;
-int i1;
+int i1, k;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 i1 = 0;
@@ -592,37 +699,58 @@
 		if ((easycap_control[i1].minimum > value) || \
 					(easycap_control[i1].maximum < value))
 			value = easycap_control[i1].default_value;
+
+
+
+		if ((easycap_control[i1].minimum <= peasycap->contrast) && \
+				(easycap_control[i1].maximum >= \
+							peasycap->contrast)) {
+			if (peasycap->contrast == value) {
+				SAM("unchanged contrast at  0x%02X\n", value);
+				return 0;
+			}
+		}
 		peasycap->contrast = value;
+		for (k = 0; k < INPUT_MANY; k++) {
+			if (!peasycap->inputset[k].contrast_ok) {
+				peasycap->inputset[k].contrast = \
+							peasycap->contrast;
+			}
+		}
+		if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
+			peasycap->inputset[peasycap->input].contrast = \
+							peasycap->contrast;
+			peasycap->inputset[peasycap->input].contrast_ok = 1;
+		} else
+			JOM(8, "%i=peasycap->input\n", peasycap->input);
 		mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
-
-		set2to78(peasycap->pusb_device);
-
 		if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
-			SAY("adjusting contrast to  0x%02X\n", mood);
+			SAM("adjusting contrast to  0x%02X\n", mood);
 			return 0;
 		} else {
-			SAY("WARNING: failed to adjust contrast to " \
+			SAM("WARNING: failed to adjust contrast to " \
 							"0x%02X\n", mood);
 			return -ENOENT;
 		}
-
-		set2to78(peasycap->pusb_device);
-
 		break;
 	}
 	i1++;
 }
-SAY("WARNING: failed to adjust contrast: control not found\n");
+SAM("WARNING: failed to adjust contrast: control not found\n");
 return -ENOENT;
 }
 /*****************************************************************************/
 int adjust_saturation(struct easycap *peasycap, int value)
 {
 unsigned int mood;
-int i1;
+int i1, k;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 i1 = 0;
@@ -631,37 +759,58 @@
 		if ((easycap_control[i1].minimum > value) || \
 					(easycap_control[i1].maximum < value))
 			value = easycap_control[i1].default_value;
+
+
+		if ((easycap_control[i1].minimum <= peasycap->saturation) && \
+					(easycap_control[i1].maximum >= \
+						peasycap->saturation)) {
+			if (peasycap->saturation == value) {
+				SAM("unchanged saturation at  0x%02X\n", \
+								value);
+				return 0;
+			}
+		}
 		peasycap->saturation = value;
+		for (k = 0; k < INPUT_MANY; k++) {
+			if (!peasycap->inputset[k].saturation_ok) {
+				peasycap->inputset[k].saturation = \
+							peasycap->saturation;
+			}
+		}
+		if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
+			peasycap->inputset[peasycap->input].saturation = \
+							peasycap->saturation;
+			peasycap->inputset[peasycap->input].saturation_ok = 1;
+		} else
+			JOM(8, "%i=peasycap->input\n", peasycap->input);
 		mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
-
-		set2to78(peasycap->pusb_device);
-
 		if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
-			SAY("adjusting saturation to  0x%02X\n", mood);
+			SAM("adjusting saturation to  0x%02X\n", mood);
 			return 0;
 		} else {
-			SAY("WARNING: failed to adjust saturation to " \
+			SAM("WARNING: failed to adjust saturation to " \
 							"0x%02X\n", mood);
 			return -ENOENT;
 		}
 		break;
-
-		set2to78(peasycap->pusb_device);
-
 	}
 	i1++;
 }
-SAY("WARNING: failed to adjust saturation: control not found\n");
+SAM("WARNING: failed to adjust saturation: control not found\n");
 return -ENOENT;
 }
 /*****************************************************************************/
 int adjust_hue(struct easycap *peasycap, int value)
 {
 unsigned int mood;
-int i1, i2;
+int i1, i2, k;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 i1 = 0;
@@ -670,27 +819,40 @@
 		if ((easycap_control[i1].minimum > value) || \
 					(easycap_control[i1].maximum < value))
 			value = easycap_control[i1].default_value;
+
+		if ((easycap_control[i1].minimum <= peasycap->hue) && \
+					(easycap_control[i1].maximum >= \
+							peasycap->hue)) {
+			if (peasycap->hue == value) {
+				SAM("unchanged hue at  0x%02X\n", value);
+				return 0;
+			}
+		}
 		peasycap->hue = value;
+		for (k = 0; k < INPUT_MANY; k++) {
+			if (!peasycap->inputset[k].hue_ok)
+				peasycap->inputset[k].hue = peasycap->hue;
+		}
+		if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
+			peasycap->inputset[peasycap->input].hue = \
+							peasycap->hue;
+			peasycap->inputset[peasycap->input].hue_ok = 1;
+		} else
+			JOM(8, "%i=peasycap->input\n", peasycap->input);
 		i2 = peasycap->hue - 128;
 		mood = 0x00FF & ((int) i2);
-
-		set2to78(peasycap->pusb_device);
-
 		if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
-			SAY("adjusting hue to  0x%02X\n", mood);
+			SAM("adjusting hue to  0x%02X\n", mood);
 			return 0;
 		} else {
-			SAY("WARNING: failed to adjust hue to 0x%02X\n", mood);
+			SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
 			return -ENOENT;
 		}
-
-		set2to78(peasycap->pusb_device);
-
 		break;
 	}
 	i1++;
 }
-SAY("WARNING: failed to adjust hue: control not found\n");
+SAM("WARNING: failed to adjust hue: control not found\n");
 return -ENOENT;
 }
 /*****************************************************************************/
@@ -699,33 +861,45 @@
 __s8 mood;
 int i1;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 i1 = 0;
 while (0xFFFFFFFF != easycap_control[i1].id) {
 	if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
 		if ((easycap_control[i1].minimum > value) || \
-			(easycap_control[i1].maximum < value))
+				(easycap_control[i1].maximum < value))
 			value = easycap_control[i1].default_value;
+		if ((easycap_control[i1].minimum <= peasycap->volume) && \
+					(easycap_control[i1].maximum >= \
+							peasycap->volume)) {
+			if (peasycap->volume == value) {
+				SAM("unchanged volume at  0x%02X\n", value);
+				return 0;
+			}
+		}
 		peasycap->volume = value;
 		mood = (16 > peasycap->volume) ? 16 : \
 			((31 < peasycap->volume) ? 31 : \
 			(__s8) peasycap->volume);
 		if (!audio_gainset(peasycap->pusb_device, mood)) {
-			SAY("adjusting volume to 0x%01X\n", mood);
+			SAM("adjusting volume to 0x%02X\n", mood);
 			return 0;
 		} else {
-			SAY("WARNING: failed to adjust volume to " \
-							"0x%1X\n", mood);
+			SAM("WARNING: failed to adjust volume to " \
+							"0x%2X\n", mood);
 			return -ENOENT;
 		}
 		break;
 	}
 i1++;
 }
-SAY("WARNING: failed to adjust volume: control not found\n");
+SAM("WARNING: failed to adjust volume: control not found\n");
 return -ENOENT;
 }
 /*****************************************************************************/
@@ -744,8 +918,12 @@
 {
 int i1;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 i1 = 0;
@@ -756,13 +934,13 @@
 		case 1: {
 			peasycap->audio_idle = 1;
 			peasycap->timeval0.tv_sec = 0;
-			SAY("adjusting mute: %i=peasycap->audio_idle\n", \
+			SAM("adjusting mute: %i=peasycap->audio_idle\n", \
 							peasycap->audio_idle);
 			return 0;
 		}
 		default: {
 			peasycap->audio_idle = 0;
-			SAY("adjusting mute: %i=peasycap->audio_idle\n", \
+			SAM("adjusting mute: %i=peasycap->audio_idle\n", \
 							peasycap->audio_idle);
 			return 0;
 		}
@@ -771,47 +949,107 @@
 	}
 	i1++;
 }
-SAY("WARNING: failed to adjust mute: control not found\n");
+SAM("WARNING: failed to adjust mute: control not found\n");
 return -ENOENT;
 }
-
-/*--------------------------------------------------------------------------*/
-static int easycap_ioctl_bkl(struct inode *inode, struct file *file,
-			     unsigned int cmd, unsigned long arg)
+/*****************************************************************************/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
+	(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
+long
+easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
+	return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg);
+}
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*---------------------------------------------------------------------------*/
+int
+easycap_ioctl(struct inode *inode, struct file *file,
+					unsigned int cmd, unsigned long arg)
 {
-static struct easycap *peasycap;
-static struct usb_device *p;
-static __u32 isequence;
+struct easycap *peasycap;
+struct usb_device *p;
+int kd;
 
+if (NULL == file) {
+	SAY("ERROR:  file is NULL\n");
+	return -ERESTARTSYS;
+}
 peasycap = file->private_data;
 if (NULL == peasycap) {
 	SAY("ERROR:  peasycap is NULL\n");
 	return -1;
 }
-p = peasycap->pusb_device;
-if ((struct usb_device *)NULL == p) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap\n");
 	return -EFAULT;
 }
+p = peasycap->pusb_device;
+if (NULL == p) {
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+kd = isdongle(peasycap);
+if (0 <= kd && DONGLE_MANY > kd) {
+	if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
+		SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd);
+		return -ERESTARTSYS;
+	}
+	JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
 /*---------------------------------------------------------------------------*/
 /*
- *  MOST OF THE VARIABLES DECLARED static IN THE case{} BLOCKS BELOW ARE SO
- *  DECLARED SIMPLY TO AVOID A COMPILER WARNING OF THE KIND:
- *  easycap_ioctl.c: warning:
- *                       the frame size of ... bytes is larger than 1024 bytes
- */
+ *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
+ *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
+ *  IF NECESSARY, BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	if (kd != isdongle(peasycap))
+		return -ERESTARTSYS;
+	if (NULL == file) {
+		SAY("ERROR:  file is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+	peasycap = file->private_data;
+	if (NULL == peasycap) {
+		SAY("ERROR:  peasycap is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+		SAY("ERROR: bad peasycap\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EFAULT;
+	}
+	p = peasycap->pusb_device;
+	if (NULL == peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+} else {
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
+ *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	return -ERESTARTSYS;
+}
 /*---------------------------------------------------------------------------*/
 switch (cmd) {
 case VIDIOC_QUERYCAP: {
-	static struct v4l2_capability v4l2_capability;
-	static char version[16], *p1, *p2;
-	static int i, rc, k[3];
-	static long lng;
+	struct v4l2_capability v4l2_capability;
+	char version[16], *p1, *p2;
+	int i, rc, k[3];
+	long lng;
 
-	JOT(8, "VIDIOC_QUERYCAP\n");
+	JOM(8, "VIDIOC_QUERYCAP\n");
 
 	if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
-		SAY("ERROR: bad driver version string\n"); return -EINVAL;
+		SAM("ERROR: bad driver version string\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EINVAL;
 	}
 	strcpy(&version[0], EASYCAP_DRIVER_VERSION);
 	for (i = 0; i < 3; i++)
@@ -826,8 +1064,9 @@
 		if (3 > i) {
 			rc = (int) strict_strtol(p1, 10, &lng);
 			if (0 != rc) {
-				SAY("ERROR: %i=strict_strtol(%s,.,,)\n", \
+				SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \
 								rc, p1);
+				mutex_unlock(&easycap_dongle[kd].mutex_video);
 				return -EINVAL;
 			}
 			k[i] = (int)lng;
@@ -844,7 +1083,7 @@
 				V4L2_CAP_AUDIO         | V4L2_CAP_READWRITE;
 
 	v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
-	JOT(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
+	JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
 
 	strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
 		sizeof(v4l2_capability.card));
@@ -853,26 +1092,26 @@
 				sizeof(v4l2_capability.bus_info)) < 0) {
 		strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \
 					sizeof(v4l2_capability.bus_info));
-		JOT(8, "%s=v4l2_capability.bus_info\n", \
+		JOM(8, "%s=v4l2_capability.bus_info\n", \
 					&v4l2_capability.bus_info[0]);
 	}
 	if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
 					sizeof(struct v4l2_capability))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_ENUMINPUT: {
-	static struct v4l2_input v4l2_input;
-	static __u32 index;
+	struct v4l2_input v4l2_input;
+	__u32 index;
 
-	JOT(8, "VIDIOC_ENUMINPUT\n");
+	JOM(8, "VIDIOC_ENUMINPUT\n");
 
 	if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
 					sizeof(struct v4l2_input))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
@@ -889,7 +1128,7 @@
 		v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
 				V4L2_STD_NTSC ;
 		v4l2_input.status = 0;
-		JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
 		break;
 	}
 	case 1: {
@@ -901,7 +1140,7 @@
 		v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
 				V4L2_STD_NTSC ;
 		v4l2_input.status = 0;
-		JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
 		break;
 	}
 	case 2: {
@@ -913,7 +1152,7 @@
 		v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
 				V4L2_STD_NTSC ;
 		v4l2_input.status = 0;
-		JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
 		break;
 	}
 	case 3: {
@@ -925,7 +1164,7 @@
 		v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
 				V4L2_STD_NTSC ;
 		v4l2_input.status = 0;
-		JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
 		break;
 	}
 	case 4: {
@@ -937,7 +1176,7 @@
 		v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
 				V4L2_STD_NTSC ;
 		v4l2_input.status = 0;
-		JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
 		break;
 	}
 	case 5: {
@@ -949,31 +1188,32 @@
 		v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
 				V4L2_STD_NTSC ;
 		v4l2_input.status = 0;
-		JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
 		break;
 	}
 	default: {
-		JOT(8, "%i=index: exhausts inputs\n", index);
+		JOM(8, "%i=index: exhausts inputs\n", index);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
 	}
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
 						sizeof(struct v4l2_input))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_INPUT: {
-	static __u32 index;
+	__u32 index;
 
-	JOT(8, "VIDIOC_G_INPUT\n");
+	JOM(8, "VIDIOC_G_INPUT\n");
 	index = (__u32)peasycap->input;
-	JOT(8, "user is told: %i\n", index);
+	JOM(8, "user is told: %i\n", index);
 	if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
@@ -981,79 +1221,89 @@
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_S_INPUT:
 	{
-	static __u32 index;
+	__u32 index;
+	int rc;
 
-	JOT(8, "VIDIOC_S_INPUT\n");
+	JOM(8, "VIDIOC_S_INPUT\n");
 
 	if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	JOT(8, "user requests input %i\n", index);
+	JOM(8, "user requests input %i\n", index);
 
 	if ((int)index == peasycap->input) {
-		SAY("requested input already in effect\n");
+		SAM("requested input already in effect\n");
 		break;
 	}
 
-	if ((0 > index) || (5 < index)) {
-		JOT(8, "ERROR:  bad requested input: %i\n", index);
+	if ((0 > index) || (INPUT_MANY <= index)) {
+		JOM(8, "ERROR:  bad requested input: %i\n", index);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
-	peasycap->input = (int)index;
 
-	select_input(peasycap->pusb_device, peasycap->input, 9);
-
+	rc = newinput(peasycap, (int)index);
+	if (0 == rc) {
+		JOM(8, "newinput(.,%i) OK\n", (int)index);
+	} else {
+		SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EFAULT;
+	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_ENUMAUDIO: {
-	JOT(8, "VIDIOC_ENUMAUDIO\n");
+	JOM(8, "VIDIOC_ENUMAUDIO\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_ENUMAUDOUT: {
-	static struct v4l2_audioout v4l2_audioout;
+	struct v4l2_audioout v4l2_audioout;
 
-	JOT(8, "VIDIOC_ENUMAUDOUT\n");
+	JOM(8, "VIDIOC_ENUMAUDOUT\n");
 
 	if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
 					sizeof(struct v4l2_audioout))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (0 != v4l2_audioout.index)
+	if (0 != v4l2_audioout.index) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
+	}
 	memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
 	v4l2_audioout.index = 0;
 	strcpy(&v4l2_audioout.name[0], "Soundtrack");
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
 					sizeof(struct v4l2_audioout))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_QUERYCTRL: {
-	static int i1;
-	static struct v4l2_queryctrl v4l2_queryctrl;
+	int i1;
+	struct v4l2_queryctrl v4l2_queryctrl;
 
-	JOT(8, "VIDIOC_QUERYCTRL\n");
+	JOM(8, "VIDIOC_QUERYCTRL\n");
 
 	if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
 					sizeof(struct v4l2_queryctrl))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
 	i1 = 0;
 	while (0xFFFFFFFF != easycap_control[i1].id) {
 		if (easycap_control[i1].id == v4l2_queryctrl.id) {
-			JOT(8, "VIDIOC_QUERYCTRL  %s=easycap_control[%i]" \
+			JOM(8, "VIDIOC_QUERYCTRL  %s=easycap_control[%i]" \
 				".name\n", &easycap_control[i1].name[0], i1);
 			memcpy(&v4l2_queryctrl, &easycap_control[i1], \
 						sizeof(struct v4l2_queryctrl));
@@ -1062,127 +1312,137 @@
 		i1++;
 	}
 	if (0xFFFFFFFF == easycap_control[i1].id) {
-		JOT(8, "%i=index: exhausts controls\n", i1);
+		JOM(8, "%i=index: exhausts controls\n", i1);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
 	if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
 					sizeof(struct v4l2_queryctrl))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_QUERYMENU: {
-	JOT(8, "VIDIOC_QUERYMENU unsupported\n");
+	JOM(8, "VIDIOC_QUERYMENU unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
-	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_CTRL: {
-	static struct v4l2_control v4l2_control;
+	struct v4l2_control *pv4l2_control;
 
-	JOT(8, "VIDIOC_G_CTRL\n");
-
-	if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
+	JOM(8, "VIDIOC_G_CTRL\n");
+	pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL);
+	if (!pv4l2_control) {
+		SAM("ERROR: out of memory\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ENOMEM;
+	}
+	if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \
 					sizeof(struct v4l2_control))) {
-		POUT;
+		kfree(pv4l2_control);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	switch (v4l2_control.id) {
+	switch (pv4l2_control->id) {
 	case V4L2_CID_BRIGHTNESS: {
-		v4l2_control.value = peasycap->brightness;
-		JOT(8, "user enquires brightness: %i\n", v4l2_control.value);
+		pv4l2_control->value = peasycap->brightness;
+		JOM(8, "user enquires brightness: %i\n", pv4l2_control->value);
 		break;
 	}
 	case V4L2_CID_CONTRAST: {
-		v4l2_control.value = peasycap->contrast;
-		JOT(8, "user enquires contrast: %i\n", v4l2_control.value);
+		pv4l2_control->value = peasycap->contrast;
+		JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
 		break;
 	}
 	case V4L2_CID_SATURATION: {
-		v4l2_control.value = peasycap->saturation;
-		JOT(8, "user enquires saturation: %i\n", v4l2_control.value);
+		pv4l2_control->value = peasycap->saturation;
+		JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
 		break;
 	}
 	case V4L2_CID_HUE: {
-		v4l2_control.value = peasycap->hue;
-		JOT(8, "user enquires hue: %i\n", v4l2_control.value);
+		pv4l2_control->value = peasycap->hue;
+		JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
 		break;
 	}
 	case V4L2_CID_AUDIO_VOLUME: {
-		v4l2_control.value = peasycap->volume;
-		JOT(8, "user enquires volume: %i\n", v4l2_control.value);
+		pv4l2_control->value = peasycap->volume;
+		JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
 		break;
 	}
 	case V4L2_CID_AUDIO_MUTE: {
 		if (1 == peasycap->mute)
-			v4l2_control.value = true;
+			pv4l2_control->value = true;
 		else
-			v4l2_control.value = false;
-		JOT(8, "user enquires mute: %i\n", v4l2_control.value);
+			pv4l2_control->value = false;
+		JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
 		break;
 	}
 	default: {
-		SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
-							v4l2_control.id);
-		explain_cid(v4l2_control.id);
+		SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
+							pv4l2_control->id);
+		kfree(pv4l2_control);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
 	}
-	if (0 != copy_to_user((void __user *)arg, &v4l2_control, \
+	if (0 != copy_to_user((void __user *)arg, pv4l2_control, \
 					sizeof(struct v4l2_control))) {
-		POUT;
+		kfree(pv4l2_control);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
+	kfree(pv4l2_control);
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 #if defined(VIDIOC_S_CTRL_OLD)
 case VIDIOC_S_CTRL_OLD: {
-	JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
+	JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
 }
 #endif /*VIDIOC_S_CTRL_OLD*/
 case VIDIOC_S_CTRL:
 	{
-	static struct v4l2_control v4l2_control;
+	struct v4l2_control v4l2_control;
 
-	JOT(8, "VIDIOC_S_CTRL\n");
+	JOM(8, "VIDIOC_S_CTRL\n");
 
 	if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
 					sizeof(struct v4l2_control))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
 	switch (v4l2_control.id) {
 	case V4L2_CID_BRIGHTNESS: {
-		JOT(8, "user requests brightness %i\n", v4l2_control.value);
+		JOM(8, "user requests brightness %i\n", v4l2_control.value);
 		if (0 != adjust_brightness(peasycap, v4l2_control.value))
 			;
 		break;
 	}
 	case V4L2_CID_CONTRAST: {
-		JOT(8, "user requests contrast %i\n", v4l2_control.value);
+		JOM(8, "user requests contrast %i\n", v4l2_control.value);
 		if (0 != adjust_contrast(peasycap, v4l2_control.value))
 			;
 		break;
 	}
 	case V4L2_CID_SATURATION: {
-		JOT(8, "user requests saturation %i\n", v4l2_control.value);
+		JOM(8, "user requests saturation %i\n", v4l2_control.value);
 		if (0 != adjust_saturation(peasycap, v4l2_control.value))
 			;
 		break;
 	}
 	case V4L2_CID_HUE: {
-		JOT(8, "user requests hue %i\n", v4l2_control.value);
+		JOM(8, "user requests hue %i\n", v4l2_control.value);
 		if (0 != adjust_hue(peasycap, v4l2_control.value))
 			;
 		break;
 	}
 	case V4L2_CID_AUDIO_VOLUME: {
-		JOT(8, "user requests volume %i\n", v4l2_control.value);
+		JOM(8, "user requests volume %i\n", v4l2_control.value);
 		if (0 != adjust_volume(peasycap, v4l2_control.value))
 			;
 		break;
@@ -1190,40 +1450,41 @@
 	case V4L2_CID_AUDIO_MUTE: {
 		int mute;
 
-		JOT(8, "user requests mute %i\n", v4l2_control.value);
+		JOM(8, "user requests mute %i\n", v4l2_control.value);
 		if (true == v4l2_control.value)
 			mute = 1;
 		else
 			mute = 0;
 
 		if (0 != adjust_mute(peasycap, mute))
-			SAY("WARNING: failed to adjust mute to %i\n", mute);
+			SAM("WARNING: failed to adjust mute to %i\n", mute);
 		break;
 	}
 	default: {
-		SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
+		SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
 							v4l2_control.id);
-		explain_cid(v4l2_control.id);
-	return -EINVAL;
-			}
-		}
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EINVAL;
+	}
+	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_S_EXT_CTRLS: {
-	JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
+	JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_ENUM_FMT: {
-	static __u32 index;
-	static struct v4l2_fmtdesc v4l2_fmtdesc;
+	__u32 index;
+	struct v4l2_fmtdesc v4l2_fmtdesc;
 
-	JOT(8, "VIDIOC_ENUM_FMT\n");
+	JOM(8, "VIDIOC_ENUM_FMT\n");
 
 	if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
 					sizeof(struct v4l2_fmtdesc))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
@@ -1238,117 +1499,327 @@
 		v4l2_fmtdesc.flags = 0;
 		strcpy(&v4l2_fmtdesc.description[0], "uyvy");
 		v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
-		JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
 		break;
 	}
 	case 1: {
 		v4l2_fmtdesc.flags = 0;
 		strcpy(&v4l2_fmtdesc.description[0], "yuy2");
 		v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
-		JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
 		break;
 	}
 	case 2: {
 		v4l2_fmtdesc.flags = 0;
 		strcpy(&v4l2_fmtdesc.description[0], "rgb24");
 		v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
-		JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
 		break;
 	}
 	case 3: {
 		v4l2_fmtdesc.flags = 0;
 		strcpy(&v4l2_fmtdesc.description[0], "rgb32");
 		v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
-		JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
 		break;
 	}
 	case 4: {
 		v4l2_fmtdesc.flags = 0;
 		strcpy(&v4l2_fmtdesc.description[0], "bgr24");
 		v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
-		JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
 		break;
 	}
 	case 5: {
 		v4l2_fmtdesc.flags = 0;
 		strcpy(&v4l2_fmtdesc.description[0], "bgr32");
 		v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
-		JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
+		JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
 		break;
 	}
 	default: {
-		JOT(8, "%i=index: exhausts formats\n", index);
+		JOM(8, "%i=index: exhausts formats\n", index);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
 	}
 	if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
 					sizeof(struct v4l2_fmtdesc))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/*
+ *  THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
+ *  THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS.  BEWARE.
+*/
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_ENUM_FRAMESIZES: {
-	JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n");
-	return -EINVAL;
+	__u32 index;
+	struct v4l2_frmsizeenum v4l2_frmsizeenum;
+
+	JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
+
+	if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \
+					sizeof(struct v4l2_frmsizeenum))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EFAULT;
+	}
+
+	index = v4l2_frmsizeenum.index;
+
+	v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE;
+
+	if (true == peasycap->ntsc) {
+		switch (index) {
+		case 0: {
+			v4l2_frmsizeenum.discrete.width = 640;
+			v4l2_frmsizeenum.discrete.height = 480;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						 discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 1: {
+			v4l2_frmsizeenum.discrete.width = 320;
+			v4l2_frmsizeenum.discrete.height = 240;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 2: {
+			v4l2_frmsizeenum.discrete.width = 720;
+			v4l2_frmsizeenum.discrete.height = 480;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 3: {
+			v4l2_frmsizeenum.discrete.width = 360;
+			v4l2_frmsizeenum.discrete.height = 240;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		default: {
+			JOM(8, "%i=index: exhausts framesizes\n", index);
+			mutex_unlock(&easycap_dongle[kd].mutex_video);
+			return -EINVAL;
+		}
+		}
+	} else {
+		switch (index) {
+		case 0: {
+			v4l2_frmsizeenum.discrete.width = 640;
+			v4l2_frmsizeenum.discrete.height = 480;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 1: {
+			v4l2_frmsizeenum.discrete.width = 320;
+			v4l2_frmsizeenum.discrete.height = 240;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 2: {
+			v4l2_frmsizeenum.discrete.width = 704;
+			v4l2_frmsizeenum.discrete.height = 576;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 3: {
+			v4l2_frmsizeenum.discrete.width = 720;
+			v4l2_frmsizeenum.discrete.height = 576;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		case 4: {
+			v4l2_frmsizeenum.discrete.width = 360;
+			v4l2_frmsizeenum.discrete.height = 288;
+			JOM(8, "%i=index: %ix%i\n", index, \
+					(int)(v4l2_frmsizeenum.\
+						discrete.width), \
+					(int)(v4l2_frmsizeenum.\
+						discrete.height));
+			break;
+		}
+		default: {
+			JOM(8, "%i=index: exhausts framesizes\n", index);
+			mutex_unlock(&easycap_dongle[kd].mutex_video);
+			return -EINVAL;
+		}
+		}
+	}
+	if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \
+					sizeof(struct v4l2_frmsizeenum))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EFAULT;
+	}
+	break;
 }
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/*
+ *  THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
+ *  THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS.  BEWARE.
+*/
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_ENUM_FRAMEINTERVALS: {
-	JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
-	return -EINVAL;
+	__u32 index;
+	int denominator;
+	struct v4l2_frmivalenum v4l2_frmivalenum;
+
+	JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
+
+	if (peasycap->fps)
+		denominator = peasycap->fps;
+	else {
+		if (true == peasycap->ntsc)
+			denominator = 30;
+		else
+			denominator = 25;
+	}
+
+	if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \
+					sizeof(struct v4l2_frmivalenum))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EFAULT;
+	}
+
+	index = v4l2_frmivalenum.index;
+
+	v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE;
+
+	switch (index) {
+	case 0: {
+		v4l2_frmivalenum.discrete.numerator = 1;
+		v4l2_frmivalenum.discrete.denominator = denominator;
+		JOM(8, "%i=index: %i/%i\n", index, \
+			(int)(v4l2_frmivalenum.discrete.numerator), \
+			(int)(v4l2_frmivalenum.discrete.denominator));
+		break;
+	}
+	case 1: {
+		v4l2_frmivalenum.discrete.numerator = 1;
+		v4l2_frmivalenum.discrete.denominator = denominator/5;
+		JOM(8, "%i=index: %i/%i\n", index, \
+			(int)(v4l2_frmivalenum.discrete.numerator), \
+			(int)(v4l2_frmivalenum.discrete.denominator));
+		break;
+	}
+	default: {
+		JOM(8, "%i=index: exhausts frameintervals\n", index);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EINVAL;
+	}
+	}
+	if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \
+					sizeof(struct v4l2_frmivalenum))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EFAULT;
+	}
+	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_FMT: {
-	static struct v4l2_format v4l2_format;
-	static struct v4l2_pix_format v4l2_pix_format;
+	struct v4l2_format *pv4l2_format;
+	struct v4l2_pix_format *pv4l2_pix_format;
 
-	JOT(8, "VIDIOC_G_FMT\n");
-
-	if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
+	JOM(8, "VIDIOC_G_FMT\n");
+	pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
+	if (!pv4l2_format) {
+		SAM("ERROR: out of memory\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ENOMEM;
+	}
+	pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
+	if (!pv4l2_pix_format) {
+		SAM("ERROR: out of memory\n");
+		kfree(pv4l2_format);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ENOMEM;
+	}
+	if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \
 					sizeof(struct v4l2_format))) {
-		POUT;
+		kfree(pv4l2_format);
+		kfree(pv4l2_pix_format);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		POUT;
+	if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		kfree(pv4l2_format);
+		kfree(pv4l2_pix_format);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
 
-	memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
-	v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	memcpy(&(v4l2_format.fmt.pix), \
-			 &(easycap_format[peasycap->format_offset]\
-			.v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
-	JOT(8, "user is told: %s\n", \
+	memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
+	pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	memcpy(&pv4l2_format->fmt.pix, \
+			 &easycap_format[peasycap->format_offset]\
+			.v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format));
+	JOM(8, "user is told: %s\n", \
 			&easycap_format[peasycap->format_offset].name[0]);
 
-	if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
+	if (0 != copy_to_user((void __user *)arg, pv4l2_format, \
 					sizeof(struct v4l2_format))) {
-		POUT;
+		kfree(pv4l2_format);
+		kfree(pv4l2_pix_format);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
+	kfree(pv4l2_format);
+	kfree(pv4l2_pix_format);
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_TRY_FMT:
 case VIDIOC_S_FMT: {
-	static struct v4l2_format v4l2_format;
-	static struct v4l2_pix_format v4l2_pix_format;
-	static bool try;
-	static int best_format;
+	struct v4l2_format v4l2_format;
+	struct v4l2_pix_format v4l2_pix_format;
+	bool try;
+	int best_format;
 
 	if (VIDIOC_TRY_FMT == cmd) {
-		JOT(8, "VIDIOC_TRY_FMT\n");
+		JOM(8, "VIDIOC_TRY_FMT\n");
 		try = true;
 	} else {
-		JOT(8, "VIDIOC_S_FMT\n");
+		JOM(8, "VIDIOC_S_FMT\n");
 		try = false;
 	}
 
 	if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
 					sizeof(struct v4l2_format))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
@@ -1359,7 +1830,12 @@
 					v4l2_format.fmt.pix.field, \
 					try);
 	if (0 > best_format) {
-		JOT(8, "WARNING: adjust_format() returned %i\n", best_format);
+		if (-EBUSY == best_format) {
+			mutex_unlock(&easycap_dongle[kd].mutex_video);
+			return -EBUSY;
+		}
+		JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -ENOENT;
 	}
 /*...........................................................................*/
@@ -1368,29 +1844,29 @@
 
 	memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\
 			.v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
-	JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
+	JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
 					sizeof(struct v4l2_format))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_CROPCAP: {
-	static struct v4l2_cropcap v4l2_cropcap;
+	struct v4l2_cropcap v4l2_cropcap;
 
-	JOT(8, "VIDIOC_CROPCAP\n");
+	JOM(8, "VIDIOC_CROPCAP\n");
 
 	if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
 					sizeof(struct v4l2_cropcap))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
 	if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
+		JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
 
 	memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
 	v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1405,11 +1881,11 @@
 	v4l2_cropcap.pixelaspect.numerator = 1;
 	v4l2_cropcap.pixelaspect.denominator = 1;
 
-	JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
+	JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
 					sizeof(struct v4l2_cropcap))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
@@ -1417,13 +1893,15 @@
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_CROP:
 case VIDIOC_S_CROP: {
-	JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP  unsupported\n");
+	JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP  unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_QUERYSTD: {
-	JOT(8, "VIDIOC_QUERYSTD: " \
+	JOM(8, "VIDIOC_QUERYSTD: " \
 			"EasyCAP is incapable of detecting standard\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 	break;
 }
@@ -1436,16 +1914,16 @@
  */
 /*---------------------------------------------------------------------------*/
 case VIDIOC_ENUMSTD: {
-	static int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
-	static struct v4l2_standard v4l2_standard;
-	static __u32 index;
-	static struct easycap_standard const *peasycap_standard;
+	int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
+	struct v4l2_standard v4l2_standard;
+	__u32 index;
+	struct easycap_standard const *peasycap_standard;
 
-	JOT(8, "VIDIOC_ENUMSTD\n");
+	JOM(8, "VIDIOC_ENUMSTD\n");
 
 	if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
 					sizeof(struct v4l2_standard))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	index = v4l2_standard.index;
@@ -1466,10 +1944,11 @@
 		peasycap_standard++;
 	}
 	if (0xFFFF == peasycap_standard->mask) {
-		JOT(8, "%i=index: exhausts standards\n", index);
+		JOM(8, "%i=index: exhausts standards\n", index);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
-	JOT(8, "%i=index: %s\n", index, \
+	JOM(8, "%i=index: %s\n", index, \
 				&(peasycap_standard->v4l2_standard.name[0]));
 	memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \
 					sizeof(struct v4l2_standard));
@@ -1478,87 +1957,101 @@
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
 					sizeof(struct v4l2_standard))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_STD: {
-	static v4l2_std_id std_id;
-	static struct easycap_standard const *peasycap_standard;
+	v4l2_std_id std_id;
+	struct easycap_standard const *peasycap_standard;
 
-	JOT(8, "VIDIOC_G_STD\n");
+	JOM(8, "VIDIOC_G_STD\n");
+
+	if (0 > peasycap->standard_offset) {
+		JOM(8, "%i=peasycap->standard_offset\n", \
+					peasycap->standard_offset);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EBUSY;
+	}
 
 	if (0 != copy_from_user(&std_id, (void __user *)arg, \
 						sizeof(v4l2_std_id))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
 	peasycap_standard = &easycap_standard[peasycap->standard_offset];
 	std_id = peasycap_standard->v4l2_standard.id;
 
-	JOT(8, "user is told: %s\n", \
+	JOM(8, "user is told: %s\n", \
 				&peasycap_standard->v4l2_standard.name[0]);
 
 	if (0 != copy_to_user((void __user *)arg, &std_id, \
 						sizeof(v4l2_std_id))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_S_STD: {
-	static v4l2_std_id std_id;
-	static int rc;
+	v4l2_std_id std_id;
+	int rc;
 
-	JOT(8, "VIDIOC_S_STD\n");
+	JOM(8, "VIDIOC_S_STD\n");
 
 	if (0 != copy_from_user(&std_id, (void __user *)arg, \
 						sizeof(v4l2_std_id))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
+	JOM(8, "User requests standard: 0x%08X%08X\n", \
+		(int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \
+		(int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));
+
 	rc = adjust_standard(peasycap, std_id);
 	if (0 > rc) {
-		JOT(8, "WARNING: adjust_standard() returned %i\n", rc);
+		JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -ENOENT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_REQBUFS: {
-	static int nbuffers;
-	static struct v4l2_requestbuffers v4l2_requestbuffers;
+	int nbuffers;
+	struct v4l2_requestbuffers v4l2_requestbuffers;
 
-	JOT(8, "VIDIOC_REQBUFS\n");
+	JOM(8, "VIDIOC_REQBUFS\n");
 
 	if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
 				sizeof(struct v4l2_requestbuffers))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
+	}
 	if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
 	nbuffers = v4l2_requestbuffers.count;
-	JOT(8, "                   User requests %i buffers ...\n", nbuffers);
+	JOM(8, "                   User requests %i buffers ...\n", nbuffers);
 	if (nbuffers < 2)
 		nbuffers = 2;
 	if (nbuffers > FRAME_BUFFER_MANY)
 		nbuffers = FRAME_BUFFER_MANY;
 	if (v4l2_requestbuffers.count == nbuffers) {
-		JOT(8, "                   ... agree to  %i buffers\n", \
+		JOM(8, "                   ... agree to  %i buffers\n", \
 								nbuffers);
 	} else {
-		JOT(8, "                  ... insist on  %i buffers\n", \
+		JOM(8, "                  ... insist on  %i buffers\n", \
 								nbuffers);
 		v4l2_requestbuffers.count = nbuffers;
 	}
@@ -1566,32 +2059,35 @@
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
 				sizeof(struct v4l2_requestbuffers))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_QUERYBUF: {
-	static __u32 index;
-	static struct v4l2_buffer v4l2_buffer;
+	__u32 index;
+	struct v4l2_buffer v4l2_buffer;
 
-	JOT(8, "VIDIOC_QUERYBUF\n");
+	JOM(8, "VIDIOC_QUERYBUF\n");
 
 	if (peasycap->video_eof) {
-		JOT(8, "returning -1 because  %i=video_eof\n", \
+		JOM(8, "returning -EIO because  %i=video_eof\n", \
 							peasycap->video_eof);
-		return -1;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -EIO;
 	}
 
 	if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
 					sizeof(struct v4l2_buffer))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
+	}
 	index = v4l2_buffer.index;
 	if (index < 0 || index >= peasycap->frame_buffer_many)
 		return -EINVAL;
@@ -1602,49 +2098,55 @@
 	v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
 						peasycap->done[index] | \
 						peasycap->queued[index];
-	v4l2_buffer.field = peasycap->field;
+	v4l2_buffer.field = V4L2_FIELD_NONE;
 	v4l2_buffer.memory = V4L2_MEMORY_MMAP;
 	v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
 	v4l2_buffer.length = FRAME_BUFFER_SIZE;
 
-	JOT(16, "  %10i=index\n", v4l2_buffer.index);
-	JOT(16, "  0x%08X=type\n", v4l2_buffer.type);
-	JOT(16, "  %10i=bytesused\n", v4l2_buffer.bytesused);
-	JOT(16, "  0x%08X=flags\n", v4l2_buffer.flags);
-	JOT(16, "  %10i=field\n", v4l2_buffer.field);
-	JOT(16, "  %10li=timestamp.tv_usec\n", \
+	JOM(16, "  %10i=index\n", v4l2_buffer.index);
+	JOM(16, "  0x%08X=type\n", v4l2_buffer.type);
+	JOM(16, "  %10i=bytesused\n", v4l2_buffer.bytesused);
+	JOM(16, "  0x%08X=flags\n", v4l2_buffer.flags);
+	JOM(16, "  %10i=field\n", v4l2_buffer.field);
+	JOM(16, "  %10li=timestamp.tv_usec\n", \
 					 (long)v4l2_buffer.timestamp.tv_usec);
-	JOT(16, "  %10i=sequence\n", v4l2_buffer.sequence);
-	JOT(16, "  0x%08X=memory\n", v4l2_buffer.memory);
-	JOT(16, "  %10i=m.offset\n", v4l2_buffer.m.offset);
-	JOT(16, "  %10i=length\n", v4l2_buffer.length);
+	JOM(16, "  %10i=sequence\n", v4l2_buffer.sequence);
+	JOM(16, "  0x%08X=memory\n", v4l2_buffer.memory);
+	JOM(16, "  %10i=m.offset\n", v4l2_buffer.m.offset);
+	JOM(16, "  %10i=length\n", v4l2_buffer.length);
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
 					sizeof(struct v4l2_buffer))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_QBUF: {
-	static struct v4l2_buffer v4l2_buffer;
+	struct v4l2_buffer v4l2_buffer;
 
-	JOT(8, "VIDIOC_QBUF\n");
+	JOM(8, "VIDIOC_QBUF\n");
 
 	if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
 					sizeof(struct v4l2_buffer))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
-	if (v4l2_buffer.memory != V4L2_MEMORY_MMAP)
+	}
+	if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
+	}
 	if (v4l2_buffer.index < 0 || \
-		 (v4l2_buffer.index >= peasycap->frame_buffer_many))
+		 (v4l2_buffer.index >= peasycap->frame_buffer_many)) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
+	}
 	v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
 
 	peasycap->done[v4l2_buffer.index]   = 0;
@@ -1652,11 +2154,11 @@
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
 					sizeof(struct v4l2_buffer))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	JOT(8, ".....   user queueing frame buffer %i\n", \
+	JOM(8, ".....   user queueing frame buffer %i\n", \
 						(int)v4l2_buffer.index);
 
 	peasycap->frame_lock = 0;
@@ -1667,36 +2169,60 @@
 case VIDIOC_DQBUF:
 	{
 #if defined(AUDIOTIME)
-	static struct signed_div_result sdr;
-	static long long int above, below, dnbydt, fudge, sll;
-	static unsigned long long int ull;
-	static struct timeval timeval0;
+	struct signed_div_result sdr;
+	long long int above, below, dnbydt, fudge, sll;
+	unsigned long long int ull;
+	struct timeval timeval8;
 	struct timeval timeval1;
 #endif /*AUDIOTIME*/
-	static struct timeval timeval, timeval2;
-	static int i, j;
-	static struct v4l2_buffer v4l2_buffer;
+	struct timeval timeval, timeval2;
+	int i, j;
+	struct v4l2_buffer v4l2_buffer;
+	int rcdq;
+	__u16 input;
 
-	JOT(8, "VIDIOC_DQBUF\n");
+	JOM(8, "VIDIOC_DQBUF\n");
 
 	if ((peasycap->video_idle) || (peasycap->video_eof)) {
-		JOT(8, "returning -EIO because  " \
+		JOM(8, "returning -EIO because  " \
 				"%i=video_idle  %i=video_eof\n", \
 				peasycap->video_idle, peasycap->video_eof);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EIO;
 	}
 
 	if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
 					sizeof(struct v4l2_buffer))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
+	}
+
+	if (true == peasycap->offerfields) {
+		/*-----------------------------------------------------------*/
+		/*
+		 *  IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
+		 *  V4L2_FIELD_BOTTOM
+		*/
+		/*-----------------------------------------------------------*/
+		if (V4L2_FIELD_TOP == v4l2_buffer.field)
+			JOM(8, "user wants V4L2_FIELD_TOP\n");
+		else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
+			JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
+		else if (V4L2_FIELD_ANY == v4l2_buffer.field)
+			JOM(8, "user wants V4L2_FIELD_ANY\n");
+		else
+			JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \
+							v4l2_buffer.field);
+	}
 
 	if (!peasycap->video_isoc_streaming) {
-		JOT(16, "returning -EIO because video urbs not streaming\n");
+		JOM(16, "returning -EIO because video urbs not streaming\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EIO;
 	}
 /*---------------------------------------------------------------------------*/
@@ -1708,19 +2234,28 @@
 /*---------------------------------------------------------------------------*/
 
 	if (!peasycap->polled) {
-		if (-EIO == easycap_dqbuf(peasycap, 0))
-			return -EIO;
+		do {
+			rcdq = easycap_dqbuf(peasycap, 0);
+			if (-EIO == rcdq) {
+				JOM(8, "returning -EIO because " \
+						"dqbuf() returned -EIO\n");
+				mutex_unlock(&easycap_dongle[kd].mutex_video);
+				return -EIO;
+			}
+		} while (0 != rcdq);
 	} else {
-		if (peasycap->video_eof)
+		if (peasycap->video_eof) {
+			mutex_unlock(&easycap_dongle[kd].mutex_video);
 			return -EIO;
+		}
 	}
 	if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
-		SAY("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
+		SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
 					peasycap->done[peasycap->frame_read]);
 	}
 	peasycap->polled = 0;
 
-	if (!(isequence % 10)) {
+	if (!(peasycap->isequence % 10)) {
 		for (i = 0; i < 179; i++)
 			peasycap->merit[i] = peasycap->merit[i+1];
 		peasycap->merit[179] = merit_saa(peasycap->pusb_device);
@@ -1728,7 +2263,7 @@
 		for (i = 0; i < 180; i++)
 			j += peasycap->merit[i];
 		if (90 < j) {
-			SAY("easycap driver shutting down " \
+			SAM("easycap driver shutting down " \
 							"on condition blue\n");
 			peasycap->video_eof = 1; peasycap->audio_eof = 1;
 		}
@@ -1738,31 +2273,23 @@
 	v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	v4l2_buffer.bytesused = peasycap->frame_buffer_used;
 	v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
-	v4l2_buffer.field =  peasycap->field;
-	if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field)
-		v4l2_buffer.field = \
-				0x000F & (peasycap->\
-				frame_buffer[peasycap->frame_read][0].kount);
+	if (true == peasycap->offerfields)
+		v4l2_buffer.field = V4L2_FIELD_BOTTOM;
+	else
+		v4l2_buffer.field = V4L2_FIELD_NONE;
 	do_gettimeofday(&timeval);
 	timeval2 = timeval;
 
 #if defined(AUDIOTIME)
 	if (!peasycap->timeval0.tv_sec) {
-		timeval0 = timeval;
+		timeval8 = timeval;
 		timeval1 = timeval;
 		timeval2 = timeval;
 		dnbydt = 192000;
-
-		if (mutex_lock_interruptible(&(peasycap->mutex_timeval0)))
-			return -ERESTARTSYS;
-		peasycap->timeval0 = timeval0;
-		mutex_unlock(&(peasycap->mutex_timeval0));
+		peasycap->timeval0 = timeval8;
 	} else {
-		if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
-			return -ERESTARTSYS;
 		dnbydt = peasycap->dnbydt;
 		timeval1 = peasycap->timeval1;
-		mutex_unlock(&(peasycap->mutex_timeval1));
 		above = dnbydt * MICROSECONDS(timeval, timeval1);
 		below = 192000;
 		sdr = signed_div(above, below);
@@ -1774,72 +2301,76 @@
 		timeval2.tv_usec = sdr.remainder;
 		timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
 	}
-	if (!(isequence % 500)) {
+	if (!(peasycap->isequence % 500)) {
 		fudge = ((long long int)(1000000)) * \
 				((long long int)(timeval.tv_sec - \
 						timeval2.tv_sec)) + \
 				(long long int)(timeval.tv_usec - \
-				timeval2.tv_usec);
+						timeval2.tv_usec);
 		sdr = signed_div(fudge, 1000);
 		sll = sdr.quotient;
 		ull = sdr.remainder;
 
-		SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
+		SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
 	}
 #endif /*AUDIOTIME*/
 
 	v4l2_buffer.timestamp = timeval2;
-	v4l2_buffer.sequence = isequence++;
+	v4l2_buffer.sequence = peasycap->isequence++;
 	v4l2_buffer.memory = V4L2_MEMORY_MMAP;
 	v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
 	v4l2_buffer.length = FRAME_BUFFER_SIZE;
 
-	JOT(16, "  %10i=index\n", v4l2_buffer.index);
-	JOT(16, "  0x%08X=type\n", v4l2_buffer.type);
-	JOT(16, "  %10i=bytesused\n", v4l2_buffer.bytesused);
-	JOT(16, "  0x%08X=flags\n", v4l2_buffer.flags);
-	JOT(16, "  %10i=field\n", v4l2_buffer.field);
-	JOT(16, "  %10li=timestamp.tv_usec\n", \
+	JOM(16, "  %10i=index\n", v4l2_buffer.index);
+	JOM(16, "  0x%08X=type\n", v4l2_buffer.type);
+	JOM(16, "  %10i=bytesused\n", v4l2_buffer.bytesused);
+	JOM(16, "  0x%08X=flags\n", v4l2_buffer.flags);
+	JOM(16, "  %10i=field\n", v4l2_buffer.field);
+	JOM(16, "  %10li=timestamp.tv_sec\n", \
+					(long)v4l2_buffer.timestamp.tv_sec);
+	JOM(16, "  %10li=timestamp.tv_usec\n", \
 					(long)v4l2_buffer.timestamp.tv_usec);
-	JOT(16, "  %10i=sequence\n", v4l2_buffer.sequence);
-	JOT(16, "  0x%08X=memory\n", v4l2_buffer.memory);
-	JOT(16, "  %10i=m.offset\n", v4l2_buffer.m.offset);
-	JOT(16, "  %10i=length\n", v4l2_buffer.length);
+	JOM(16, "  %10i=sequence\n", v4l2_buffer.sequence);
+	JOM(16, "  0x%08X=memory\n", v4l2_buffer.memory);
+	JOM(16, "  %10i=m.offset\n", v4l2_buffer.m.offset);
+	JOM(16, "  %10i=length\n", v4l2_buffer.length);
 
 	if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
 						sizeof(struct v4l2_buffer))) {
-		POUT;
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	JOT(8, "..... user is offered frame buffer %i\n", \
+	input = peasycap->frame_buffer[peasycap->frame_read][0].input;
+	if (0x08 & input) {
+		JOM(8, "user is offered frame buffer %i, input %i\n", \
+					peasycap->frame_read, (0x07 & input));
+	} else {
+		JOM(8, "user is offered frame buffer %i\n", \
 							peasycap->frame_read);
+	}
 	peasycap->frame_lock = 1;
+	JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill);
 	if (peasycap->frame_read == peasycap->frame_fill) {
 		if (peasycap->frame_lock) {
-			JOT(8, "ERROR:  filling frame buffer " \
+			JOM(8, "WORRY:  filling frame buffer " \
 						"while offered to user\n");
 		}
 	}
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/*---------------------------------------------------------------------------*/
-/*
- *  AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED;
- *  VIDEO URBS HAVE NOT.
- */
-/*---------------------------------------------------------------------------*/
 case VIDIOC_STREAMON: {
-	static int i;
+	int i;
 
-	JOT(8, "VIDIOC_STREAMON\n");
+	JOM(8, "VIDIOC_STREAMON\n");
 
-	isequence = 0;
+	peasycap->isequence = 0;
 	for (i = 0; i < 180; i++)
 		peasycap->merit[i] = 0;
 	if ((struct usb_device *)NULL == peasycap->pusb_device) {
-		SAY("ERROR: peasycap->pusb_device is NULL\n");
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 	submit_video_urbs(peasycap);
@@ -1851,10 +2382,11 @@
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_STREAMOFF: {
-	JOT(8, "VIDIOC_STREAMOFF\n");
+	JOM(8, "VIDIOC_STREAMOFF\n");
 
 	if ((struct usb_device *)NULL == peasycap->pusb_device) {
-		SAY("ERROR: peasycap->pusb_device is NULL\n");
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
@@ -1866,7 +2398,7 @@
  *  THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT.   BEWARE.
  */
 /*---------------------------------------------------------------------------*/
-	JOT(8, "calling wake_up on wq_video and wq_audio\n");
+	JOM(8, "calling wake_up on wq_video and wq_audio\n");
 	wake_up_interruptible(&(peasycap->wq_video));
 	wake_up_interruptible(&(peasycap->wq_audio));
 /*---------------------------------------------------------------------------*/
@@ -1874,111 +2406,200 @@
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_PARM: {
-	static struct v4l2_streamparm v4l2_streamparm;
+	struct v4l2_streamparm *pv4l2_streamparm;
 
-	JOT(8, "VIDIOC_G_PARM\n");
-
-	if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \
+	JOM(8, "VIDIOC_G_PARM\n");
+	pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL);
+	if (!pv4l2_streamparm) {
+		SAM("ERROR: out of memory\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ENOMEM;
+	}
+	if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \
 					sizeof(struct v4l2_streamparm))) {
-		POUT;
+		kfree(pv4l2_streamparm);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
 
-	if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		POUT;
+	if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		kfree(pv4l2_streamparm);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EINVAL;
 	}
-	v4l2_streamparm.parm.capture.capability = 0;
-	v4l2_streamparm.parm.capture.capturemode = 0;
-	v4l2_streamparm.parm.capture.timeperframe.numerator = 1;
-	v4l2_streamparm.parm.capture.timeperframe.denominator = 30;
-	v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many;
-	v4l2_streamparm.parm.capture.extendedmode = 0;
-	if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \
+	pv4l2_streamparm->parm.capture.capability = 0;
+	pv4l2_streamparm->parm.capture.capturemode = 0;
+	pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
+
+	if (peasycap->fps) {
+		pv4l2_streamparm->parm.capture.timeperframe.\
+						denominator = peasycap->fps;
+	} else {
+		if (true == peasycap->ntsc) {
+			pv4l2_streamparm->parm.capture.timeperframe.\
+						denominator = 30;
+		} else {
+			pv4l2_streamparm->parm.capture.timeperframe.\
+						denominator = 25;
+		}
+	}
+
+	pv4l2_streamparm->parm.capture.readbuffers = \
+						peasycap->frame_buffer_many;
+	pv4l2_streamparm->parm.capture.extendedmode = 0;
+	if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \
 					sizeof(struct v4l2_streamparm))) {
-		POUT;
+		kfree(pv4l2_streamparm);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
 		return -EFAULT;
 	}
+	kfree(pv4l2_streamparm);
 	break;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_S_PARM: {
-	JOT(8, "VIDIOC_S_PARM unsupported\n");
+	JOM(8, "VIDIOC_S_PARM unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_AUDIO: {
-	JOT(8, "VIDIOC_G_AUDIO unsupported\n");
+	JOM(8, "VIDIOC_G_AUDIO unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_S_AUDIO: {
-	JOT(8, "VIDIOC_S_AUDIO unsupported\n");
+	JOM(8, "VIDIOC_S_AUDIO unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_S_TUNER: {
-	JOT(8, "VIDIOC_S_TUNER unsupported\n");
+	JOM(8, "VIDIOC_S_TUNER unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_FBUF:
 case VIDIOC_S_FBUF:
 case VIDIOC_OVERLAY: {
-	JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
+	JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 case VIDIOC_G_TUNER: {
-	JOT(8, "VIDIOC_G_TUNER unsupported\n");
+	JOM(8, "VIDIOC_G_TUNER unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 case VIDIOC_G_FREQUENCY:
 case VIDIOC_S_FREQUENCY: {
-	JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
+	JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -EINVAL;
 }
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 default: {
-	JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
-	explain_ioctl(cmd);
-	POUT;
+	JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
 	return -ENOIOCTLCMD;
 }
 }
+mutex_unlock(&easycap_dongle[kd].mutex_video);
+JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
 return 0;
 }
-
-long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct inode *inode = file->f_dentry->d_inode;
-	long ret;
-
-	lock_kernel();
-	ret = easycap_ioctl_bkl(inode, file, cmd, arg);
-	unlock_kernel();
-
-	return ret;
+/*****************************************************************************/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
+	(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
+long
+easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
+	return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg);
 }
-
-/*--------------------------------------------------------------------------*/
-static int easysnd_ioctl_bkl(struct inode *inode, struct file *file,
-			     unsigned int cmd, unsigned long arg)
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*---------------------------------------------------------------------------*/
+int
+easysnd_ioctl(struct inode *inode, struct file *file,
+					unsigned int cmd, unsigned long arg)
 {
 struct easycap *peasycap;
 struct usb_device *p;
+int kd;
 
+if (NULL == file) {
+	SAY("ERROR:  file is NULL\n");
+	return -ERESTARTSYS;
+}
 peasycap = file->private_data;
 if (NULL == peasycap) {
 	SAY("ERROR:  peasycap is NULL.\n");
-	return -1;
+	return -EFAULT;
+}
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap\n");
+	return -EFAULT;
 }
 p = peasycap->pusb_device;
+if (NULL == p) {
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+kd = isdongle(peasycap);
+if (0 <= kd && DONGLE_MANY > kd) {
+	if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) {
+		SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd);
+		return -ERESTARTSYS;
+	}
+	JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
+/*---------------------------------------------------------------------------*/
+/*
+ *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
+ *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
+ *  IF NECESSARY, BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	if (kd != isdongle(peasycap))
+		return -ERESTARTSYS;
+	if (NULL == file) {
+		SAY("ERROR:  file is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	peasycap = file->private_data;
+	if (NULL == peasycap) {
+		SAY("ERROR:  peasycap is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+		SAY("ERROR: bad peasycap\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	p = peasycap->pusb_device;
+	if (NULL == peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+} else {
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
+ *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	return -ERESTARTSYS;
+}
 /*---------------------------------------------------------------------------*/
 switch (cmd) {
 case SNDCTL_DSP_GETCAPS: {
 	int caps;
-	JOT(8, "SNDCTL_DSP_GETCAPS\n");
+	JOM(8, "SNDCTL_DSP_GETCAPS\n");
 
 #if defined(UPSAMPLE)
 	if (true == peasycap->microphone)
@@ -1992,13 +2613,15 @@
 		caps = 0x04400000;
 #endif /*UPSAMPLE*/
 
-	if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int)))
+	if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
 case SNDCTL_DSP_GETFMTS: {
 	int incoming;
-	JOT(8, "SNDCTL_DSP_GETFMTS\n");
+	JOM(8, "SNDCTL_DSP_GETFMTS\n");
 
 #if defined(UPSAMPLE)
 	if (true == peasycap->microphone)
@@ -2012,16 +2635,20 @@
 		incoming = AFMT_S16_LE;
 #endif /*UPSAMPLE*/
 
-	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
 case SNDCTL_DSP_SETFMT: {
 	int incoming, outgoing;
-	JOT(8, "SNDCTL_DSP_SETFMT\n");
-	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+	JOM(8, "SNDCTL_DSP_SETFMT\n");
+	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
-	JOT(8, "........... %i=incoming\n", incoming);
+	}
+	JOM(8, "........... %i=incoming\n", incoming);
 
 #if defined(UPSAMPLE)
 	if (true == peasycap->microphone)
@@ -2036,22 +2663,27 @@
 #endif /*UPSAMPLE*/
 
 	if (incoming != outgoing) {
-		JOT(8, "........... %i=outgoing\n", outgoing);
-		JOT(8, "        cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
-		JOT(8, "        cf. %i=AFMT_U8\n", AFMT_U8);
+		JOM(8, "........... %i=outgoing\n", outgoing);
+		JOM(8, "        cf. %i=AFMT_S16_LE\n", AFMT_S16_LE);
+		JOM(8, "        cf. %i=AFMT_U8\n", AFMT_U8);
 		if (0 != copy_to_user((void __user *)arg, &outgoing, \
-								sizeof(int)))
+								sizeof(int))) {
+			mutex_unlock(&easycap_dongle[kd].mutex_audio);
 			return -EFAULT;
+		}
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EINVAL ;
 	}
 	break;
 }
 case SNDCTL_DSP_STEREO: {
 	int incoming;
-	JOT(8, "SNDCTL_DSP_STEREO\n");
-	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+	JOM(8, "SNDCTL_DSP_STEREO\n");
+	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
-	JOT(8, "........... %i=incoming\n", incoming);
+	}
+	JOM(8, "........... %i=incoming\n", incoming);
 
 #if defined(UPSAMPLE)
 	if (true == peasycap->microphone)
@@ -2065,16 +2697,20 @@
 		incoming = 1;
 #endif /*UPSAMPLE*/
 
-	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
 case SNDCTL_DSP_SPEED: {
 	int incoming;
-	JOT(8, "SNDCTL_DSP_SPEED\n");
-	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+	JOM(8, "SNDCTL_DSP_SPEED\n");
+	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
-	JOT(8, "........... %i=incoming\n", incoming);
+	}
+	JOM(8, "........... %i=incoming\n", incoming);
 
 #if defined(UPSAMPLE)
 	if (true == peasycap->microphone)
@@ -2088,29 +2724,37 @@
 		incoming = 48000;
 #endif /*UPSAMPLE*/
 
-	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
 case SNDCTL_DSP_GETTRIGGER: {
 	int incoming;
-	JOT(8, "SNDCTL_DSP_GETTRIGGER\n");
-	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+	JOM(8, "SNDCTL_DSP_GETTRIGGER\n");
+	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
-	JOT(8, "........... %i=incoming\n", incoming);
+	}
+	JOM(8, "........... %i=incoming\n", incoming);
 
 	incoming = PCM_ENABLE_INPUT;
-	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
 case SNDCTL_DSP_SETTRIGGER: {
 	int incoming;
-	JOT(8, "SNDCTL_DSP_SETTRIGGER\n");
-	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+	JOM(8, "SNDCTL_DSP_SETTRIGGER\n");
+	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
-	JOT(8, "........... %i=incoming\n", incoming);
-	JOT(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \
+	}
+	JOM(8, "........... %i=incoming\n", incoming);
+	JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \
 				"0x%x=PCM_ENABLE_OUTPUT\n", \
 					PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT);
 	;
@@ -2121,19 +2765,23 @@
 }
 case SNDCTL_DSP_GETBLKSIZE: {
 	int incoming;
-	JOT(8, "SNDCTL_DSP_GETBLKSIZE\n");
-	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int)))
+	JOM(8, "SNDCTL_DSP_GETBLKSIZE\n");
+	if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
-	JOT(8, "........... %i=incoming\n", incoming);
+	}
+	JOM(8, "........... %i=incoming\n", incoming);
 	incoming = peasycap->audio_bytes_per_fragment;
-	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int)))
+	if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
 case SNDCTL_DSP_GETISPACE: {
 	struct audio_buf_info audio_buf_info;
 
-	JOT(8, "SNDCTL_DSP_GETISPACE\n");
+	JOM(8, "SNDCTL_DSP_GETISPACE\n");
 
 	audio_buf_info.bytes      = peasycap->audio_bytes_per_fragment;
 	audio_buf_info.fragments  = 1;
@@ -2141,555 +2789,31 @@
 	audio_buf_info.fragstotal = 0;
 
 	if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
-								sizeof(int)))
+								sizeof(int))) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
+	}
 	break;
 }
+case 0x00005401:
+case 0x00005402:
+case 0x00005403:
+case 0x00005404:
+case 0x00005405:
+case 0x00005406: {
+	JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd);
+	mutex_unlock(&easycap_dongle[kd].mutex_audio);
+	return -ENOIOCTLCMD;
+}
 default: {
-	JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
-	POUT;
+	JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
+	mutex_unlock(&easycap_dongle[kd].mutex_audio);
 	return -ENOIOCTLCMD;
 }
 }
+mutex_unlock(&easycap_dongle[kd].mutex_audio);
 return 0;
 }
-
-long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct inode *inode = file->f_dentry->d_inode;
-	long ret;
-
-	lock_kernel();
-	ret = easysnd_ioctl_bkl(inode, file, cmd, arg);
-	unlock_kernel();
-
-	return ret;
-}
-
 /*****************************************************************************/
-int explain_ioctl(__u32 wot)
-{
-int k;
-/*---------------------------------------------------------------------------*/
-/*
- *  THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
- *  SHELL SCRIPT:
- *  #
- *  cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \
- *     grep "^#define VIDIOC_" - | grep -v "_OLD" - | \
- *     sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \
- *     sed -e "s/^#define /  {/;s/#define /, \"/;s/$/\"},/" | \
- *     sed -e "s,	,,g;s, ,,g" >ioctl.tmp
- *  echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp
- *  exit 0
- *  #
- * AND REINSTATING THE EXCISED "_OLD" CASES WERE LATER MANUALLY.
- *
- * THE DATA FOR THE ARRAY mess1 BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
- * SHELL SCRIPT:
- *  cat /usr/src/linux-headers-`uname -r`/include/linux/videodev.h | \
- *     grep "^#define VIDIOC" - | grep -v "_OLD" - | \
- *     sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \
- *     sed -e "s/^#define /  {/;s/#define /, \"/;s/$/\"},/" | \
- *     sed -e "s,   ,,g;s, ,,g" >ioctl.tmp
- *  echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp
- *  exit 0
- *  #
- */
-/*---------------------------------------------------------------------------*/
-static struct mess {
-	__u32 command;
-	char  name[64];
-} mess[] = {
-#if defined(VIDIOC_QUERYCAP)
-{VIDIOC_QUERYCAP, "VIDIOC_QUERYCAP"},
-#endif
-#if defined(VIDIOC_RESERVED)
-{VIDIOC_RESERVED, "VIDIOC_RESERVED"},
-#endif
-#if defined(VIDIOC_ENUM_FMT)
-{VIDIOC_ENUM_FMT, "VIDIOC_ENUM_FMT"},
-#endif
-#if defined(VIDIOC_G_FMT)
-{VIDIOC_G_FMT, "VIDIOC_G_FMT"},
-#endif
-#if defined(VIDIOC_S_FMT)
-{VIDIOC_S_FMT, "VIDIOC_S_FMT"},
-#endif
-#if defined(VIDIOC_REQBUFS)
-{VIDIOC_REQBUFS, "VIDIOC_REQBUFS"},
-#endif
-#if defined(VIDIOC_QUERYBUF)
-{VIDIOC_QUERYBUF, "VIDIOC_QUERYBUF"},
-#endif
-#if defined(VIDIOC_G_FBUF)
-{VIDIOC_G_FBUF, "VIDIOC_G_FBUF"},
-#endif
-#if defined(VIDIOC_S_FBUF)
-{VIDIOC_S_FBUF, "VIDIOC_S_FBUF"},
-#endif
-#if defined(VIDIOC_OVERLAY)
-{VIDIOC_OVERLAY, "VIDIOC_OVERLAY"},
-#endif
-#if defined(VIDIOC_QBUF)
-{VIDIOC_QBUF, "VIDIOC_QBUF"},
-#endif
-#if defined(VIDIOC_DQBUF)
-{VIDIOC_DQBUF, "VIDIOC_DQBUF"},
-#endif
-#if defined(VIDIOC_STREAMON)
-{VIDIOC_STREAMON, "VIDIOC_STREAMON"},
-#endif
-#if defined(VIDIOC_STREAMOFF)
-{VIDIOC_STREAMOFF, "VIDIOC_STREAMOFF"},
-#endif
-#if defined(VIDIOC_G_PARM)
-{VIDIOC_G_PARM, "VIDIOC_G_PARM"},
-#endif
-#if defined(VIDIOC_S_PARM)
-{VIDIOC_S_PARM, "VIDIOC_S_PARM"},
-#endif
-#if defined(VIDIOC_G_STD)
-{VIDIOC_G_STD, "VIDIOC_G_STD"},
-#endif
-#if defined(VIDIOC_S_STD)
-{VIDIOC_S_STD, "VIDIOC_S_STD"},
-#endif
-#if defined(VIDIOC_ENUMSTD)
-{VIDIOC_ENUMSTD, "VIDIOC_ENUMSTD"},
-#endif
-#if defined(VIDIOC_ENUMINPUT)
-{VIDIOC_ENUMINPUT, "VIDIOC_ENUMINPUT"},
-#endif
-#if defined(VIDIOC_G_CTRL)
-{VIDIOC_G_CTRL, "VIDIOC_G_CTRL"},
-#endif
-#if defined(VIDIOC_S_CTRL)
-{VIDIOC_S_CTRL, "VIDIOC_S_CTRL"},
-#endif
-#if defined(VIDIOC_G_TUNER)
-{VIDIOC_G_TUNER, "VIDIOC_G_TUNER"},
-#endif
-#if defined(VIDIOC_S_TUNER)
-{VIDIOC_S_TUNER, "VIDIOC_S_TUNER"},
-#endif
-#if defined(VIDIOC_G_AUDIO)
-{VIDIOC_G_AUDIO, "VIDIOC_G_AUDIO"},
-#endif
-#if defined(VIDIOC_S_AUDIO)
-{VIDIOC_S_AUDIO, "VIDIOC_S_AUDIO"},
-#endif
-#if defined(VIDIOC_QUERYCTRL)
-{VIDIOC_QUERYCTRL, "VIDIOC_QUERYCTRL"},
-#endif
-#if defined(VIDIOC_QUERYMENU)
-{VIDIOC_QUERYMENU, "VIDIOC_QUERYMENU"},
-#endif
-#if defined(VIDIOC_G_INPUT)
-{VIDIOC_G_INPUT, "VIDIOC_G_INPUT"},
-#endif
-#if defined(VIDIOC_S_INPUT)
-{VIDIOC_S_INPUT, "VIDIOC_S_INPUT"},
-#endif
-#if defined(VIDIOC_G_OUTPUT)
-{VIDIOC_G_OUTPUT, "VIDIOC_G_OUTPUT"},
-#endif
-#if defined(VIDIOC_S_OUTPUT)
-{VIDIOC_S_OUTPUT, "VIDIOC_S_OUTPUT"},
-#endif
-#if defined(VIDIOC_ENUMOUTPUT)
-{VIDIOC_ENUMOUTPUT, "VIDIOC_ENUMOUTPUT"},
-#endif
-#if defined(VIDIOC_G_AUDOUT)
-{VIDIOC_G_AUDOUT, "VIDIOC_G_AUDOUT"},
-#endif
-#if defined(VIDIOC_S_AUDOUT)
-{VIDIOC_S_AUDOUT, "VIDIOC_S_AUDOUT"},
-#endif
-#if defined(VIDIOC_G_MODULATOR)
-{VIDIOC_G_MODULATOR, "VIDIOC_G_MODULATOR"},
-#endif
-#if defined(VIDIOC_S_MODULATOR)
-{VIDIOC_S_MODULATOR, "VIDIOC_S_MODULATOR"},
-#endif
-#if defined(VIDIOC_G_FREQUENCY)
-{VIDIOC_G_FREQUENCY, "VIDIOC_G_FREQUENCY"},
-#endif
-#if defined(VIDIOC_S_FREQUENCY)
-{VIDIOC_S_FREQUENCY, "VIDIOC_S_FREQUENCY"},
-#endif
-#if defined(VIDIOC_CROPCAP)
-{VIDIOC_CROPCAP, "VIDIOC_CROPCAP"},
-#endif
-#if defined(VIDIOC_G_CROP)
-{VIDIOC_G_CROP, "VIDIOC_G_CROP"},
-#endif
-#if defined(VIDIOC_S_CROP)
-{VIDIOC_S_CROP, "VIDIOC_S_CROP"},
-#endif
-#if defined(VIDIOC_G_JPEGCOMP)
-{VIDIOC_G_JPEGCOMP, "VIDIOC_G_JPEGCOMP"},
-#endif
-#if defined(VIDIOC_S_JPEGCOMP)
-{VIDIOC_S_JPEGCOMP, "VIDIOC_S_JPEGCOMP"},
-#endif
-#if defined(VIDIOC_QUERYSTD)
-{VIDIOC_QUERYSTD, "VIDIOC_QUERYSTD"},
-#endif
-#if defined(VIDIOC_TRY_FMT)
-{VIDIOC_TRY_FMT, "VIDIOC_TRY_FMT"},
-#endif
-#if defined(VIDIOC_ENUMAUDIO)
-{VIDIOC_ENUMAUDIO, "VIDIOC_ENUMAUDIO"},
-#endif
-#if defined(VIDIOC_ENUMAUDOUT)
-{VIDIOC_ENUMAUDOUT, "VIDIOC_ENUMAUDOUT"},
-#endif
-#if defined(VIDIOC_G_PRIORITY)
-{VIDIOC_G_PRIORITY, "VIDIOC_G_PRIORITY"},
-#endif
-#if defined(VIDIOC_S_PRIORITY)
-{VIDIOC_S_PRIORITY, "VIDIOC_S_PRIORITY"},
-#endif
-#if defined(VIDIOC_G_SLICED_VBI_CAP)
-{VIDIOC_G_SLICED_VBI_CAP, "VIDIOC_G_SLICED_VBI_CAP"},
-#endif
-#if defined(VIDIOC_LOG_STATUS)
-{VIDIOC_LOG_STATUS, "VIDIOC_LOG_STATUS"},
-#endif
-#if defined(VIDIOC_G_EXT_CTRLS)
-{VIDIOC_G_EXT_CTRLS, "VIDIOC_G_EXT_CTRLS"},
-#endif
-#if defined(VIDIOC_S_EXT_CTRLS)
-{VIDIOC_S_EXT_CTRLS, "VIDIOC_S_EXT_CTRLS"},
-#endif
-#if defined(VIDIOC_TRY_EXT_CTRLS)
-{VIDIOC_TRY_EXT_CTRLS, "VIDIOC_TRY_EXT_CTRLS"},
-#endif
-#if defined(VIDIOC_ENUM_FRAMESIZES)
-{VIDIOC_ENUM_FRAMESIZES, "VIDIOC_ENUM_FRAMESIZES"},
-#endif
-#if defined(VIDIOC_ENUM_FRAMEINTERVALS)
-{VIDIOC_ENUM_FRAMEINTERVALS, "VIDIOC_ENUM_FRAMEINTERVALS"},
-#endif
-#if defined(VIDIOC_G_ENC_INDEX)
-{VIDIOC_G_ENC_INDEX, "VIDIOC_G_ENC_INDEX"},
-#endif
-#if defined(VIDIOC_ENCODER_CMD)
-{VIDIOC_ENCODER_CMD, "VIDIOC_ENCODER_CMD"},
-#endif
-#if defined(VIDIOC_TRY_ENCODER_CMD)
-{VIDIOC_TRY_ENCODER_CMD, "VIDIOC_TRY_ENCODER_CMD"},
-#endif
-#if defined(VIDIOC_G_CHIP_IDENT)
-{VIDIOC_G_CHIP_IDENT, "VIDIOC_G_CHIP_IDENT"},
-#endif
 
-#if defined(VIDIOC_OVERLAY_OLD)
-{VIDIOC_OVERLAY_OLD, "VIDIOC_OVERLAY_OLD"},
-#endif
-#if defined(VIDIOC_S_PARM_OLD)
-{VIDIOC_S_PARM_OLD, "VIDIOC_S_PARM_OLD"},
-#endif
-#if defined(VIDIOC_S_CTRL_OLD)
-{VIDIOC_S_CTRL_OLD, "VIDIOC_S_CTRL_OLD"},
-#endif
-#if defined(VIDIOC_G_AUDIO_OLD)
-{VIDIOC_G_AUDIO_OLD, "VIDIOC_G_AUDIO_OLD"},
-#endif
-#if defined(VIDIOC_G_AUDOUT_OLD)
-{VIDIOC_G_AUDOUT_OLD, "VIDIOC_G_AUDOUT_OLD"},
-#endif
-#if defined(VIDIOC_CROPCAP_OLD)
-{VIDIOC_CROPCAP_OLD, "VIDIOC_CROPCAP_OLD"},
-#endif
-{0xFFFFFFFF, ""}
-};
 
-static struct mess mess1[] = \
-{
-#if defined(VIDIOCGCAP)
-{VIDIOCGCAP, "VIDIOCGCAP"},
-#endif
-#if defined(VIDIOCGCHAN)
-{VIDIOCGCHAN, "VIDIOCGCHAN"},
-#endif
-#if defined(VIDIOCSCHAN)
-{VIDIOCSCHAN, "VIDIOCSCHAN"},
-#endif
-#if defined(VIDIOCGTUNER)
-{VIDIOCGTUNER, "VIDIOCGTUNER"},
-#endif
-#if defined(VIDIOCSTUNER)
-{VIDIOCSTUNER, "VIDIOCSTUNER"},
-#endif
-#if defined(VIDIOCGPICT)
-{VIDIOCGPICT, "VIDIOCGPICT"},
-#endif
-#if defined(VIDIOCSPICT)
-{VIDIOCSPICT, "VIDIOCSPICT"},
-#endif
-#if defined(VIDIOCCAPTURE)
-{VIDIOCCAPTURE, "VIDIOCCAPTURE"},
-#endif
-#if defined(VIDIOCGWIN)
-{VIDIOCGWIN, "VIDIOCGWIN"},
-#endif
-#if defined(VIDIOCSWIN)
-{VIDIOCSWIN, "VIDIOCSWIN"},
-#endif
-#if defined(VIDIOCGFBUF)
-{VIDIOCGFBUF, "VIDIOCGFBUF"},
-#endif
-#if defined(VIDIOCSFBUF)
-{VIDIOCSFBUF, "VIDIOCSFBUF"},
-#endif
-#if defined(VIDIOCKEY)
-{VIDIOCKEY, "VIDIOCKEY"},
-#endif
-#if defined(VIDIOCGFREQ)
-{VIDIOCGFREQ, "VIDIOCGFREQ"},
-#endif
-#if defined(VIDIOCSFREQ)
-{VIDIOCSFREQ, "VIDIOCSFREQ"},
-#endif
-#if defined(VIDIOCGAUDIO)
-{VIDIOCGAUDIO, "VIDIOCGAUDIO"},
-#endif
-#if defined(VIDIOCSAUDIO)
-{VIDIOCSAUDIO, "VIDIOCSAUDIO"},
-#endif
-#if defined(VIDIOCSYNC)
-{VIDIOCSYNC, "VIDIOCSYNC"},
-#endif
-#if defined(VIDIOCMCAPTURE)
-{VIDIOCMCAPTURE, "VIDIOCMCAPTURE"},
-#endif
-#if defined(VIDIOCGMBUF)
-{VIDIOCGMBUF, "VIDIOCGMBUF"},
-#endif
-#if defined(VIDIOCGUNIT)
-{VIDIOCGUNIT, "VIDIOCGUNIT"},
-#endif
-#if defined(VIDIOCGCAPTURE)
-{VIDIOCGCAPTURE, "VIDIOCGCAPTURE"},
-#endif
-#if defined(VIDIOCSCAPTURE)
-{VIDIOCSCAPTURE, "VIDIOCSCAPTURE"},
-#endif
-#if defined(VIDIOCSPLAYMODE)
-{VIDIOCSPLAYMODE, "VIDIOCSPLAYMODE"},
-#endif
-#if defined(VIDIOCSWRITEMODE)
-{VIDIOCSWRITEMODE, "VIDIOCSWRITEMODE"},
-#endif
-#if defined(VIDIOCGPLAYINFO)
-{VIDIOCGPLAYINFO, "VIDIOCGPLAYINFO"},
-#endif
-#if defined(VIDIOCSMICROCODE)
-{VIDIOCSMICROCODE, "VIDIOCSMICROCODE"},
-#endif
-{0xFFFFFFFF, ""}
-};
-
-k = 0;
-while (mess[k].name[0]) {
-	if (wot == mess[k].command) {
-		JOT(8, "ioctl 0x%08X is %s\n", \
-					mess[k].command, &mess[k].name[0]);
-		return 0;
-	}
-	k++;
-}
-JOT(8, "ioctl 0x%08X is not in videodev2.h\n", wot);
-
-k = 0;
-while (mess1[k].name[0]) {
-	if (wot == mess1[k].command) {
-		JOT(8, "ioctl 0x%08X is %s (V4L1)\n", \
-					mess1[k].command, &mess1[k].name[0]);
-		return 0;
-	}
-	k++;
-}
-JOT(8, "ioctl 0x%08X is not in videodev.h\n", wot);
-return -1;
-}
-/*****************************************************************************/
-int explain_cid(__u32 wot)
-{
-int k;
-/*---------------------------------------------------------------------------*/
-/*
- *  THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING
- *  SHELL SCRIPT:
- *  #
- *  cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \
- *     grep "^#define V4L2_CID_" |  \
- *     sed -e "s,(.*$,,;p" | sed -e "N;s,\n,, " | \
- *     sed -e "s/^#define /  {/;s/#define /, \"/;s/$/\"},/" | \
- *     sed -e "s,	,,g;s, ,,g" | grep -v "_BASE" | grep -v "MPEG" >cid.tmp
- *  echo "{0xFFFFFFFF,\"\"}" >>cid.tmp
- *  exit 0
- *  #
- */
-/*---------------------------------------------------------------------------*/
-static struct mess
-{
-__u32 command;
-char  name[64];
-} mess[] = {
-#if defined(V4L2_CID_USER_CLASS)
-{V4L2_CID_USER_CLASS, "V4L2_CID_USER_CLASS"},
-#endif
-#if defined(V4L2_CID_BRIGHTNESS)
-{V4L2_CID_BRIGHTNESS, "V4L2_CID_BRIGHTNESS"},
-#endif
-#if defined(V4L2_CID_CONTRAST)
-{V4L2_CID_CONTRAST, "V4L2_CID_CONTRAST"},
-#endif
-#if defined(V4L2_CID_SATURATION)
-{V4L2_CID_SATURATION, "V4L2_CID_SATURATION"},
-#endif
-#if defined(V4L2_CID_HUE)
-{V4L2_CID_HUE, "V4L2_CID_HUE"},
-#endif
-#if defined(V4L2_CID_AUDIO_VOLUME)
-{V4L2_CID_AUDIO_VOLUME, "V4L2_CID_AUDIO_VOLUME"},
-#endif
-#if defined(V4L2_CID_AUDIO_BALANCE)
-{V4L2_CID_AUDIO_BALANCE, "V4L2_CID_AUDIO_BALANCE"},
-#endif
-#if defined(V4L2_CID_AUDIO_BASS)
-{V4L2_CID_AUDIO_BASS, "V4L2_CID_AUDIO_BASS"},
-#endif
-#if defined(V4L2_CID_AUDIO_TREBLE)
-{V4L2_CID_AUDIO_TREBLE, "V4L2_CID_AUDIO_TREBLE"},
-#endif
-#if defined(V4L2_CID_AUDIO_MUTE)
-{V4L2_CID_AUDIO_MUTE, "V4L2_CID_AUDIO_MUTE"},
-#endif
-#if defined(V4L2_CID_AUDIO_LOUDNESS)
-{V4L2_CID_AUDIO_LOUDNESS, "V4L2_CID_AUDIO_LOUDNESS"},
-#endif
-#if defined(V4L2_CID_BLACK_LEVEL)
-{V4L2_CID_BLACK_LEVEL, "V4L2_CID_BLACK_LEVEL"},
-#endif
-#if defined(V4L2_CID_AUTO_WHITE_BALANCE)
-{V4L2_CID_AUTO_WHITE_BALANCE, "V4L2_CID_AUTO_WHITE_BALANCE"},
-#endif
-#if defined(V4L2_CID_DO_WHITE_BALANCE)
-{V4L2_CID_DO_WHITE_BALANCE, "V4L2_CID_DO_WHITE_BALANCE"},
-#endif
-#if defined(V4L2_CID_RED_BALANCE)
-{V4L2_CID_RED_BALANCE, "V4L2_CID_RED_BALANCE"},
-#endif
-#if defined(V4L2_CID_BLUE_BALANCE)
-{V4L2_CID_BLUE_BALANCE, "V4L2_CID_BLUE_BALANCE"},
-#endif
-#if defined(V4L2_CID_GAMMA)
-{V4L2_CID_GAMMA, "V4L2_CID_GAMMA"},
-#endif
-#if defined(V4L2_CID_WHITENESS)
-{V4L2_CID_WHITENESS, "V4L2_CID_WHITENESS"},
-#endif
-#if defined(V4L2_CID_EXPOSURE)
-{V4L2_CID_EXPOSURE, "V4L2_CID_EXPOSURE"},
-#endif
-#if defined(V4L2_CID_AUTOGAIN)
-{V4L2_CID_AUTOGAIN, "V4L2_CID_AUTOGAIN"},
-#endif
-#if defined(V4L2_CID_GAIN)
-{V4L2_CID_GAIN, "V4L2_CID_GAIN"},
-#endif
-#if defined(V4L2_CID_HFLIP)
-{V4L2_CID_HFLIP, "V4L2_CID_HFLIP"},
-#endif
-#if defined(V4L2_CID_VFLIP)
-{V4L2_CID_VFLIP, "V4L2_CID_VFLIP"},
-#endif
-#if defined(V4L2_CID_HCENTER)
-{V4L2_CID_HCENTER, "V4L2_CID_HCENTER"},
-#endif
-#if defined(V4L2_CID_VCENTER)
-{V4L2_CID_VCENTER, "V4L2_CID_VCENTER"},
-#endif
-#if defined(V4L2_CID_POWER_LINE_FREQUENCY)
-{V4L2_CID_POWER_LINE_FREQUENCY, "V4L2_CID_POWER_LINE_FREQUENCY"},
-#endif
-#if defined(V4L2_CID_HUE_AUTO)
-{V4L2_CID_HUE_AUTO, "V4L2_CID_HUE_AUTO"},
-#endif
-#if defined(V4L2_CID_WHITE_BALANCE_TEMPERATURE)
-{V4L2_CID_WHITE_BALANCE_TEMPERATURE, "V4L2_CID_WHITE_BALANCE_TEMPERATURE"},
-#endif
-#if defined(V4L2_CID_SHARPNESS)
-{V4L2_CID_SHARPNESS, "V4L2_CID_SHARPNESS"},
-#endif
-#if defined(V4L2_CID_BACKLIGHT_COMPENSATION)
-{V4L2_CID_BACKLIGHT_COMPENSATION, "V4L2_CID_BACKLIGHT_COMPENSATION"},
-#endif
-#if defined(V4L2_CID_CHROMA_AGC)
-{V4L2_CID_CHROMA_AGC, "V4L2_CID_CHROMA_AGC"},
-#endif
-#if defined(V4L2_CID_COLOR_KILLER)
-{V4L2_CID_COLOR_KILLER, "V4L2_CID_COLOR_KILLER"},
-#endif
-#if defined(V4L2_CID_LASTP1)
-{V4L2_CID_LASTP1, "V4L2_CID_LASTP1"},
-#endif
-#if defined(V4L2_CID_CAMERA_CLASS)
-{V4L2_CID_CAMERA_CLASS, "V4L2_CID_CAMERA_CLASS"},
-#endif
-#if defined(V4L2_CID_EXPOSURE_AUTO)
-{V4L2_CID_EXPOSURE_AUTO, "V4L2_CID_EXPOSURE_AUTO"},
-#endif
-#if defined(V4L2_CID_EXPOSURE_ABSOLUTE)
-{V4L2_CID_EXPOSURE_ABSOLUTE, "V4L2_CID_EXPOSURE_ABSOLUTE"},
-#endif
-#if defined(V4L2_CID_EXPOSURE_AUTO_PRIORITY)
-{V4L2_CID_EXPOSURE_AUTO_PRIORITY, "V4L2_CID_EXPOSURE_AUTO_PRIORITY"},
-#endif
-#if defined(V4L2_CID_PAN_RELATIVE)
-{V4L2_CID_PAN_RELATIVE, "V4L2_CID_PAN_RELATIVE"},
-#endif
-#if defined(V4L2_CID_TILT_RELATIVE)
-{V4L2_CID_TILT_RELATIVE, "V4L2_CID_TILT_RELATIVE"},
-#endif
-#if defined(V4L2_CID_PAN_RESET)
-{V4L2_CID_PAN_RESET, "V4L2_CID_PAN_RESET"},
-#endif
-#if defined(V4L2_CID_TILT_RESET)
-{V4L2_CID_TILT_RESET, "V4L2_CID_TILT_RESET"},
-#endif
-#if defined(V4L2_CID_PAN_ABSOLUTE)
-{V4L2_CID_PAN_ABSOLUTE, "V4L2_CID_PAN_ABSOLUTE"},
-#endif
-#if defined(V4L2_CID_TILT_ABSOLUTE)
-{V4L2_CID_TILT_ABSOLUTE, "V4L2_CID_TILT_ABSOLUTE"},
-#endif
-#if defined(V4L2_CID_FOCUS_ABSOLUTE)
-{V4L2_CID_FOCUS_ABSOLUTE, "V4L2_CID_FOCUS_ABSOLUTE"},
-#endif
-#if defined(V4L2_CID_FOCUS_RELATIVE)
-{V4L2_CID_FOCUS_RELATIVE, "V4L2_CID_FOCUS_RELATIVE"},
-#endif
-#if defined(V4L2_CID_FOCUS_AUTO)
-{V4L2_CID_FOCUS_AUTO, "V4L2_CID_FOCUS_AUTO"},
-#endif
-{0xFFFFFFFF, ""}
-};
-
-k = 0;
-while (mess[k].name[0]) {
-	if (wot == mess[k].command) {
-		JOT(8, "ioctl 0x%08X is %s\n", \
-					mess[k].command, &mess[k].name[0]);
-		return 0;
-	}
-	k++;
-}
-JOT(8, "cid 0x%08X is not in videodev2.h\n", wot);
-return -1;
-}
-/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c
index ad1fc4c..b75db82b 100644
--- a/drivers/staging/easycap/easycap_low.c
+++ b/drivers/staging/easycap/easycap_low.c
@@ -38,148 +38,209 @@
 */
 /****************************************************************************/
 
-#include "easycap_debug.h"
 #include "easycap.h"
+#include "easycap_debug.h"
 
 /*--------------------------------------------------------------------------*/
-const struct stk1160config { int reg; int set; } stk1160config[256] = {
-	{0x000, 0x0098},
-	{0x002, 0x0093},
+const struct stk1160config { int reg; int set; } stk1160configPAL[256] = {
+		{0x000, 0x0098},
+		{0x002, 0x0093},
 
-	{0x001, 0x0003},
-	{0x003, 0x0080},
-	{0x00D, 0x0000},
-	{0x00F, 0x0002},
-	{0x018, 0x0010},
-	{0x019, 0x0000},
-	{0x01A, 0x0014},
-	{0x01B, 0x000E},
-	{0x01C, 0x0046},
+		{0x001, 0x0003},
+		{0x003, 0x0080},
+		{0x00D, 0x0000},
+		{0x00F, 0x0002},
+		{0x018, 0x0010},
+		{0x019, 0x0000},
+		{0x01A, 0x0014},
+		{0x01B, 0x000E},
+		{0x01C, 0x0046},
 
-	{0x100, 0x0033},
-	{0x103, 0x0000},
-	{0x104, 0x0000},
-	{0x105, 0x0000},
-	{0x106, 0x0000},
+		{0x100, 0x0033},
+		{0x103, 0x0000},
+		{0x104, 0x0000},
+		{0x105, 0x0000},
+		{0x106, 0x0000},
 
-#if defined(PREFER_NTSC)
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/*
+ *  RESOLUTION 640x480
+*/
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+		{0x110, 0x0008},
+		{0x111, 0x0000},
+		{0x112, 0x0020},
+		{0x113, 0x0000},
+		{0x114, 0x0508},
+		{0x115, 0x0005},
+		{0x116, 0x0110},
+		{0x117, 0x0001},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
-#undef  OLDMARGIN
-#if defined(OLDMARGIN)
-	{0x110, 0x0008},
-#else
-	{0x110, 0x0014},
-#endif /*OLDMARGIN*/
+		{0x202, 0x000F},
+		{0x203, 0x004A},
+		{0x2FF, 0x0000},
 
-	{0x111, 0x0000},
-	{0x112, 0x0003},
-	{0x113, 0x0000},
-
-#if defined(OLDMARGIN)
-	{0x114, 0x0508},
-#else
-	{0x114, 0x0514},
-#endif /*OLDMARGIN*/
-
-	{0x115, 0x0005},
-	{0x116, 0x00F3},
-	{0x117, 0x0000},
-
-#else /* ! PREFER_NTSC*/
-
-#if defined(OLDMARGIN)
-	{0x110, 0x0008},
-#else
-	{0x110, 0x0014},
-#endif /*OLDMARGIN*/
-
-	{0x111, 0x0000},
-	{0x112, 0x0020},
-	{0x113, 0x0000},
-
-#if defined(OLDMARGIN)
-	{0x114, 0x0508},
-#else
-	{0x114, 0x0514},
-#endif /*OLDMARGIN*/
-
-	{0x115, 0x0005},
-	{0x116, 0x0110},
-	{0x117, 0x0001},
-
-#endif /* ! PREFER_NTSC*/
-
-	{0x202, 0x000F},
-	{0x203, 0x004A},
-	{0x2FF, 0x0000},
-/*---------------------------------------------------------------------------*/
-	{0xFFF, 0xFFFF}
-	};
+		{0xFFF, 0xFFFF}
+};
 /*--------------------------------------------------------------------------*/
-const struct saa7113config { int reg; int set; } saa7113config[256] = {
-	{0x01, 0x08},
-	{0x02, 0x80},
-	{0x03, 0x33},
-	{0x04, 0x00},
-	{0x05, 0x00},
-	{0x06, 0xE9},
-	{0x07, 0x0D},
-#if defined(PREFER_NTSC)
-	{0x08, 0x78},
+const struct stk1160config stk1160configNTSC[256] = {
+		{0x000, 0x0098},
+		{0x002, 0x0093},
+
+		{0x001, 0x0003},
+		{0x003, 0x0080},
+		{0x00D, 0x0000},
+		{0x00F, 0x0002},
+		{0x018, 0x0010},
+		{0x019, 0x0000},
+		{0x01A, 0x0014},
+		{0x01B, 0x000E},
+		{0x01C, 0x0046},
+
+		{0x100, 0x0033},
+		{0x103, 0x0000},
+		{0x104, 0x0000},
+		{0x105, 0x0000},
+		{0x106, 0x0000},
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/*
+ *  RESOLUTION 640x480
+*/
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+		{0x110, 0x0008},
+		{0x111, 0x0000},
+		{0x112, 0x0003},
+		{0x113, 0x0000},
+		{0x114, 0x0508},
+		{0x115, 0x0005},
+		{0x116, 0x00F3},
+		{0x117, 0x0000},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+		{0x202, 0x000F},
+		{0x203, 0x004A},
+		{0x2FF, 0x0000},
+
+		{0xFFF, 0xFFFF}
+};
+/*--------------------------------------------------------------------------*/
+const struct saa7113config { int reg; int set; } saa7113configPAL[256] = {
+		{0x01, 0x08},
+#if defined(ANTIALIAS)
+		{0x02, 0xC0},
 #else
-	{0x08, 0x38},
-#endif /* ! PREFER_NTSC*/
-	{0x09, 0x00},
-	{0x0A, SAA_0A_DEFAULT},
-	{0x0B, SAA_0B_DEFAULT},
-	{0x0C, SAA_0C_DEFAULT},
-	{0x0D, SAA_0D_DEFAULT},
-	{0x0E, 0x01},
-	{0x0F, 0x36},
-	{0x10, 0x00},
-	{0x11, 0x0C},
-	{0x12, 0xE7},
-	{0x13, 0x00},
-	{0x15, 0x00},
-	{0x16, 0x00},
-#if defined(PREFER_NTSC)
-	{0x40, 0x82},
+		{0x02, 0x80},
+#endif /*ANTIALIAS*/
+		{0x03, 0x33},
+		{0x04, 0x00},
+		{0x05, 0x00},
+		{0x06, 0xE9},
+		{0x07, 0x0D},
+		{0x08, 0x38},
+		{0x09, 0x00},
+		{0x0A, SAA_0A_DEFAULT},
+		{0x0B, SAA_0B_DEFAULT},
+		{0x0C, SAA_0C_DEFAULT},
+		{0x0D, SAA_0D_DEFAULT},
+		{0x0E, 0x01},
+		{0x0F, 0x36},
+		{0x10, 0x00},
+		{0x11, 0x0C},
+		{0x12, 0xE7},
+		{0x13, 0x00},
+		{0x15, 0x00},
+		{0x16, 0x00},
+		{0x40, 0x02},
+		{0x41, 0xFF},
+		{0x42, 0xFF},
+		{0x43, 0xFF},
+		{0x44, 0xFF},
+		{0x45, 0xFF},
+		{0x46, 0xFF},
+		{0x47, 0xFF},
+		{0x48, 0xFF},
+		{0x49, 0xFF},
+		{0x4A, 0xFF},
+		{0x4B, 0xFF},
+		{0x4C, 0xFF},
+		{0x4D, 0xFF},
+		{0x4E, 0xFF},
+		{0x4F, 0xFF},
+		{0x50, 0xFF},
+		{0x51, 0xFF},
+		{0x52, 0xFF},
+		{0x53, 0xFF},
+		{0x54, 0xFF},
+		{0x55, 0xFF},
+		{0x56, 0xFF},
+		{0x57, 0xFF},
+		{0x58, 0x40},
+		{0x59, 0x54},
+		{0x5A, 0x07},
+		{0x5B, 0x83},
+
+		{0xFF, 0xFF}
+};
+/*--------------------------------------------------------------------------*/
+const struct saa7113config saa7113configNTSC[256] = {
+		{0x01, 0x08},
+#if defined(ANTIALIAS)
+		{0x02, 0xC0},
 #else
-	{0x40, 0x02},
-#endif /* ! PREFER_NTSC*/
-	{0x41, 0xFF},
-	{0x42, 0xFF},
-	{0x43, 0xFF},
-	{0x44, 0xFF},
-	{0x45, 0xFF},
-	{0x46, 0xFF},
-	{0x47, 0xFF},
-	{0x48, 0xFF},
-	{0x49, 0xFF},
-	{0x4A, 0xFF},
-	{0x4B, 0xFF},
-	{0x4C, 0xFF},
-	{0x4D, 0xFF},
-	{0x4E, 0xFF},
-	{0x4F, 0xFF},
-	{0x50, 0xFF},
-	{0x51, 0xFF},
-	{0x52, 0xFF},
-	{0x53, 0xFF},
-	{0x54, 0xFF},
-	{0x55, 0xFF},
-	{0x56, 0xFF},
-	{0x57, 0xFF},
-	{0x58, 0x40},
-	{0x59, 0x54},
-#if defined(PREFER_NTSC)
-	{0x5A, 0x0A},
-#else
-	{0x5A, 0x07},
-#endif /* ! PREFER_NTSC*/
-	{0x5B, 0x83},
-	{0xFF, 0xFF}
-	};
+		{0x02, 0x80},
+#endif /*ANTIALIAS*/
+		{0x03, 0x33},
+		{0x04, 0x00},
+		{0x05, 0x00},
+		{0x06, 0xE9},
+		{0x07, 0x0D},
+		{0x08, 0x78},
+		{0x09, 0x00},
+		{0x0A, SAA_0A_DEFAULT},
+		{0x0B, SAA_0B_DEFAULT},
+		{0x0C, SAA_0C_DEFAULT},
+		{0x0D, SAA_0D_DEFAULT},
+		{0x0E, 0x01},
+		{0x0F, 0x36},
+		{0x10, 0x00},
+		{0x11, 0x0C},
+		{0x12, 0xE7},
+		{0x13, 0x00},
+		{0x15, 0x00},
+		{0x16, 0x00},
+		{0x40, 0x82},
+		{0x41, 0xFF},
+		{0x42, 0xFF},
+		{0x43, 0xFF},
+		{0x44, 0xFF},
+		{0x45, 0xFF},
+		{0x46, 0xFF},
+		{0x47, 0xFF},
+		{0x48, 0xFF},
+		{0x49, 0xFF},
+		{0x4A, 0xFF},
+		{0x4B, 0xFF},
+		{0x4C, 0xFF},
+		{0x4D, 0xFF},
+		{0x4E, 0xFF},
+		{0x4F, 0xFF},
+		{0x50, 0xFF},
+		{0x51, 0xFF},
+		{0x52, 0xFF},
+		{0x53, 0xFF},
+		{0x54, 0xFF},
+		{0x55, 0xFF},
+		{0x56, 0xFF},
+		{0x57, 0xFF},
+		{0x58, 0x40},
+		{0x59, 0x54},
+		{0x5A, 0x0A},
+		{0x5B, 0x83},
+
+		{0xFF, 0xFF}
+};
 /*--------------------------------------------------------------------------*/
 
 /****************************************************************************/
@@ -187,6 +248,9 @@
 confirm_resolution(struct usb_device *p)
 {
 __u8 get0, get1, get2, get3, get4, get5, get6, get7;
+
+if (NULL == p)
+	return -ENODEV;
 GET(p, 0x0110, &get0);
 GET(p, 0x0111, &get1);
 GET(p, 0x0112, &get2);
@@ -227,6 +291,8 @@
 __u16 get2;
 __u8 igot;
 
+if (NULL == p)
+	return -ENODEV;
 GET(p, 0x0100, &igot);  get2 = 0x80 & igot;
 if (0x80 == get2)
 	JOT(8, "confirm_stream:  OK\n");
@@ -236,15 +302,24 @@
 }
 /****************************************************************************/
 int
-setup_stk(struct usb_device *p)
+setup_stk(struct usb_device *p, bool ntsc)
 {
 int i0;
 
+if (NULL == p)
+	return -ENODEV;
 i0 = 0;
-while (0xFFF != stk1160config[i0].reg) {
-	SET(p, stk1160config[i0].reg, stk1160config[i0].set);
-	i0++;
+if (true == ntsc) {
+	while (0xFFF != stk1160configNTSC[i0].reg) {
+		SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set);
+		i0++;
 	}
+} else {
+	while (0xFFF != stk1160configPAL[i0].reg) {
+		SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set);
+		i0++;
+	}
+}
 
 write_300(p);
 
@@ -252,19 +327,26 @@
 }
 /****************************************************************************/
 int
-setup_saa(struct usb_device *p)
+setup_saa(struct usb_device *p, bool ntsc)
 {
 int i0, ir;
 
-
-set2to78(p);
-
-
+if (NULL == p)
+	return -ENODEV;
 i0 = 0;
-while (0xFF != saa7113config[i0].reg) {
-	ir = write_saa(p, saa7113config[i0].reg, saa7113config[i0].set);
-	i0++;
+if (true == ntsc) {
+	while (0xFF != saa7113configNTSC[i0].reg) {
+		ir = write_saa(p, saa7113configNTSC[i0].reg, \
+					saa7113configNTSC[i0].set);
+		i0++;
 	}
+} else {
+	while (0xFF != saa7113configPAL[i0].reg) {
+		ir = write_saa(p, saa7113configPAL[i0].reg, \
+					saa7113configPAL[i0].set);
+		i0++;
+	}
+}
 return 0;
 }
 /****************************************************************************/
@@ -273,6 +355,8 @@
 {
 __u8 igot0, igot2;
 
+if (NULL == p)
+	return -ENODEV;
 GET(p, 0x0002, &igot2);
 GET(p, 0x0000, &igot0);
 SET(p, 0x0002, set2);
@@ -283,6 +367,8 @@
 int
 write_saa(struct usb_device *p, __u16 reg0, __u16 set0)
 {
+if (NULL == p)
+	return -ENODEV;
 SET(p, 0x200, 0x00);
 SET(p, 0x204, reg0);
 SET(p, 0x205, set0);
@@ -306,6 +392,8 @@
 __u16 got502, got503;
 __u16 set502, set503;
 
+if (NULL == p)
+	return -ENODEV;
 SET(p, 0x0504, reg0);
 SET(p, 0x0500, 0x008B);
 
@@ -341,6 +429,8 @@
 __u8 igot;
 __u16 got502, got503;
 
+if (NULL == p)
+	return -ENODEV;
 SET(p, 0x0504, reg0);
 SET(p, 0x0500, 0x008B);
 
@@ -360,6 +450,8 @@
 int
 write_300(struct usb_device *p)
 {
+if (NULL == p)
+	return -ENODEV;
 SET(p, 0x300, 0x0012);
 SET(p, 0x350, 0x002D);
 SET(p, 0x351, 0x0001);
@@ -376,24 +468,48 @@
  */
 /*--------------------------------------------------------------------------*/
 int
-check_saa(struct usb_device *p)
+check_saa(struct usb_device *p, bool ntsc)
 {
 int i0, ir, rc;
+
+if (NULL == p)
+	return -ENODEV;
 i0 = 0;
-
 rc = 0;
-while (0xFF != saa7113config[i0].reg) {
-	if (0x0F == saa7113config[i0].reg) {
-		i0++; continue;
-	}
+if (true == ntsc) {
+	while (0xFF != saa7113configNTSC[i0].reg) {
+		if (0x0F == saa7113configNTSC[i0].reg) {
+			i0++;
+			continue;
+		}
 
-	ir = read_saa(p, saa7113config[i0].reg);
-	if (ir != saa7113config[i0].set) {
-		SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", \
-			saa7113config[i0].reg, ir, saa7113config[i0].set);
-		rc--;
+		ir = read_saa(p, saa7113configNTSC[i0].reg);
+		if (ir != saa7113configNTSC[i0].set) {
+			SAY("SAA register 0x%02X has 0x%02X, " \
+						"expected 0x%02X\n", \
+						saa7113configNTSC[i0].reg, \
+						ir, saa7113configNTSC[i0].set);
+			rc--;
+		}
+		i0++;
 	}
-	i0++;
+} else {
+	while (0xFF != saa7113configPAL[i0].reg) {
+		if (0x0F == saa7113configPAL[i0].reg) {
+			i0++;
+			continue;
+		}
+
+		ir = read_saa(p, saa7113configPAL[i0].reg);
+		if (ir != saa7113configPAL[i0].set) {
+			SAY("SAA register 0x%02X has 0x%02X, " \
+						"expected 0x%02X\n", \
+						saa7113configPAL[i0].reg, \
+						ir, saa7113configPAL[i0].set);
+			rc--;
+		}
+		i0++;
+	}
 }
 if (-8 > rc)
 	return rc;
@@ -406,6 +522,8 @@
 {
 int rc;
 
+if (NULL == p)
+	return -ENODEV;
 rc = read_saa(p, 0x1F);
 if ((0 > rc) || (0x02 & rc))
 	return 1 ;
@@ -416,29 +534,46 @@
 int
 ready_saa(struct usb_device *p)
 {
-int j, rc;
-static int max = 10;
-
+int j, rc, rate;
+const int max = 5, marktime = PATIENCE/5;
+/*--------------------------------------------------------------------------*/
+/*
+ *   RETURNS    0     FOR INTERLACED       50 Hz
+ *              1     FOR NON-INTERLACED   50 Hz
+ *              2     FOR INTERLACED       60 Hz
+ *              3     FOR NON-INTERLACED   60 Hz
+*/
+/*--------------------------------------------------------------------------*/
+if (NULL == p)
+	return -ENODEV;
 j = 0;
 while (max > j) {
 	rc = read_saa(p, 0x1F);
 	if (0 <= rc) {
-		if ((1 == (0x01 & rc))&&(0 == (0x40 & rc)))
+		if (0 == (0x40 & rc))
+			break;
+		if (1 == (0x01 & rc))
 			break;
 	}
-	msleep(100);  j++;
+	msleep(marktime);
+	j++;
 }
 if (max == j)
 	return -1;
 else {
-	if (0x20 & rc)
+	if (0x20 & rc) {
+		rate = 2;
 		JOT(8, "hardware detects 60 Hz\n");
-	else
+	} else {
+		rate = 0;
 		JOT(8, "hardware detects 50 Hz\n");
+	}
 	if (0x80 & rc)
 		JOT(8, "hardware detects interlacing\n");
-	else
+	else {
+		rate++;
 		JOT(8, "hardware detects no interlacing\n");
+	}
 }
 return 0;
 }
@@ -447,45 +582,80 @@
 /*
  *  NOTE: THE FOLLOWING ARE NOT CHECKED:
  *  REGISTERS 0x000, 0x002:  FUNCTIONALITY IS NOT KNOWN
- *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config[.].set)
+ *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config....[.].set)
  */
 /*--------------------------------------------------------------------------*/
 int
-check_stk(struct usb_device *p)
+check_stk(struct usb_device *p, bool ntsc)
 {
 int i0, ir;
+
+if (NULL == p)
+	return -ENODEV;
 i0 = 0;
-while (0xFFF != stk1160config[i0].reg) {
-	if (0x000 == stk1160config[i0].reg) {
-		i0++; continue;
-	}
-	if (0x002 == stk1160config[i0].reg) {
-		i0++; continue;
-	}
-
-	ir = read_stk(p, stk1160config[i0].reg);
-
-	if (0x100 == stk1160config[i0].reg) {
-		if ((ir != (0xFF & stk1160config[i0].set)) && \
-			(ir != (0x80 | (0xFF & stk1160config[i0].set))) && \
-				(0xFFFF != stk1160config[i0].set)) {
-			SAY("STK register 0x%03X has 0x%02X, " \
-					"expected 0x%02X\n", \
-					stk1160config[i0].reg, ir, \
-					stk1160config[i0].set);
+if (true == ntsc) {
+	while (0xFFF != stk1160configNTSC[i0].reg) {
+		if (0x000 == stk1160configNTSC[i0].reg) {
+			i0++; continue;
+		}
+		if (0x002 == stk1160configNTSC[i0].reg) {
+			i0++; continue;
+		}
+		ir = read_stk(p, stk1160configNTSC[i0].reg);
+		if (0x100 == stk1160configNTSC[i0].reg) {
+			if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \
+					(ir != (0x80 | (0xFF & \
+					stk1160configNTSC[i0].set))) && \
+					(0xFFFF != \
+					stk1160configNTSC[i0].set)) {
+				SAY("STK register 0x%03X has 0x%02X, " \
+						"expected 0x%02X\n", \
+						stk1160configNTSC[i0].reg, \
+						ir, stk1160configNTSC[i0].set);
+				}
+			i0++; continue;
 			}
-		i0++; continue;
+		if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \
+				(0xFFFF != stk1160configNTSC[i0].set)) {
+			SAY("STK register 0x%03X has 0x%02X, " \
+						"expected 0x%02X\n", \
+						stk1160configNTSC[i0].reg, \
+						ir, stk1160configNTSC[i0].set);
 		}
-
-	if ((ir != (0xFF & stk1160config[i0].set)) && \
-			(0xFFFF != stk1160config[i0].set)) {
-		SAY("STK register 0x%03X has 0x%02X, " \
-					"expected 0x%02X\n", \
-					stk1160config[i0].reg, ir, \
-					stk1160config[i0].set);
-		}
-	i0++;
+		i0++;
 	}
+} else {
+	while (0xFFF != stk1160configPAL[i0].reg) {
+		if (0x000 == stk1160configPAL[i0].reg) {
+			i0++; continue;
+		}
+		if (0x002 == stk1160configPAL[i0].reg) {
+			i0++; continue;
+		}
+		ir = read_stk(p, stk1160configPAL[i0].reg);
+		if (0x100 == stk1160configPAL[i0].reg) {
+			if ((ir != (0xFF & stk1160configPAL[i0].set)) && \
+					(ir != (0x80 | (0xFF & \
+					stk1160configPAL[i0].set))) && \
+					(0xFFFF != \
+					stk1160configPAL[i0].set)) {
+				SAY("STK register 0x%03X has 0x%02X, " \
+						"expected 0x%02X\n", \
+						stk1160configPAL[i0].reg, \
+						ir, stk1160configPAL[i0].set);
+				}
+			i0++; continue;
+			}
+		if ((ir != (0xFF & stk1160configPAL[i0].set)) && \
+				(0xFFFF != stk1160configPAL[i0].set)) {
+			SAY("STK register 0x%03X has 0x%02X, " \
+						"expected 0x%02X\n", \
+						stk1160configPAL[i0].reg, \
+						ir, stk1160configPAL[i0].set);
+		}
+		i0++;
+	}
+}
 return 0;
 }
 /****************************************************************************/
@@ -494,6 +664,8 @@
 {
 __u8 igot;
 
+if (NULL == p)
+	return -ENODEV;
 SET(p, 0x208, reg0);
 SET(p, 0x200, 0x20);
 if (0 != wait_i2c(p))
@@ -508,12 +680,14 @@
 {
 __u8 igot;
 
+if (NULL == p)
+	return -ENODEV;
 igot = 0;
 GET(p, reg0, &igot);
 return igot;
 }
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
+/****************************************************************************/
+/*--------------------------------------------------------------------------*/
 /*
  *    HARDWARE    USERSPACE INPUT NUMBER   PHYSICAL INPUT   DRIVER input VALUE
  *
@@ -534,81 +708,100 @@
 int
 select_input(struct usb_device *p, int input, int mode)
 {
+int ir;
 
+if (NULL == p)
+	return -ENODEV;
 stop_100(p);
-
-msleep(20);
 switch (input) {
 case 0:
 case 1: {
-	SET(p, 0x0000, 0x0098); break;
+	if (0 != write_saa(p, 0x02, 0x80)) {
+		SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
+									input);
+	}
+	SET(p, 0x0000, 0x0098);
+	SET(p, 0x0002, 0x0078);
+	break;
 }
 case 2: {
-	SET(p, 0x0000, 0x0090); break;
+	if (0 != write_saa(p, 0x02, 0x80)) {
+		SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
+									input);
+	}
+	SET(p, 0x0000, 0x0090);
+	SET(p, 0x0002, 0x0078);
+	break;
 }
 case 3: {
-	SET(p, 0x0000, 0x0088); break;
+	if (0 != write_saa(p, 0x02, 0x80)) {
+		SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
+									input);
+	}
+	SET(p, 0x0000, 0x0088);
+	SET(p, 0x0002, 0x0078);
+	break;
 }
 case 4: {
-	SET(p, 0x0000, 0x0080); break;
+	if (0 != write_saa(p, 0x02, 0x80)) {
+		SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \
+									input);
+	}
+	SET(p, 0x0000, 0x0080);
+	SET(p, 0x0002, 0x0078);
+	break;
 }
 case 5: {
 	if (9 != mode)
 		mode = 7;
 	switch (mode) {
-	case 7:
-		{
+	case 7: {
 		if (0 != write_saa(p, 0x02, 0x87)) {
-			SAY("ERROR: failed to set SAA " \
-				"register 0x02 for input " \
-				"%i\n", input);
+			SAY("ERROR: failed to set SAA register 0x02 " \
+						"for input %i\n", input);
 		}
 		if (0 != write_saa(p, 0x05, 0xFF)) {
-			SAY("ERROR: failed to set SAA " \
-				"register 0x05 for input " \
-				"%i\n", input);
+			SAY("ERROR: failed to set SAA register 0x05 " \
+						"for input %i\n", input);
 		}
 		break;
 	}
-	case 9:
-		{
+	case 9: {
 		if (0 != write_saa(p, 0x02, 0x89)) {
-			SAY("ERROR: failed to set SAA " \
-				"register 0x02 for input " \
-				"%i\n", input);
+			SAY("ERROR: failed to set SAA register 0x02 " \
+						"for input %i\n", input);
 		}
 		if (0 != write_saa(p, 0x05, 0x00)) {
-			SAY("ERROR: failed to set SAA " \
-				"register 0x05 for input " \
-				"%i\n", input);
+			SAY("ERROR: failed to set SAA register 0x05 " \
+						"for input %i\n", input);
 		}
-		break;
+	break;
 	}
-	default:
-		{
+	default: {
 		SAY("MISTAKE:  bad mode: %i\n", mode);
 		return -1;
-		}
+	}
 	}
 	if (0 != write_saa(p, 0x04, 0x00)) {
-		SAY("ERROR: failed to set SAA register 0x04 " \
-					"for input %i\n", input);
+		SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \
+									input);
 	}
 	if (0 != write_saa(p, 0x09, 0x80)) {
-		SAY("ERROR: failed to set SAA register 0x09 " \
-					"for input %i\n", input);
+		SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \
+									input);
 	}
+	SET(p, 0x0002, 0x0093);
 	break;
 }
-default:
-	{
+default: {
 	SAY("ERROR:  bad input: %i\n", input);
 	return -1;
 }
 }
-msleep(20);
-SET(p, 0x0002, 0x0093);
-msleep(20);
+ir = read_stk(p, 0x00);
+JOT(8, "STK register 0x00 has 0x%02X\n", ir);
+ir = read_saa(p, 0x02);
+JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
 
 start_100(p);
 
@@ -621,6 +814,8 @@
 {
 __u16 u0x0111, u0x0113, u0x0115, u0x0117;
 
+if (NULL == p)
+	return -ENODEV;
 u0x0111 = ((0xFF00 & set0) >> 8);
 u0x0113 = ((0xFF00 & set1) >> 8);
 u0x0115 = ((0xFF00 & set2) >> 8);
@@ -641,13 +836,25 @@
 int
 start_100(struct usb_device *p)
 {
-__u16 get0;
-__u8 igot;
+__u16 get116, get117, get0;
+__u8 igot116, igot117, igot;
 
-GET(p, 0x0100, &igot);  get0 = igot;
-msleep(0x1f4);
+if (NULL == p)
+	return -ENODEV;
+GET(p, 0x0116, &igot116);
+get116 = igot116;
+GET(p, 0x0117, &igot117);
+get117 = igot117;
+SET(p, 0x0116, 0x0000);
+SET(p, 0x0117, 0x0000);
+
+GET(p, 0x0100, &igot);
+get0 = igot;
 SET(p, 0x0100, (0x80 | get0));
-msleep(0x1f4);
+
+SET(p, 0x0116, get116);
+SET(p, 0x0117, get117);
+
 return 0;
 }
 /****************************************************************************/
@@ -657,10 +864,11 @@
 __u16 get0;
 __u8 igot;
 
-GET(p, 0x0100, &igot);  get0 = igot;
-msleep(0x1f4);
+if (NULL == p)
+	return -ENODEV;
+GET(p, 0x0100, &igot);
+get0 = igot;
 SET(p, 0x0100, (0x7F & get0));
-msleep(0x1f4);
 return 0;
 }
 /****************************************************************************/
@@ -674,9 +882,11 @@
 {
 __u16 get0;
 __u8 igot;
-const int max = 4;
+const int max = 2;
 int k;
 
+if (NULL == p)
+	return -ENODEV;
 for (k = 0;  k < max;  k++) {
 	GET(p, 0x0201, &igot);  get0 = igot;
 	switch (get0) {
@@ -685,7 +895,7 @@
 		return 0;
 	}
 	case 0x00: {
-		msleep(10);
+		msleep(20);
 		continue;
 	}
 	default: {
@@ -703,8 +913,7 @@
 int rc0, rc1;
 
 if (!pusb_device)
-	return -EFAULT;
-
+	return -ENODEV;
 rc1 = 0;  igot = 0;
 rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
 		(__u8)0x01, \
@@ -741,27 +950,14 @@
 case 0x205:
 case 0x350:
 case 0x351: {
-	if (0 != igot) {
+	if (0 != (0xFF & igot)) {
 		JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \
 								igot, index);
 	}
 break;
 }
-case 0x114:
-case 0x116: {
-	if ((0xFF & value) != igot) {
-		JOT(8, "unexpected 0x%02X != 0x%02X " \
-						"for STK register 0x%03X\n", \
-						igot, value, index);
-	}
-break;
-}
-case 0x200: {
-	if (0 == igot)
-		break;
-}
 default: {
-	if (value != igot) {
+	if ((0xFF & value) != (0xFF & igot)) {
 		JOT(8, "unexpected 0x%02X != 0x%02X " \
 					"for STK register 0x%03X\n", \
 					igot, value, index);
@@ -780,8 +976,7 @@
 int ir;
 
 if (!pusb_device)
-	return -EFAULT;
-
+	return -ENODEV;
 ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \
 		(__u8)0x00, \
 		(__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \
@@ -796,6 +991,8 @@
 int
 wakeup_device(struct usb_device *pusb_device)
 {
+if (!pusb_device)
+	return -ENODEV;
 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
 		(__u8)USB_REQ_SET_FEATURE, \
 		(__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \
@@ -806,6 +1003,12 @@
 		(int)50000);
 }
 /*****************************************************************************/
+int
+audio_setup(struct easycap *peasycap)
+{
+struct usb_device *pusb_device;
+unsigned char buffer[1];
+int rc, id1, id2;
 /*---------------------------------------------------------------------------*/
 /*
  *                                IMPORTANT:
@@ -814,29 +1017,21 @@
  *  TO ENABLE AUDIO  THE VALUE 0x0200 MUST BE SENT.
  */
 /*---------------------------------------------------------------------------*/
-int
-audio_setup(struct easycap *peasycap)
-{
-struct usb_device *pusb_device;
-static __u8 request = 0x01;
-static __u8 requesttype = \
+const __u8 request = 0x01;
+const __u8 requesttype = \
 		(__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
-
-static __u16 value_unmute = 0x0200;
-static __u16 index = 0x0301;
-
-static unsigned char buffer[1];
-static __u16 length = 1;
-int rc, id1, id2;
+const __u16 value_unmute = 0x0200;
+const __u16 index = 0x0301;
+const __u16 length = 1;
 
 if (NULL == peasycap)
 	return -EFAULT;
 
 pusb_device = peasycap->pusb_device;
 if (NULL == pusb_device)
-	return -EFAULT;
+	return -ENODEV;
 
-JOT(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",	\
+JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",	\
 			requesttype, request,		\
 			(0x00FF & value_unmute),	\
 			(0xFF00 & value_unmute) >> 8,	\
@@ -875,41 +1070,25 @@
  *                    THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
  */
 /*--------------------------------------------------------------------------*/
-
 SET(pusb_device, 0x0500, 0x0094);
-
 SET(pusb_device, 0x0500, 0x008C);
-
 SET(pusb_device, 0x0506, 0x0001);
 SET(pusb_device, 0x0507, 0x0000);
-
 id1 = read_vt(pusb_device, 0x007C);
 id2 = read_vt(pusb_device, 0x007E);
-SAY("0x%04X:0x%04X is audio vendor id\n", id1, id2);
-
+SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
 /*---------------------------------------------------------------------------*/
 /*
-*   SELECT AUDIO SOURCE "LINE IN" AND SET DEFAULT GAIN TO 0 dB.
-*
-*   THESE COMMANDS SEEM TO BE ACCEPTED (THOUGH POSSIBLY IGNORED) EVEN WHEN
-*   THERE IS NO SEPARATE AUDIO CHIP PRESENT.
+ *  SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
 */
 /*---------------------------------------------------------------------------*/
-
-write_vt(pusb_device, 0x0002, 0x8000);
-write_vt(pusb_device, 0x001C, 0x8000);
-
-write_vt(pusb_device, 0x000E, 0x0000);
-write_vt(pusb_device, 0x0010, 0x0000);
-write_vt(pusb_device, 0x0012, 0x8000);
-write_vt(pusb_device, 0x0016, 0x0000);
-
-write_vt(pusb_device, 0x001A, 0x0404);
-write_vt(pusb_device, 0x0002, 0x0000);
-write_vt(pusb_device, 0x001C, 0x0000);
-
+if (31 < gain)
+	gain = 31;
+if (0 > gain)
+	gain = 0;
+if (0 != audio_gainset(pusb_device, (__s8)gain))
+	SAY("ERROR: audio_gainset() failed\n");
 check_vt(pusb_device);
-
 return 0;
 }
 /*****************************************************************************/
@@ -918,6 +1097,8 @@
 {
 int igot;
 
+if (!pusb_device)
+	return -ENODEV;
 igot = read_vt(pusb_device, 0x0002);
 if (0 > igot)
 	SAY("ERROR: failed to read VT1612A register 0x02\n");
@@ -942,17 +1123,23 @@
 if (0x8000 & igot)
 	SAY("register 0x%02X muted\n", 0x12);
 
+igot = read_vt(pusb_device, 0x0014);
+if (0 > igot)
+	SAY("ERROR: failed to read VT1612A register 0x14\n");
+if (0x8000 & igot)
+	SAY("register 0x%02X muted\n", 0x14);
+
 igot = read_vt(pusb_device, 0x0016);
 if (0 > igot)
 	SAY("ERROR: failed to read VT1612A register 0x16\n");
 if (0x8000 & igot)
 	SAY("register 0x%02X muted\n", 0x16);
 
-igot = read_vt(pusb_device, 0x001A);
+igot = read_vt(pusb_device, 0x0018);
 if (0 > igot)
-	SAY("ERROR: failed to read VT1612A register 0x1A\n");
+	SAY("ERROR: failed to read VT1612A register 0x18\n");
 if (0x8000 & igot)
-	SAY("register 0x%02X muted\n", 0x1A);
+	SAY("register 0x%02X muted\n", 0x18);
 
 igot = read_vt(pusb_device, 0x001C);
 if (0 > igot)
@@ -964,14 +1151,18 @@
 }
 /*****************************************************************************/
 /*---------------------------------------------------------------------------*/
-/*
- *  NOTE:  THIS DOES INCREASE THE VOLUME DRAMATICALLY:
- *         audio_gainset(pusb_device, 0x000F);
+/*  NOTE:  THIS DOES INCREASE THE VOLUME DRAMATICALLY:
+ *                      audio_gainset(pusb_device, 0x000F);
  *
- *  IF 16<loud<31 VT1621A REGISTER 0x1C IS SET FOR POSITIVE GAIN.
- *  IF loud<=16 VT1621A REGISTER 0x1C IS SET FOR ZERO GAIN.
- *  THERE IS NEVER ANY (ADDITIONAL) ATTENUATION.
- */
+ *       loud        dB  register 0x10      dB register 0x1C    dB total
+ *         0               -34.5                   0             -34.5
+ *        ..                ....                   .              ....
+ *        15                10.5                   0              10.5
+ *        16                12.0                   0              12.0
+ *        17                12.0                   1.5            13.5
+ *        ..                ....                  ....            ....
+ *        31                12.0                  22.5            34.5
+*/
 /*---------------------------------------------------------------------------*/
 int
 audio_gainset(struct usb_device *pusb_device, __s8 loud)
@@ -980,25 +1171,65 @@
 __u8 u8;
 __u16 mute;
 
-if (16 > loud)
-	loud = 16;
-u8 = 0x000F & (__u8)(loud - 16);
+if (NULL == pusb_device)
+	return -ENODEV;
+if (0 > loud)
+	loud = 0;
+if (31 < loud)
+	loud = 31;
 
 write_vt(pusb_device, 0x0002, 0x8000);
+/*---------------------------------------------------------------------------*/
+igot = read_vt(pusb_device, 0x000E);
+if (0 > igot) {
+	SAY("ERROR: failed to read VT1612A register 0x0E\n");
+	mute = 0x0000;
+} else
+	mute = 0x8000 & ((unsigned int)igot);
+mute = 0;
 
+if (16 > loud)
+	u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1));
+else
+	u8 = 0;
+
+JOT(8, "0x%04X=(mute|u8) for VT1612A register 0x0E\n", mute | u8);
+write_vt(pusb_device, 0x000E, (mute | u8));
+/*---------------------------------------------------------------------------*/
+igot = read_vt(pusb_device, 0x0010);
+if (0 > igot) {
+	SAY("ERROR: failed to read VT1612A register 0x10\n");
+	mute = 0x0000;
+} else
+	mute = 0x8000 & ((unsigned int)igot);
+mute = 0;
+
+JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", \
+							mute | u8 | (u8 << 8));
+write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8)));
+write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8)));
+write_vt(pusb_device, 0x0014, (mute | u8 | (u8 << 8)));
+write_vt(pusb_device, 0x0016, (mute | u8 | (u8 << 8)));
+write_vt(pusb_device, 0x0018, (mute | u8 | (u8 << 8)));
+/*---------------------------------------------------------------------------*/
 igot = read_vt(pusb_device, 0x001C);
 if (0 > igot) {
 	SAY("ERROR: failed to read VT1612A register 0x1C\n");
 	mute = 0x0000;
 } else
 	mute = 0x8000 & ((unsigned int)igot);
+mute = 0;
 
-JOT(8, "0x%04X=(mute|u8|(u8<<8))\n", mute | u8 | (u8 << 8));
+if (16 <= loud)
+	u8 = 0x000F & (__u8)(loud - 16);
+else
+	u8 = 0;
 
-write_vt(pusb_device, 0x001C, 0x8000);
+JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", \
+							mute | u8 | (u8 << 8));
 write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8)));
+write_vt(pusb_device, 0x001A, 0x0404);
 write_vt(pusb_device, 0x0002, 0x0000);
-
 return 0;
 }
 /*****************************************************************************/
@@ -1007,35 +1238,11 @@
 {
 int igot;
 
+if (NULL == pusb_device)
+	return -ENODEV;
 igot = read_vt(pusb_device, 0x001C);
 if (0 > igot)
 	SAY("ERROR: failed to read VT1612A register 0x1C\n");
 return igot;
 }
 /*****************************************************************************/
-int
-set2to78(struct usb_device *p)
-{
-int ir;
-
-msleep(20);
-ir = regset(p, 0x0002, 0x0078);
-if (0 > ir)
-	SAY("ERROR: failed to set register 0x0002 to 0x0078\n");
-msleep(20);
-return ir;
-}
-/*****************************************************************************/
-int
-set2to93(struct usb_device *p)
-{
-int ir;
-
-msleep(20);
-ir = regset(p, 0x0002, 0x0093);
-if (0 > ir)
-	SAY("ERROR: failed to set register 0x0002 to 0x0078\n");
-msleep(20);
-return ir;
-}
-/*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c
index 5a4bbd9..25e4178 100644
--- a/drivers/staging/easycap/easycap_main.c
+++ b/drivers/staging/easycap/easycap_main.c
@@ -30,9 +30,29 @@
 
 #include "easycap.h"
 #include "easycap_standard.h"
+#include "easycap_ioctl.h"
 
-int easycap_debug;
-module_param(easycap_debug, int, S_IRUGO | S_IWUSR);
+int debug;
+int bars;
+int gain = 16;
+module_param(debug, int, S_IRUGO | S_IWUSR);
+module_param(bars, int, S_IRUGO | S_IWUSR);
+module_param(gain, int, S_IRUGO | S_IWUSR);
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  dongle_this IS INDISPENSIBLY static BECAUSE FUNCTION easycap_usb_probe()
+ *  IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap
+ *  ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN
+ *  PROBING INTERFACES 1 AND 2.
+ *
+ *  IOCTL LOCKING IS DONE AT MODULE LEVEL, NOT DEVICE LEVEL.
+*/
+/*---------------------------------------------------------------------------*/
+
+struct easycap_dongle easycap_dongle[DONGLE_MANY];
+static int dongle_this;
+static int dongle_done;
 
 /*---------------------------------------------------------------------------*/
 /*
@@ -63,22 +83,25 @@
 	.owner		= THIS_MODULE,
 	.open		= easycap_open,
 	.release	= easycap_release,
-	.unlocked_ioctl	= easycap_ioctl,
+#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
+	.unlocked_ioctl	= easycap_ioctl_noinode,
+#else
+	.ioctl		= easycap_ioctl,
+#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
 	.poll		= easycap_poll,
 	.mmap		= easycap_mmap,
 	.llseek		= no_llseek,
 };
 struct vm_operations_struct easycap_vm_ops = {
-.open  = easycap_vma_open,
-.close = easycap_vma_close,
-.fault = easycap_vma_fault,
+	.open  = easycap_vma_open,
+	.close = easycap_vma_close,
+	.fault = easycap_vma_fault,
 };
 struct usb_class_driver easycap_class = {
-.name = "usb/easycap%d",
-.fops = &easycap_fops,
-.minor_base = USB_SKEL_MINOR_BASE,
+	.name = "usb/easycap%d",
+	.fops = &easycap_fops,
+	.minor_base = USB_SKEL_MINOR_BASE,
 };
-
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
@@ -86,16 +109,17 @@
 	.owner		= THIS_MODULE,
 	.open		= easycap_open_noinode,
 	.release	= easycap_release_noinode,
-	.unlocked_ioctl	= easycap_ioctl,
+#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
+	.unlocked_ioctl	= easycap_ioctl_noinode,
+#else
+	.ioctl		= easycap_ioctl,
+#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
 	.poll		= easycap_poll,
 	.mmap		= easycap_mmap,
 };
 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
-int video_device_many /*=0*/;
-struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device;
 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
 /*--------------------------------------------------------------------------*/
 /*
  *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
@@ -105,7 +129,11 @@
 	.owner		= THIS_MODULE,
 	.open		= easysnd_open,
 	.release	= easysnd_release,
-	.unlocked_ioctl	= easysnd_ioctl,
+#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
+	.unlocked_ioctl	= easysnd_ioctl_noinode,
+#else
+	.ioctl		= easysnd_ioctl,
+#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
 	.read		= easysnd_read,
 	.llseek		= no_llseek,
 };
@@ -115,17 +143,26 @@
 .minor_base = USB_SKEL_MINOR_BASE,
 };
 /****************************************************************************/
-/*--------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
 /*
- *  IT IS NOT APPROPRIATE FOR easycap_open() TO SUBMIT THE VIDEO URBS HERE,
- *  BECAUSE THERE WILL ALWAYS BE SUBSEQUENT NEGOTIATION OF TV STANDARD AND
- *  FORMAT BY IOCTL AND IT IS INADVISABLE TO HAVE THE URBS RUNNING WHILE
- *  REGISTERS OF THE SA7113H ARE BEING MANIPULATED.
- *
- *  THE SUBMISSION OF VIDEO URBS IS THEREFORE DELAYED UNTIL THE IOCTL COMMAND
- *  STREAMON IS RECEIVED.
- */
-/*--------------------------------------------------------------------------*/
+ *  THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
+*/
+/*---------------------------------------------------------------------------*/
+int
+isdongle(struct easycap *peasycap)
+{
+int k;
+if (NULL == peasycap)
+	return -2;
+for (k = 0; k < DONGLE_MANY; k++) {
+	if (easycap_dongle[k].peasycap == peasycap) {
+		peasycap->isdongle = k;
+		return k;
+	}
+}
+return -1;
+}
+/*****************************************************************************/
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
 int
@@ -140,15 +177,17 @@
 {
 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
 struct usb_interface *pusb_interface;
+#else
+struct video_device *pvideo_device;
 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
-struct usb_device *p;
 struct easycap *peasycap;
-int i, k, m, rc;
+int rc;
 
 JOT(4, "\n");
 SAY("==========OPEN=========\n");
 
 peasycap = (struct easycap *)NULL;
+/*---------------------------------------------------------------------------*/
 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
 if ((struct inode *)NULL == inode) {
 	SAY("ERROR: inode is NULL.\n");
@@ -162,161 +201,427 @@
 peasycap = usb_get_intfdata(pusb_interface);
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #else
-for (i = 0;  i < video_device_many;  i++) {
-	pvideo_device = pvideo_array[i];
-	if ((struct video_device *)NULL != pvideo_device) {
-		peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
-		break;
-	}
-}
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
-if ((struct easycap *)NULL == peasycap) {
-	SAY("MISTAKE: peasycap is NULL\n");
+pvideo_device = video_devdata(file);
+if ((struct video_device *)NULL == pvideo_device) {
+	SAY("ERROR: pvideo_device is NULL.\n");
 	return -EFAULT;
 }
-file->private_data = peasycap;
-/*---------------------------------------------------------------------------*/
-/*
- *  INITIALIZATION
- */
-/*---------------------------------------------------------------------------*/
-JOT(4, "starting initialization\n");
-
-for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
-	for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++)
-		memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
+peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
 }
-p = peasycap->pusb_device;
-if ((struct usb_device *)NULL == p) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+if (NULL == peasycap->pusb_device) {
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 } else {
-	JOT(16, "0x%08lX=peasycap->pusb_device\n", \
+	JOM(16, "0x%08lX=peasycap->pusb_device\n", \
 					(long int)peasycap->pusb_device);
 }
+file->private_data = peasycap;
 rc = wakeup_device(peasycap->pusb_device);
 if (0 == rc)
-	JOT(8, "wakeup_device() OK\n");
+	JOM(8, "wakeup_device() OK\n");
 else {
-	SAY("ERROR: wakeup_device() returned %i\n", rc);
+	SAM("ERROR: wakeup_device() returned %i\n", rc);
+	if (-ENODEV == rc)
+		SAM("ERROR: wakeup_device() returned -ENODEV\n");
+	else
+		SAM("ERROR: wakeup_device() returned %i\n", rc);
+	return rc;
+}
+peasycap->input = 0;
+rc = reset(peasycap);
+if (0 != rc) {
+	SAM("ERROR: reset() returned %i\n", rc);
 	return -EFAULT;
 }
-rc = setup_stk(p);  peasycap->input = 0;
-if (0 == rc)
-	JOT(8, "setup_stk() OK\n");
-else {
-	SAY("ERROR: setup_stk() returned %i\n", rc);
-	return -EFAULT;
+return 0;
 }
-rc = setup_saa(p);
-if (0 == rc)
-	JOT(8, "setup_saa() OK\n");
-else {
-	SAY("ERROR: setup_saa() returned %i\n", rc);
-	return -EFAULT;
-}
-rc = check_saa(p);
-if (0 == rc)
-	JOT(8, "check_saa() OK\n");
-else if (-8 < rc)
-	SAY("check_saa() returned %i\n", rc);
-else {
-	SAY("ERROR: check_saa() returned %i\n", rc);
-	return -EFAULT;
-}
-peasycap->standard_offset = -1;
+/*****************************************************************************/
 /*---------------------------------------------------------------------------*/
-#if defined(PREFER_NTSC)
-
-rc = adjust_standard(peasycap, V4L2_STD_NTSC_M);
-if (0 == rc)
-	JOT(8, "adjust_standard(.,NTSC_M) OK\n");
-else {
-	SAY("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc);
-	return -EFAULT;
-}
-rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
-									false);
-if (0 <= rc)
-	JOT(8, "adjust_format(.,640,480,UYVY) OK\n");
-else {
-	SAY("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc);
-	return -EFAULT;
-}
-
-#else
-
-rc = adjust_standard(peasycap, \
-		(V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
-		V4L2_STD_PAL_I | V4L2_STD_PAL_N));
-if (0 == rc)
-	JOT(8, "adjust_standard(.,PAL_BGHIN) OK\n");
-else {
-	SAY("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc);
-	return -EFAULT;
-}
-rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
-									false);
-if (0 <= rc)
-	JOT(8, "adjust_format(.,640,480,uyvy,false) OK\n");
-else {
-	SAY("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc);
-	return -EFAULT;
-}
-
-#endif /* !PREFER_NTSC*/
+/*
+ *  RESET THE HARDWARE TO ITS REFERENCE STATE.
+ *
+ *  THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
+ *  A BAD VIDEO FRAME SIZE.
+*/
 /*---------------------------------------------------------------------------*/
-rc = adjust_brightness(peasycap, -8192);
-if (0 != rc) {
-	SAY("ERROR: adjust_brightness(default) returned %i\n", rc);
+int
+reset(struct easycap *peasycap)
+{
+struct easycap_standard const *peasycap_standard;
+int i, rc, input, rate;
+bool ntsc, other;
+
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
 	return -EFAULT;
 }
-rc = adjust_contrast(peasycap, -8192);
-if (0 != rc) {
-	SAY("ERROR: adjust_contrast(default) returned %i\n", rc);
-	return -EFAULT;
-}
-rc = adjust_saturation(peasycap, -8192);
-if (0 != rc) {
-	SAY("ERROR: adjust_saturation(default) returned %i\n", rc);
-	return -EFAULT;
-}
-rc = adjust_hue(peasycap, -8192);
-if (0 != rc) {
-	SAY("ERROR: adjust_hue(default) returned %i\n", rc);
-	return -EFAULT;
-}
+input = peasycap->input;
+
 /*---------------------------------------------------------------------------*/
-rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \
-						peasycap->video_altsetting_on);
+/*
+ *  IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED
+ *  FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL.  THIS IS ESSENTIAL FOR
+ *  gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
+ *  A SWITCH BETWEEN PAL AND NTSC.
+ *
+ *  FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
+ *  COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
+*/
+/*---------------------------------------------------------------------------*/
+other = false;
+if (true == peasycap->ntsc)
+	JOM(8, "true=peasycap->ntsc\n");
+else
+	JOM(8, "false=peasycap->ntsc\n");
+rate = ready_saa(peasycap->pusb_device);
+if (0 > rate) {
+	JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
+	if (true == peasycap->ntsc) {
+		JOM(8, "... trying PAL ...\n");  ntsc = false;
+	} else {
+		JOM(8, "... trying NTSC ...\n"); ntsc = true;
+}
+rc = setup_stk(peasycap->pusb_device, ntsc);
 if (0 == rc)
-	JOT(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \
-						peasycap->video_altsetting_on);
+	JOM(4, "setup_stk() OK\n");
 else {
-	SAY("ERROR: usb_set_interface() returned %i\n", rc);
+	SAM("ERROR: setup_stk() returned %i\n", rc);
 	return -EFAULT;
 }
-rc = start_100(p);
+rc = setup_saa(peasycap->pusb_device, ntsc);
 if (0 == rc)
-	JOT(8, "start_100() OK\n");
+	JOM(4, "setup_saa() OK\n");
 else {
-	SAY("ERROR: start_100() returned %i\n", rc);
+	SAM("ERROR: setup_saa() returned %i\n", rc);
 	return -EFAULT;
 }
-peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
-peasycap->video_idle = 0;
-peasycap->video_junk = 0;
+rate = ready_saa(peasycap->pusb_device);
+if (0 > rate) {
+	JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
+	JOM(8, "... saa register 0x1F has 0x%02X\n", \
+				read_saa(peasycap->pusb_device, 0x1F));
+	ntsc = peasycap->ntsc;
+	} else {
+		JOM(8, "... success at second try:  %i=rate\n", rate);
+		ntsc = (0 < (rate/2)) ? true : false ;
+		other = true;
+	}
+} else {
+	JOM(8, "... success at first try:  %i=rate\n", rate);
+	ntsc = (0 < rate/2) ? true : false ;
+}
+if (true == ntsc)
+	JOM(8, "true=ntsc\n");
+else
+	JOM(8, "false=ntsc\n");
+/*---------------------------------------------------------------------------*/
+
+rc = setup_stk(peasycap->pusb_device, ntsc);
+if (0 == rc)
+	JOM(4, "setup_stk() OK\n");
+else {
+	SAM("ERROR: setup_stk() returned %i\n", rc);
+	return -EFAULT;
+}
+rc = setup_saa(peasycap->pusb_device, ntsc);
+if (0 == rc)
+	JOM(4, "setup_saa() OK\n");
+else {
+	SAM("ERROR: setup_saa() returned %i\n", rc);
+	return -EFAULT;
+}
+
 for (i = 0; i < 180; i++)
 	peasycap->merit[i] = 0;
 peasycap->video_eof = 0;
 peasycap->audio_eof = 0;
-
 do_gettimeofday(&peasycap->timeval7);
+/*---------------------------------------------------------------------------*/
+/*
+ * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
+ *
+ * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
+*/
+/*---------------------------------------------------------------------------*/
+peasycap->input = -8192;
+peasycap->standard_offset = -8192;
+if (true == other) {
+	peasycap_standard = &easycap_standard[0];
+	while (0xFFFF != peasycap_standard->mask) {
+		if (true == ntsc) {
+			if (NTSC_M == \
+				peasycap_standard->v4l2_standard.index) {
+				peasycap->inputset[input].standard_offset = \
+						peasycap_standard - \
+							&easycap_standard[0];
+				break;
+			}
+		} else {
+			if (PAL_BGHIN == \
+				peasycap_standard->v4l2_standard.index) {
+				peasycap->inputset[input].standard_offset = \
+						peasycap_standard -
+							&easycap_standard[0];
+				break;
+			}
+		}
+		peasycap_standard++;
+	}
+	if (0xFFFF == peasycap_standard->mask) {
+		SAM("ERROR: standard not found\n");
+		return -EINVAL;
+	}
+JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", \
+		peasycap->inputset[input].standard_offset, input);
+}
+peasycap->format_offset = -8192;
+peasycap->brightness = -8192;
+peasycap->contrast = -8192;
+peasycap->saturation = -8192;
+peasycap->hue = -8192;
 
-peasycap->fudge = 0;
+rc = newinput(peasycap, input);
 
-JOT(4, "finished initialization\n");
+if (0 == rc)
+	JOM(4, "restored input, standard and format\n");
+else {
+	SAM("ERROR: newinput(.,%i) returned %i\n", rc, input);
+	return -EFAULT;
+}
+if (true == peasycap->ntsc)
+	JOM(8, "true=peasycap->ntsc\n");
+else
+	JOM(8, "false=peasycap->ntsc\n");
+
+if (0 > peasycap->input) {
+	SAM("MISTAKE:  %i=peasycap->input\n", peasycap->input);
+	return -ENOENT;
+}
+if (0 > peasycap->standard_offset) {
+	SAM("MISTAKE:  %i=peasycap->standard_offset\n", \
+						peasycap->standard_offset);
+	return -ENOENT;
+}
+if (0 > peasycap->format_offset) {
+	SAM("MISTAKE:  %i=peasycap->format_offset\n", \
+						peasycap->format_offset);
+	return -ENOENT;
+}
+if (0 > peasycap->brightness) {
+	SAM("MISTAKE:  %i=peasycap->brightness\n", peasycap->brightness);
+	return -ENOENT;
+}
+if (0 > peasycap->contrast) {
+	SAM("MISTAKE:  %i=peasycap->contrast\n", peasycap->contrast);
+	return -ENOENT;
+}
+if (0 > peasycap->saturation) {
+	SAM("MISTAKE:  %i=peasycap->saturation\n", peasycap->saturation);
+	return -ENOENT;
+}
+if (0 > peasycap->hue) {
+	SAM("MISTAKE:  %i=peasycap->hue\n", peasycap->hue);
+	return -ENOENT;
+}
+return 0;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
+ *  OTHERWISE:
+ *      KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
+ *           _read AND _fill POINTERS.
+ *      SELECT THE NEW INPUT.
+ *      ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
+ *          ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
+ *      RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
+ *
+ *  NOTE:
+ *      THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
+ *      SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
+*/
+/*---------------------------------------------------------------------------*/
+int
+newinput(struct easycap *peasycap, int input)
+{
+int rc, k, m, mood, off;
+int inputnow, video_idlenow, audio_idlenow;
+bool resubmit;
+
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
+JOM(8, "%i=input sought\n", input);
+
+if (0 > input && INPUT_MANY <= input)
+	return -ENOENT;
+inputnow = peasycap->input;
+if (input == inputnow)
+	return 0;
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
+ *  STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
+ *  IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
+ *  ROUTINE.
+*/
+/*---------------------------------------------------------------------------*/
+video_idlenow = peasycap->video_idle;
+audio_idlenow = peasycap->audio_idle;
+
+peasycap->video_idle = 1;
+peasycap->audio_idle = 1;
+if (peasycap->video_isoc_streaming) {
+	resubmit = true;
+	kill_video_urbs(peasycap);
+} else
+	resubmit = false;
+/*---------------------------------------------------------------------------*/
+if (NULL == peasycap->pusb_device) {
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
+	return -ENODEV;
+}
+rc = usb_set_interface(peasycap->pusb_device,
+			peasycap->video_interface, \
+			peasycap->video_altsetting_off);
+if (0 != rc) {
+	SAM("ERROR: usb_set_interface() returned %i\n", rc);
+	return -EFAULT;
+}
+rc = stop_100(peasycap->pusb_device);
+if (0 != rc) {
+	SAM("ERROR: stop_100() returned %i\n", rc);
+	return -EFAULT;
+}
+for (k = 0; k < FIELD_BUFFER_MANY; k++) {
+	for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++)
+		memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE);
+}
+for (k = 0; k < FRAME_BUFFER_MANY; k++) {
+	for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++)
+		memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
+}
+peasycap->field_page = 0;
+peasycap->field_read = 0;
+peasycap->field_fill = 0;
+
+peasycap->frame_read = 0;
+peasycap->frame_fill = 0;
+for (k = 0; k < peasycap->input; k++) {
+	(peasycap->frame_fill)++;
+	if (peasycap->frame_buffer_many <= peasycap->frame_fill)
+		peasycap->frame_fill = 0;
+}
+peasycap->input = input;
+select_input(peasycap->pusb_device, peasycap->input, 9);
+/*---------------------------------------------------------------------------*/
+if (input == peasycap->inputset[input].input) {
+	off = peasycap->inputset[input].standard_offset;
+	if (off != peasycap->standard_offset) {
+		rc = adjust_standard(peasycap, \
+				easycap_standard[off].v4l2_standard.id);
+		if (0 != rc) {
+			SAM("ERROR: adjust_standard() returned %i\n", rc);
+			return -EFAULT;
+		}
+		JOM(8, "%i=peasycap->standard_offset\n", \
+						peasycap->standard_offset);
+	} else {
+		JOM(8, "%i=peasycap->standard_offset unchanged\n", \
+						peasycap->standard_offset);
+	}
+	off = peasycap->inputset[input].format_offset;
+	if (off != peasycap->format_offset) {
+		rc = adjust_format(peasycap, \
+			easycap_format[off].v4l2_format.fmt.pix.width, \
+			easycap_format[off].v4l2_format.fmt.pix.height, \
+			easycap_format[off].v4l2_format.fmt.pix.pixelformat, \
+			easycap_format[off].v4l2_format.fmt.pix.field, false);
+		if (0 > rc) {
+			SAM("ERROR: adjust_format() returned %i\n", rc);
+			return -EFAULT;
+		}
+		JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset);
+	} else {
+		JOM(8, "%i=peasycap->format_offset unchanged\n", \
+						peasycap->format_offset);
+	}
+	mood = peasycap->inputset[input].brightness;
+	if (mood != peasycap->brightness) {
+		rc = adjust_brightness(peasycap, mood);
+		if (0 != rc) {
+			SAM("ERROR: adjust_brightness returned %i\n", rc);
+			return -EFAULT;
+		}
+		JOM(8, "%i=peasycap->brightness\n", peasycap->brightness);
+	}
+	mood = peasycap->inputset[input].contrast;
+	if (mood != peasycap->contrast) {
+		rc = adjust_contrast(peasycap, mood);
+		if (0 != rc) {
+			SAM("ERROR: adjust_contrast returned %i\n", rc);
+			return -EFAULT;
+		}
+		JOM(8, "%i=peasycap->contrast\n", peasycap->contrast);
+	}
+	mood = peasycap->inputset[input].saturation;
+	if (mood != peasycap->saturation) {
+		rc = adjust_saturation(peasycap, mood);
+		if (0 != rc) {
+			SAM("ERROR: adjust_saturation returned %i\n", rc);
+			return -EFAULT;
+		}
+		JOM(8, "%i=peasycap->saturation\n", peasycap->saturation);
+	}
+	mood = peasycap->inputset[input].hue;
+	if (mood != peasycap->hue) {
+		rc = adjust_hue(peasycap, mood);
+		if (0 != rc) {
+			SAM("ERROR: adjust_hue returned %i\n", rc);
+			return -EFAULT;
+		}
+		JOM(8, "%i=peasycap->hue\n", peasycap->hue);
+	}
+} else {
+	SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input);
+	return -ENOENT;
+}
+/*---------------------------------------------------------------------------*/
+if (NULL == peasycap->pusb_device) {
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
+	return -ENODEV;
+}
+rc = usb_set_interface(peasycap->pusb_device,
+			peasycap->video_interface, \
+			peasycap->video_altsetting_on);
+if (0 != rc) {
+	SAM("ERROR: usb_set_interface() returned %i\n", rc);
+	return -EFAULT;
+}
+rc = start_100(peasycap->pusb_device);
+if (0 != rc) {
+	SAM("ERROR: start_100() returned %i\n", rc);
+	return -EFAULT;
+}
+if (true == resubmit)
+	submit_video_urbs(peasycap);
+
+peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
+peasycap->video_idle = video_idlenow;
+peasycap->audio_idle = audio_idlenow;
+peasycap->video_junk = 0;
+
 return 0;
 }
 /*****************************************************************************/
@@ -326,33 +631,25 @@
 struct data_urb *pdata_urb;
 struct urb *purb;
 struct list_head *plist_head;
-int j, isbad, m, rc;
+int j, isbad, nospc, m, rc;
 int isbuf;
 
-if ((struct list_head *)NULL == peasycap->purb_video_head) {
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
+
+if (NULL == peasycap->purb_video_head) {
 	SAY("ERROR: peasycap->urb_video_head uninitialized\n");
 	return -EFAULT;
 }
-if ((struct usb_device *)NULL == peasycap->pusb_device) {
+if (NULL == peasycap->pusb_device) {
 	SAY("ERROR: peasycap->pusb_device is NULL\n");
-	return -EFAULT;
+	return -ENODEV;
 }
 if (!peasycap->video_isoc_streaming) {
-
-
-
-
-
-
-
-
-	JOT(4, "submission of all video urbs\n");
-	if (0 != ready_saa(peasycap->pusb_device)) {
-		SAY("ERROR: not ready to capture after waiting " \
-							"one second\n");
-		SAY(".....  continuing anyway\n");
-	}
-	isbad = 0;  m = 0;
+	JOM(4, "submission of all video urbs\n");
+	isbad = 0;  nospc = 0;  m = 0;
 	list_for_each(plist_head, (peasycap->purb_video_head)) {
 		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
 		if (NULL != pdata_urb) {
@@ -389,44 +686,57 @@
 				rc = usb_submit_urb(purb, GFP_KERNEL);
 				if (0 != rc) {
 					isbad++;
-					SAY("ERROR: usb_submit_urb() failed " \
+					SAM("ERROR: usb_submit_urb() failed " \
 							"for urb with rc:\n");
 					switch (rc) {
 					case -ENOMEM: {
-						SAY("ENOMEM\n");
+						SAM("ERROR: -ENOMEM=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -ENODEV: {
-						SAY("ENODEV\n");
+						SAM("ERROR: -ENODEV=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -ENXIO: {
-						SAY("ENXIO\n");
+						SAM("ERROR: -ENXIO=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -EINVAL: {
-						SAY("EINVAL\n");
+						SAM("ERROR: -EINVAL=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -EAGAIN: {
-						SAY("EAGAIN\n");
+						SAM("ERROR: -EAGAIN=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -EFBIG: {
-						SAY("EFBIG\n");
+						SAM("ERROR: -EFBIG=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -EPIPE: {
-						SAY("EPIPE\n");
+						SAM("ERROR: -EPIPE=" \
+							"usb_submit_urb()\n");
 						break;
 					}
 					case -EMSGSIZE: {
-						SAY("EMSGSIZE\n");
+						SAM("ERROR: -EMSGSIZE=" \
+							"usb_submit_urb()\n");
+						break;
+					}
+					case -ENOSPC: {
+						nospc++;
 						break;
 					}
 					default: {
-						SAY("unknown error code %i\n",\
-									 rc);
+						SAM("ERROR: %i=" \
+							"usb_submit_urb()\n",\
+							rc);
 						break;
 					}
 					}
@@ -434,14 +744,20 @@
 					m++;
 				}
 				} else {
-					isbad++;
+					 isbad++;
 				}
 			} else {
 				 isbad++;
 			}
 		}
+	if (nospc) {
+		SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
+		SAM(".....  possibly inadequate USB bandwidth\n");
+		peasycap->video_eof = 1;
+	}
+
 	if (isbad) {
-		JOT(4, "attempting cleanup instead of submitting\n");
+		JOM(4, "attempting cleanup instead of submitting\n");
 		list_for_each(plist_head, (peasycap->purb_video_head)) {
 			pdata_urb = list_entry(plist_head, struct data_urb, \
 								list_head);
@@ -454,16 +770,10 @@
 		peasycap->video_isoc_streaming = 0;
 	} else {
 		peasycap->video_isoc_streaming = 1;
-		JOT(4, "submitted %i video urbs\n", m);
+		JOM(4, "submitted %i video urbs\n", m);
 	}
-
-
-
-
-
-
 } else {
-	JOT(4, "already streaming video urbs\n");
+	JOM(4, "already streaming video urbs\n");
 }
 return 0;
 }
@@ -475,35 +785,32 @@
 struct list_head *plist_head;
 struct data_urb *pdata_urb;
 
-if ((struct easycap *)NULL == peasycap) {
+if (NULL == peasycap) {
 	SAY("ERROR: peasycap is NULL\n");
 	return -EFAULT;
 }
 if (peasycap->video_isoc_streaming) {
-
-
-
 	if ((struct list_head *)NULL != peasycap->purb_video_head) {
 		peasycap->video_isoc_streaming = 0;
-		JOT(4, "killing video urbs\n");
+		JOM(4, "killing video urbs\n");
 		m = 0;
 		list_for_each(plist_head, (peasycap->purb_video_head)) {
 			pdata_urb = list_entry(plist_head, struct data_urb, \
 								list_head);
-			if ((struct data_urb *)NULL != pdata_urb) {
-				if ((struct urb *)NULL != pdata_urb->purb) {
+			if (NULL != pdata_urb) {
+				if (NULL != pdata_urb->purb) {
 					usb_kill_urb(pdata_urb->purb);
 					m++;
 				}
 			}
 		}
-		JOT(4, "%i video urbs killed\n", m);
+		JOM(4, "%i video urbs killed\n", m);
 	} else {
-		SAY("ERROR: peasycap->purb_video_head is NULL\n");
+		SAM("ERROR: peasycap->purb_video_head is NULL\n");
 		return -EFAULT;
 	}
 } else {
-	JOT(8, "%i=video_isoc_streaming, no video urbs killed\n", \
+	JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", \
 					peasycap->video_isoc_streaming);
 }
 return 0;
@@ -533,11 +840,15 @@
 	SAY("ending unsuccessfully\n");
 	return -EFAULT;
 }
-if (0 != kill_video_urbs(peasycap)) {
-	SAY("ERROR: kill_video_urbs() failed\n");
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
 	return -EFAULT;
 }
-JOT(4, "ending successfully\n");
+if (0 != kill_video_urbs(peasycap)) {
+	SAM("ERROR: kill_video_urbs() failed\n");
+	return -EFAULT;
+}
+JOM(4, "ending successfully\n");
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #else
 #
@@ -550,63 +861,45 @@
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
 int
-videodev_release(struct video_device *pvd)
+videodev_release(struct video_device *pvideo_device)
 {
 struct easycap *peasycap;
-int i, j, k;
 
 JOT(4, "\n");
 
-k = 0;
-for (i = 0;  i < video_device_many;  i++) {
-	pvideo_device = pvideo_array[i];
-	if ((struct video_device *)NULL != pvideo_device) {
-		if (pvd->minor == pvideo_device->minor) {
-			peasycap = (struct easycap *)\
-					video_get_drvdata(pvideo_device);
-			if ((struct easycap *)NULL == peasycap) {
-				SAY("ERROR:  peasycap is NULL\n");
-				SAY("ending unsuccessfully\n");
-				return -EFAULT;
-			}
-			if (0 != kill_video_urbs(peasycap)) {
-				SAY("ERROR: kill_video_urbs() failed\n");
-				return -EFAULT;
-			}
-			JOT(4, "freeing video_device structure: " \
-							"/dev/video%i\n", i);
-			kfree((void *)pvideo_device);
-			for (j = i;  j < (VIDEO_DEVICE_MANY - 1);  j++)
-				pvideo_array[j] = pvideo_array[j + 1];
-			video_device_many--;  k++;
-			break;
-		}
-	}
-}
-if (!k) {
-	SAY("ERROR: lost video_device structure for %i=minor\n", pvd->minor);
-	SAY("cannot free: may cause memory leak\n");
+peasycap = video_get_drvdata(pvideo_device);
+if (NULL == peasycap) {
+	SAY("ERROR:  peasycap is NULL\n");
 	SAY("ending unsuccessfully\n");
 	return -EFAULT;
 }
-
-JOT(4, "ending successfully\n");
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+if (0 != kill_video_urbs(peasycap)) {
+	SAM("ERROR: kill_video_urbs() failed\n");
+	return -EFAULT;
+}
+JOM(4, "ending successfully\n");
 return 0;
 }
 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-/****************************************************************************/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*****************************************************************************/
 /*--------------------------------------------------------------------------*/
 /*
- *  THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect().
- *  BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED.
- *  peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL.
+ *  THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS
+ *  PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect().
+ *
+ *  BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO
+ *  peasycap->pusb_device IS NO LONGER VALID.
  */
 /*---------------------------------------------------------------------------*/
 void
 easycap_delete(struct kref *pkref)
 {
-int k, m, lost;
+int k, m, gone, kd;
 int allocation_video_urb, allocation_video_page, allocation_video_struct;
 int allocation_audio_urb, allocation_audio_page, allocation_audio_struct;
 int registered_video, registered_audio;
@@ -617,22 +910,27 @@
 JOT(4, "\n");
 
 peasycap = container_of(pkref, struct easycap, kref);
-if ((struct easycap *)NULL == peasycap) {
-	SAY("ERROR: peasycap is NULL: cannot perform deletions\n");
+if (NULL == peasycap) {
+	SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
 	return;
 }
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return;
+}
+kd = isdongle(peasycap);
 /*---------------------------------------------------------------------------*/
 /*
  *  FREE VIDEO.
  */
 /*---------------------------------------------------------------------------*/
 if ((struct list_head *)NULL != peasycap->purb_video_head) {
-	JOT(4, "freeing video urbs\n");
+	JOM(4, "freeing video urbs\n");
 	m = 0;
 	list_for_each(plist_head, (peasycap->purb_video_head)) {
 		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
 		if (NULL == pdata_urb)
-			JOT(4, "ERROR: pdata_urb is NULL\n");
+			JOM(4, "ERROR: pdata_urb is NULL\n");
 		else {
 			if ((struct urb *)NULL != pdata_urb->purb) {
 				usb_free_urb(pdata_urb->purb);
@@ -643,9 +941,9 @@
 		}
 	}
 
-	JOT(4, "%i video urbs freed\n", m);
+	JOM(4, "%i video urbs freed\n", m);
 /*---------------------------------------------------------------------------*/
-	JOT(4, "freeing video data_urb structures.\n");
+	JOM(4, "freeing video data_urb structures.\n");
 	m = 0;
 	list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) {
 		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
@@ -656,14 +954,12 @@
 			m++;
 		}
 	}
-	JOT(4, "%i video data_urb structures freed\n", m);
-	JOT(4, "setting peasycap->purb_video_head=NULL\n");
+	JOM(4, "%i video data_urb structures freed\n", m);
+	JOM(4, "setting peasycap->purb_video_head=NULL\n");
 	peasycap->purb_video_head = (struct list_head *)NULL;
-	} else {
-JOT(4, "peasycap->purb_video_head is NULL\n");
 }
 /*---------------------------------------------------------------------------*/
-JOT(4, "freeing video isoc buffers.\n");
+JOM(4, "freeing video isoc buffers.\n");
 m = 0;
 for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY;  k++) {
 	if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) {
@@ -676,10 +972,10 @@
 		m++;
 	}
 }
-JOT(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
+JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
 /*---------------------------------------------------------------------------*/
-JOT(4, "freeing video field buffers.\n");
-lost = 0;
+JOM(4, "freeing video field buffers.\n");
+gone = 0;
 for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
 	for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
 		if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
@@ -687,14 +983,14 @@
 					(peasycap->field_buffer[k][m].pgo));
 			peasycap->field_buffer[k][m].pgo = (void *)NULL;
 			peasycap->allocation_video_page -= 1;
-			lost++;
+			gone++;
 		}
 	}
 }
-JOT(4, "video field buffers freed: %i pages\n", lost);
+JOM(4, "video field buffers freed: %i pages\n", gone);
 /*---------------------------------------------------------------------------*/
-JOT(4, "freeing video frame buffers.\n");
-lost = 0;
+JOM(4, "freeing video frame buffers.\n");
+gone = 0;
 for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
 	for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
 		if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) {
@@ -702,23 +998,23 @@
 					(peasycap->frame_buffer[k][m].pgo));
 			peasycap->frame_buffer[k][m].pgo = (void *)NULL;
 			peasycap->allocation_video_page -= 1;
-			lost++;
+			gone++;
 		}
 	}
 }
-JOT(4, "video frame buffers freed: %i pages\n", lost);
+JOM(4, "video frame buffers freed: %i pages\n", gone);
 /*---------------------------------------------------------------------------*/
 /*
  *  FREE AUDIO.
  */
 /*---------------------------------------------------------------------------*/
 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
-	JOT(4, "freeing audio urbs\n");
+	JOM(4, "freeing audio urbs\n");
 	m = 0;
 	list_for_each(plist_head, (peasycap->purb_audio_head)) {
 		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
 		if (NULL == pdata_urb)
-			JOT(4, "ERROR: pdata_urb is NULL\n");
+			JOM(4, "ERROR: pdata_urb is NULL\n");
 		else {
 			if ((struct urb *)NULL != pdata_urb->purb) {
 				usb_free_urb(pdata_urb->purb);
@@ -728,9 +1024,9 @@
 			}
 		}
 	}
-	JOT(4, "%i audio urbs freed\n", m);
+	JOM(4, "%i audio urbs freed\n", m);
 /*---------------------------------------------------------------------------*/
-	JOT(4, "freeing audio data_urb structures.\n");
+	JOM(4, "freeing audio data_urb structures.\n");
 	m = 0;
 	list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) {
 		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
@@ -741,14 +1037,12 @@
 			m++;
 		}
 	}
-JOT(4, "%i audio data_urb structures freed\n", m);
-JOT(4, "setting peasycap->purb_audio_head=NULL\n");
+JOM(4, "%i audio data_urb structures freed\n", m);
+JOM(4, "setting peasycap->purb_audio_head=NULL\n");
 peasycap->purb_audio_head = (struct list_head *)NULL;
-} else {
-JOT(4, "peasycap->purb_audio_head is NULL\n");
 }
 /*---------------------------------------------------------------------------*/
-JOT(4, "freeing audio isoc buffers.\n");
+JOM(4, "freeing audio isoc buffers.\n");
 m = 0;
 for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
 	if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) {
@@ -761,22 +1055,22 @@
 		m++;
 	}
 }
-JOT(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
+JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
 					m * (0x01 << AUDIO_ISOC_ORDER));
 /*---------------------------------------------------------------------------*/
-JOT(4, "freeing audio buffers.\n");
-lost = 0;
+JOM(4, "freeing audio buffers.\n");
+gone = 0;
 for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
 	if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
 		free_page((unsigned long)(peasycap->audio_buffer[k].pgo));
 		peasycap->audio_buffer[k].pgo = (void *)NULL;
 		peasycap->allocation_audio_page -= 1;
-		lost++;
+		gone++;
 	}
 }
-JOT(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost);
+JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", gone);
 /*---------------------------------------------------------------------------*/
-JOT(4, "freeing easycap structure.\n");
+JOM(4, "freeing easycap structure.\n");
 allocation_video_urb    = peasycap->allocation_video_urb;
 allocation_video_page   = peasycap->allocation_video_page;
 allocation_video_struct = peasycap->allocation_video_struct;
@@ -785,15 +1079,16 @@
 allocation_audio_page   = peasycap->allocation_audio_page;
 allocation_audio_struct = peasycap->allocation_audio_struct;
 registered_audio        = peasycap->registered_audio;
-m = 0;
-if ((struct easycap *)NULL != peasycap) {
-	kfree(peasycap);  peasycap = (struct easycap *)NULL;
-	allocation_video_struct -= sizeof(struct easycap);
-	m++;
-}
-JOT(4, "%i easycap structure freed\n", m);
-/*---------------------------------------------------------------------------*/
 
+kfree(peasycap);
+if (0 <= kd && DONGLE_MANY > kd) {
+	easycap_dongle[kd].peasycap = (struct easycap *)NULL;
+	JOT(4, "   null-->easycap_dongle[%i].peasycap\n", kd);
+	allocation_video_struct -= sizeof(struct easycap);
+} else {
+	SAY("ERROR: cannot purge easycap_dongle[].peasycap");
+}
+/*---------------------------------------------------------------------------*/
 SAY("%8i= video urbs     after all deletions\n", allocation_video_urb);
 SAY("%8i= video pages    after all deletions\n", allocation_video_page);
 SAY("%8i= video structs  after all deletions\n", allocation_video_struct);
@@ -810,27 +1105,85 @@
 unsigned int easycap_poll(struct file *file, poll_table *wait)
 {
 struct easycap *peasycap;
+int rc, kd;
 
 JOT(8, "\n");
 
 if (NULL == ((poll_table *)wait))
 	JOT(8, "WARNING:  poll table pointer is NULL ... continuing\n");
-if (NULL == ((struct file *)file)) {
+if ((struct file *)NULL == file) {
 	SAY("ERROR:  file pointer is NULL\n");
-	return -EFAULT;
+	return -ERESTARTSYS;
 }
 peasycap = file->private_data;
 if (NULL == peasycap) {
 	SAY("ERROR:  peasycap is NULL\n");
 	return -EFAULT;
 }
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+if (NULL == peasycap->pusb_device) {
+	SAY("ERROR:  peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+kd = isdongle(peasycap);
+if (0 <= kd && DONGLE_MANY > kd) {
+	if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
+		SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd);
+		return -ERESTARTSYS;
+	}
+	JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
+	/*-------------------------------------------------------------------*/
+	/*
+	 *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
+	 *  peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
+	 *  IF NECESSARY, BAIL OUT.
+	*/
+	/*-------------------------------------------------------------------*/
+	if (kd != isdongle(peasycap))
+		return -ERESTARTSYS;
+	if (NULL == file) {
+		SAY("ERROR:  file is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+	peasycap = file->private_data;
+	if (NULL == peasycap) {
+		SAY("ERROR:  peasycap is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+		SAY("ERROR: bad peasycap: 0x%08lX\n", \
+						(unsigned long int) peasycap);
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+	if (NULL == peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return -ERESTARTSYS;
+	}
+} else
+	/*-------------------------------------------------------------------*/
+	/*
+	 *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
+	 *  BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
+	 *  HAVE FAILED.  BAIL OUT.
+	*/
+	/*-------------------------------------------------------------------*/
+	return -ERESTARTSYS;
+/*---------------------------------------------------------------------------*/
+rc = easycap_dqbuf(peasycap, 0);
 peasycap->polled = 1;
-
-if (0 == easycap_dqbuf(peasycap, 0))
+mutex_unlock(&easycap_dongle[kd].mutex_video);
+if (0 == rc)
 	return POLLIN | POLLRDNORM;
 else
 	return POLLERR;
-
 }
 /*****************************************************************************/
 /*---------------------------------------------------------------------------*/
@@ -841,7 +1194,7 @@
 int
 easycap_dqbuf(struct easycap *peasycap, int mode)
 {
-int miss, rc;
+int input, ifield, miss, rc;
 
 JOT(8, "\n");
 
@@ -849,129 +1202,188 @@
 	SAY("ERROR:  peasycap is NULL\n");
 	return -EFAULT;
 }
+if (NULL == peasycap->pusb_device) {
+	SAY("ERROR:  peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+ifield = 0;
+JOM(8, "%i=ifield\n", ifield);
 /*---------------------------------------------------------------------------*/
 /*
- *  WAIT FOR FIELD 0
+ *  CHECK FOR LOST INPUT SIGNAL.
+ *
+ *  FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
+ *  IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
+ *  RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
+ *  IS FLYWHEELING ON INPUT 0.  THE UPSHOT IS:
+ *
+ *    INPUT 0   PLUGGED, INPUT 4   PLUGGED => SCREEN 0 OK,   SCREEN 4 OK
+ *    INPUT 0   PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK,   SCREEN 4 BLACK
+ *    INPUT 0 UNPLUGGED, INPUT 4   PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
+ *    INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
+*/
+/*---------------------------------------------------------------------------*/
+input = peasycap->input;
+if (0 <= input && INPUT_MANY > input) {
+	rc = read_saa(peasycap->pusb_device, 0x1F);
+	if (0 <= rc) {
+		if (rc & 0x40)
+			peasycap->lost[input] += 1;
+		else
+			peasycap->lost[input] -= 2;
+
+	if (0 > peasycap->lost[input])
+		peasycap->lost[input] = 0;
+	else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input])
+		peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE);
+	}
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  WAIT FOR FIELD ifield  (0 => TOP, 1 => BOTTOM)
  */
 /*---------------------------------------------------------------------------*/
 miss = 0;
-if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
-	return -ERESTARTSYS;
 while ((peasycap->field_read == peasycap->field_fill) || \
 				(0 != (0xFF00 & peasycap->field_buffer\
 					[peasycap->field_read][0].kount)) || \
-				(0 != (0x00FF & peasycap->field_buffer\
+				(ifield != (0x00FF & peasycap->field_buffer\
 					[peasycap->field_read][0].kount))) {
-	mutex_unlock(&(peasycap->mutex_mmap_video[0]));
-
 	if (mode)
 		return -EAGAIN;
 
-	JOT(8, "first wait  on wq_video, " \
+	JOM(8, "first wait  on wq_video, " \
 				"%i=field_read  %i=field_fill\n", \
 				peasycap->field_read, peasycap->field_fill);
 
-	msleep(1);
 	if (0 != (wait_event_interruptible(peasycap->wq_video, \
 			(peasycap->video_idle || peasycap->video_eof  || \
 			((peasycap->field_read != peasycap->field_fill) && \
 				(0 == (0xFF00 & peasycap->field_buffer\
 					[peasycap->field_read][0].kount)) && \
-				(0 == (0x00FF & peasycap->field_buffer\
-					[peasycap->field_read][0].kount))))))){
-		SAY("aborted by signal\n");
+				(ifield == (0x00FF & peasycap->field_buffer\
+					[peasycap->field_read][0].kount))))))) {
+		SAM("aborted by signal\n");
 		return -EIO;
 		}
 	if (peasycap->video_idle) {
-		JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
-		return -EIO;
+		JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \
+							peasycap->video_idle);
+		return -EAGAIN;
 	}
 	if (peasycap->video_eof) {
-		JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
-		debrief(peasycap);
+		JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
+		#if defined(PERSEVERE)
+		if (1 == peasycap->status) {
+			JOM(8, "persevering ...\n");
+			peasycap->video_eof = 0;
+			peasycap->audio_eof = 0;
+			if (0 != reset(peasycap)) {
+				JOM(8, " ... failed ... returning -EIO\n");
+				peasycap->video_eof = 1;
+				peasycap->audio_eof = 1;
+				kill_video_urbs(peasycap);
+				return -EIO;
+			}
+			peasycap->status = 0;
+			JOM(8, " ... OK ... returning -EAGAIN\n");
+			return -EAGAIN;
+		}
+		#endif /*PERSEVERE*/
+		peasycap->video_eof = 1;
+		peasycap->audio_eof = 1;
 		kill_video_urbs(peasycap);
+		JOM(8, "returning -EIO\n");
 		return -EIO;
 	}
 miss++;
-if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
-	return -ERESTARTSYS;
 }
-mutex_unlock(&(peasycap->mutex_mmap_video[0]));
-JOT(8, "first awakening on wq_video after %i waits\n", miss);
+JOM(8, "first awakening on wq_video after %i waits\n", miss);
 
 rc = field2frame(peasycap);
 if (0 != rc)
-	SAY("ERROR: field2frame() returned %i\n", rc);
-
-if (true == peasycap->offerfields) {
-	peasycap->frame_read = peasycap->frame_fill;
-	(peasycap->frame_fill)++;
-	if (peasycap->frame_buffer_many <= peasycap->frame_fill)
-		peasycap->frame_fill = 0;
-
-	if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
-		peasycap->frame_buffer[peasycap->frame_read][0].kount = \
-							V4L2_FIELD_BOTTOM;
-	} else {
-		peasycap->frame_buffer[peasycap->frame_read][0].kount = \
-							V4L2_FIELD_TOP;
-	}
-JOT(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
-JOT(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
-}
+	SAM("ERROR: field2frame() returned %i\n", rc);
 /*---------------------------------------------------------------------------*/
 /*
- *  WAIT FOR FIELD 1
+ *  WAIT FOR THE OTHER FIELD
  */
 /*---------------------------------------------------------------------------*/
+if (ifield)
+	ifield = 0;
+else
+	ifield = 1;
 miss = 0;
-if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
-	return -ERESTARTSYS;
 while ((peasycap->field_read == peasycap->field_fill) || \
 				(0 != (0xFF00 & peasycap->field_buffer\
 					[peasycap->field_read][0].kount)) || \
-				(0 == (0x00FF & peasycap->field_buffer\
+				(ifield != (0x00FF & peasycap->field_buffer\
 					[peasycap->field_read][0].kount))) {
-	mutex_unlock(&(peasycap->mutex_mmap_video[0]));
-
 	if (mode)
 		return -EAGAIN;
 
-	JOT(8, "second wait on wq_video, " \
+	JOM(8, "second wait on wq_video, " \
 				"%i=field_read  %i=field_fill\n", \
 				peasycap->field_read, peasycap->field_fill);
-	msleep(1);
 	if (0 != (wait_event_interruptible(peasycap->wq_video, \
 			(peasycap->video_idle || peasycap->video_eof  || \
 			((peasycap->field_read != peasycap->field_fill) && \
 				(0 == (0xFF00 & peasycap->field_buffer\
 					[peasycap->field_read][0].kount)) && \
-				(0 != (0x00FF & peasycap->field_buffer\
-					[peasycap->field_read][0].kount))))))){
-		SAY("aborted by signal\n");
+				(ifield == (0x00FF & peasycap->field_buffer\
+					[peasycap->field_read][0].\
+								kount))))))) {
+		SAM("aborted by signal\n");
 		return -EIO;
 	}
 	if (peasycap->video_idle) {
-		JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
-		return -EIO;
+		JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \
+							peasycap->video_idle);
+		return -EAGAIN;
 	}
 	if (peasycap->video_eof) {
-		JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
-		debrief(peasycap);
+		JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
+		#if defined(PERSEVERE)
+		if (1 == peasycap->status) {
+			JOM(8, "persevering ...\n");
+			peasycap->video_eof = 0;
+			peasycap->audio_eof = 0;
+			if (0 != reset(peasycap)) {
+				JOM(8, " ... failed ... returning -EIO\n");
+				peasycap->video_eof = 1;
+				peasycap->audio_eof = 1;
+				kill_video_urbs(peasycap);
+				return -EIO;
+			}
+			peasycap->status = 0;
+			JOM(8, " ... OK ... returning -EAGAIN\n");
+			return -EAGAIN;
+		}
+		#endif /*PERSEVERE*/
+		peasycap->video_eof = 1;
+		peasycap->audio_eof = 1;
 		kill_video_urbs(peasycap);
+		JOM(8, "returning -EIO\n");
 		return -EIO;
 	}
 miss++;
-if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
-	return -ERESTARTSYS;
 }
-mutex_unlock(&(peasycap->mutex_mmap_video[0]));
-JOT(8, "second awakening on wq_video after %i waits\n", miss);
+JOM(8, "second awakening on wq_video after %i waits\n", miss);
 
 rc = field2frame(peasycap);
 if (0 != rc)
-	SAY("ERROR: field2frame() returned %i\n", rc);
-
+	SAM("ERROR: field2frame() returned %i\n", rc);
+/*---------------------------------------------------------------------------*/
+/*
+ *  WASTE THIS FRAME
+*/
+/*---------------------------------------------------------------------------*/
+if (0 != peasycap->skip) {
+	peasycap->skipped++;
+	if (peasycap->skip != peasycap->skipped)
+		return peasycap->skip - peasycap->skipped;
+	peasycap->skipped = 0;
+}
+/*---------------------------------------------------------------------------*/
 peasycap->frame_read = peasycap->frame_fill;
 peasycap->queued[peasycap->frame_read] = 0;
 peasycap->done[peasycap->frame_read]   = V4L2_BUF_FLAG_DONE;
@@ -988,8 +1400,8 @@
 							V4L2_FIELD_BOTTOM;
 }
 
-JOT(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
-JOT(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
+JOM(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
+JOM(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
 
 return 0;
 }
@@ -1003,14 +1415,12 @@
  *  odd==false IS TRANSFERRED TO THE FRAME BUFFER.
  *
  *  THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
- *  CHOOSES THE OPTION V4L2_FIELD_ALTERNATE.  NO USERSPACE PROGRAM TESTED
- *  TO DATE HAS DONE THIS.  BUGS ARE LIKELY.
+ *  CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
  */
 /*---------------------------------------------------------------------------*/
 int
 field2frame(struct easycap *peasycap)
 {
-static struct timeval timeval0;
 struct timeval timeval;
 long long int above, below;
 __u32 remainder;
@@ -1019,16 +1429,26 @@
 void *pex, *pad;
 int kex, kad, mex, mad, rex, rad, rad2;
 int c2, c3, w2, w3, cz, wz;
-int rc, bytesperpixel, multiplier, much, more, over, rump, caches;
+int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input;
 __u8 mask, margin;
-bool odd, isuy, decimatepixel, offerfields;
+bool odd, isuy, decimatepixel, offerfields, badinput;
 
-JOT(8, "=====  parity %i, field buffer %i --> frame buffer %i\n", \
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
+
+badinput = false;
+input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input;
+
+JOM(8, "=====  parity %i, input 0x%02X, field buffer %i --> " \
+						"frame buffer %i\n", \
 			peasycap->field_buffer[peasycap->field_read][0].kount,\
+			peasycap->field_buffer[peasycap->field_read][0].input,\
 			peasycap->field_read, peasycap->frame_fill);
-JOT(8, "=====  %i=bytesperpixel\n", peasycap->bytesperpixel);
+JOM(8, "=====  %i=bytesperpixel\n", peasycap->bytesperpixel);
 if (true == peasycap->offerfields)
-	JOT(8, "===== offerfields\n");
+	JOM(8, "===== offerfields\n");
 
 /*---------------------------------------------------------------------------*/
 /*
@@ -1036,15 +1456,17 @@
  */
 /*---------------------------------------------------------------------------*/
 if (peasycap->field_read == peasycap->field_fill) {
-	SAY("ERROR: on entry, still filling field buffer %i\n", \
+	SAM("ERROR: on entry, still filling field buffer %i\n", \
 							peasycap->field_read);
 	return 0;
 }
 #if defined(EASYCAP_TESTCARD)
 easycap_testcard(peasycap, peasycap->field_read);
 #else
-if (0 != (0x0400 & peasycap->field_buffer[peasycap->field_read][0].kount))
-	easycap_testcard(peasycap, peasycap->field_read);
+if (0 <= input && INPUT_MANY > input) {
+	if (bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input])
+		easycap_testcard(peasycap, peasycap->field_read);
+}
 #endif /*EASYCAP_TESTCARD*/
 /*---------------------------------------------------------------------------*/
 
@@ -1055,7 +1477,7 @@
 if ((2 != bytesperpixel) && \
 			(3 != bytesperpixel) && \
 			(4 != bytesperpixel)) {
-	SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
+	SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
 	return -EFAULT;
 }
 if (true == decimatepixel)
@@ -1082,8 +1504,8 @@
 else
 	odd = false;
 
-if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) {
-	JOT(8, "  initial skipping    %4i          bytes p.%4i\n", \
+if ((true == odd) && (false == decimatepixel)) {
+	JOM(8, "  initial skipping    %4i          bytes p.%4i\n", \
 							w3/multiplier, mad);
 	pad += (w3 / multiplier);  rad -= (w3 / multiplier);
 }
@@ -1108,7 +1530,7 @@
 			rump = 0;
 
 			if (much % 2) {
-				SAY("MISTAKE: much is odd\n");
+				SAM("MISTAKE: much is odd\n");
 				return -EFAULT;
 			}
 
@@ -1116,13 +1538,11 @@
 					much) / 2;
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 			if (1 < bytesperpixel) {
-				if ((rad * \
-					2) < (much * \
-						bytesperpixel)) {
+				if (rad * 2 < much * bytesperpixel) {
 					/*
 					**   INJUDICIOUS ALTERATION OF THIS
-					**   BLOCK WILL CAUSE BREAKAGE.
-					**   BEWARE.
+					**   STATEMENT BLOCK WILL CAUSE
+					**   BREAKAGE.  BEWARE.
 					**/
 					rad2 = rad + bytesperpixel - 1;
 					much = ((((2 * \
@@ -1145,18 +1565,25 @@
 				}
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 			} else {
-				SAY("MISTAKE: %i=bytesperpixel\n", \
+				SAM("MISTAKE: %i=bytesperpixel\n", \
 						bytesperpixel);
 				return -EFAULT;
 			}
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 			if (rump)
 				caches++;
-
+				if (true == badinput) {
+					JOM(8, "ERROR: 0x%02X=->field_buffer" \
+						"[%i][%i].input, " \
+						"0x%02X=(0x08|->input)\n", \
+						peasycap->field_buffer\
+						[kex][mex].input, kex, mex, \
+						(0x08|peasycap->input));
+				}
 			rc = redaub(peasycap, pad, pex, much, more, \
 							mask, margin, isuy);
 			if (0 > rc) {
-				SAY("ERROR: redaub() failed\n");
+				SAM("ERROR: redaub() failed\n");
 				return -EFAULT;
 			}
 			if (much % 4) {
@@ -1171,6 +1598,9 @@
 				mex++;
 				pex = peasycap->field_buffer[kex][mex].pgo;
 				rex = PAGE_SIZE;
+				if (peasycap->field_buffer[kex][mex].input != \
+						(0x08|peasycap->input))
+					badinput = true;
 			}
 			pad  += more;
 			rad -= more;
@@ -1190,7 +1620,7 @@
  *  UNLESS IT IS THE LAST LINE OF AN ODD FRAME
  */
 /*---------------------------------------------------------------------------*/
-		if (((false == odd) || (cz != wz))&&(false == offerfields)) {
+		if ((false == odd) || (cz != wz)) {
 			over = w3;
 			do {
 				if (!rad) {
@@ -1224,7 +1654,7 @@
 			rump = 0;
 
 			if (much % 2) {
-				SAY("MISTAKE: much is odd\n");
+				SAM("MISTAKE: much is odd\n");
 				return -EFAULT;
 			}
 
@@ -1232,12 +1662,11 @@
 					much) / 4;
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 			if (1 < bytesperpixel) {
-				if ((rad * 4) < (much * \
-						bytesperpixel)) {
+				if (rad * 4 < much * bytesperpixel) {
 					/*
 					**   INJUDICIOUS ALTERATION OF THIS
-					**   BLOCK WILL CAUSE BREAKAGE.
-					**   BEWARE.
+					**   STATEMENT BLOCK WILL CAUSE
+					**   BREAKAGE.  BEWARE.
 					**/
 					rad2 = rad + bytesperpixel - 1;
 					much = ((((2 * rad2)/bytesperpixel)/2)\
@@ -1261,7 +1690,7 @@
 					}
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 				} else {
-					SAY("MISTAKE: %i=bytesperpixel\n", \
+					SAM("MISTAKE: %i=bytesperpixel\n", \
 						bytesperpixel);
 					return -EFAULT;
 				}
@@ -1269,10 +1698,18 @@
 			if (rump)
 				caches++;
 
+				if (true == badinput) {
+					JOM(8, "ERROR: 0x%02X=->field_buffer" \
+						"[%i][%i].input, " \
+						"0x%02X=(0x08|->input)\n", \
+						peasycap->field_buffer\
+						[kex][mex].input, kex, mex, \
+						(0x08|peasycap->input));
+				}
 			rc = redaub(peasycap, pad, pex, much, more, \
 							mask, margin, isuy);
 			if (0 > rc) {
-				SAY("ERROR: redaub() failed\n");
+				SAM("ERROR: redaub() failed\n");
 				return -EFAULT;
 			}
 			over -= much;   cz += much;
@@ -1281,6 +1718,9 @@
 				mex++;
 				pex = peasycap->field_buffer[kex][mex].pgo;
 				rex = PAGE_SIZE;
+				if (peasycap->field_buffer[kex][mex].input != \
+						(0x08|peasycap->input))
+					badinput = true;
 			}
 			pad  += more;
 			rad -= more;
@@ -1307,6 +1747,16 @@
 				mex++;
 				pex = peasycap->field_buffer[kex][mex].pgo;
 				rex = PAGE_SIZE;
+				if (peasycap->field_buffer[kex][mex].input != \
+						(0x08|peasycap->input)) {
+					JOM(8, "ERROR: 0x%02X=->field_buffer"\
+						"[%i][%i].input, " \
+						"0x%02X=(0x08|->input)\n", \
+						peasycap->field_buffer\
+						[kex][mex].input, kex, mex, \
+						(0x08|peasycap->input));
+					badinput = true;
+				}
 			}
 			much = over;
 			if (rex < much)
@@ -1325,39 +1775,39 @@
 /*---------------------------------------------------------------------------*/
 c2 = (mex + 1)*PAGE_SIZE - rex;
 if (cz != c2)
-	SAY("ERROR: discrepancy %i in bytes read\n", c2 - cz);
+	SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz);
 c3 = (mad + 1)*PAGE_SIZE - rad;
 
 if (false == decimatepixel) {
 	if (bytesperpixel * \
 		cz != c3) \
-		SAY("ERROR: discrepancy %i in bytes written\n", \
+		SAM("ERROR: discrepancy %i in bytes written\n", \
 						c3 - (bytesperpixel * \
 									cz));
 } else {
 	if (false == odd) {
 		if (bytesperpixel * \
 			cz != (4 * c3))
-			SAY("ERROR: discrepancy %i in bytes written\n", \
+			SAM("ERROR: discrepancy %i in bytes written\n", \
 						(2*c3)-(bytesperpixel * \
 									cz));
 		} else {
 			if (0 != c3)
-				SAY("ERROR: discrepancy %i " \
+				SAM("ERROR: discrepancy %i " \
 						"in bytes written\n", c3);
 		}
 }
 if (rump)
-	SAY("ERROR: undischarged cache at end of line in frame buffer\n");
+	SAM("WORRY: undischarged cache at end of line in frame buffer\n");
 
-JOT(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
-JOT(8, "===== field2frame(): %i=mad  %i=rad\n", mad, rad);
+JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
+JOM(8, "===== field2frame(): %i=mad  %i=rad\n", mad, rad);
 
 if (true == odd)
-	JOT(8, "+++++ field2frame():  frame buffer %i is full\n", kad);
+	JOM(8, "+++++ field2frame():  frame buffer %i is full\n", kad);
 
 if (peasycap->field_read == peasycap->field_fill)
-	SAY("WARNING: on exit, filling field buffer %i\n", \
+	SAM("WARNING: on exit, filling field buffer %i\n", \
 							peasycap->field_read);
 /*---------------------------------------------------------------------------*/
 /*
@@ -1365,23 +1815,24 @@
  */
 /*---------------------------------------------------------------------------*/
 do_gettimeofday(&timeval);
-if (timeval0.tv_sec) {
+if (peasycap->timeval6.tv_sec) {
 	below = ((long long int)(1000000)) * \
-		((long long int)(timeval.tv_sec  - timeval0.tv_sec)) + \
-			 (long long int)(timeval.tv_usec - timeval0.tv_usec);
+		((long long int)(timeval.tv_sec - \
+					peasycap->timeval6.tv_sec)) + \
+		 (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec);
 	above = (long long int)1000000;
 
 	sdr = signed_div(above, below);
 	above = sdr.quotient;
 	remainder = (__u32)sdr.remainder;
 
-	JOT(8, "video streaming at %3lli.%03i fields per second\n", above, \
+	JOM(8, "video streaming at %3lli.%03i fields per second\n", above, \
 							(remainder/1000));
 }
-timeval0 = timeval;
+peasycap->timeval6 = timeval;
 
 if (caches)
-	JOT(8, "%i=caches\n", caches);
+	JOM(8, "%i=caches\n", caches);
 return 0;
 }
 /*****************************************************************************/
@@ -1434,7 +1885,7 @@
 					__u8 mask, __u8 margin, bool isuy)
 {
 static __s32 ay[256], bu[256], rv[256], gu[256], gv[256];
-static __u8 cache[8], *pcache;
+__u8 *pcache;
 __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
 int  bytesperpixel;
 bool byteswaporder, decimatepixel, last;
@@ -1442,7 +1893,7 @@
 __s32 s32;
 
 if (much % 2) {
-	SAY("MISTAKE: much is odd\n");
+	SAM("MISTAKE: much is odd\n");
 	return -EFAULT;
 }
 bytesperpixel = peasycap->bytesperpixel;
@@ -1475,30 +1926,31 @@
 		ay[j] = ay[16];
 	for (j = 236; j < 256; j++)
 		ay[j] = ay[235];
-	JOT(8, "lookup tables are prepared\n");
+	JOM(8, "lookup tables are prepared\n");
 }
-if ((__u8 *)NULL == pcache)
-	pcache = &cache[0];
+pcache = peasycap->pcache;
+if (NULL == pcache)
+	pcache = &peasycap->cache[0];
 /*---------------------------------------------------------------------------*/
 /*
  *  TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
  */
 /*---------------------------------------------------------------------------*/
 if (!pcache) {
-	SAY("MISTAKE: pcache is NULL\n");
+	SAM("MISTAKE: pcache is NULL\n");
 	return -EFAULT;
 }
 
-if (pcache != &cache[0])
-	JOT(16, "cache has %i bytes\n", (int)(pcache - &cache[0]));
-p2 = &cache[0];
-p3 = (__u8 *)pad - (int)(pcache - &cache[0]);
+if (pcache != &peasycap->cache[0])
+	JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0]));
+p2 = &peasycap->cache[0];
+p3 = (__u8 *)pad - (int)(pcache - &peasycap->cache[0]);
 while (p2 < pcache) {
 	*p3++ = *p2;  p2++;
 }
-pcache = &cache[0];
+pcache = &peasycap->cache[0];
 if (p3 != pad) {
-	SAY("MISTAKE: pointer misalignment\n");
+	SAM("MISTAKE: pointer misalignment\n");
 	return -EFAULT;
 }
 /*---------------------------------------------------------------------------*/
@@ -1513,7 +1965,7 @@
 	v = *(p2 - 1);
 
 if (rump)
-	JOT(16, "%4i=much  %4i=more  %i=rump\n", much, more, rump);
+	JOM(16, "%4i=much  %4i=more  %i=rump\n", much, more, rump);
 
 /*---------------------------------------------------------------------------*/
 switch (bytesperpixel) {
@@ -1619,7 +2071,7 @@
 							0 : (__u8)s32);
 
 				if ((true == last) && rump) {
-					pcache = &cache[0];
+					pcache = &peasycap->cache[0];
 					switch (bytesperpixel - rump) {
 					case 1: {
 						*p3 = r;
@@ -1634,7 +2086,7 @@
 						break;
 					}
 					default: {
-						SAY("MISTAKE: %i=rump\n", \
+						SAM("MISTAKE: %i=rump\n", \
 							bytesperpixel - rump);
 						return -EFAULT;
 					}
@@ -1692,7 +2144,7 @@
 								0 : (__u8)s32);
 
 				if ((true == last) && rump) {
-					pcache = &cache[0];
+					pcache = &peasycap->cache[0];
 					switch (bytesperpixel - rump) {
 					case 1: {
 						*p3 = b;
@@ -1707,7 +2159,7 @@
 						break;
 					}
 					default: {
-						SAY("MISTAKE: %i=rump\n", \
+						SAM("MISTAKE: %i=rump\n", \
 							bytesperpixel - rump);
 						return -EFAULT;
 					}
@@ -1768,7 +2220,7 @@
 								0 : (__u8)s32);
 
 					if ((true == last) && rump) {
-						pcache = &cache[0];
+						pcache = &peasycap->cache[0];
 						switch (bytesperpixel - rump) {
 						case 1: {
 							*p3 = r;
@@ -1783,7 +2235,7 @@
 							break;
 						}
 						default: {
-							SAY("MISTAKE: " \
+							SAM("MISTAKE: " \
 							"%i=rump\n", \
 							bytesperpixel - rump);
 							return -EFAULT;
@@ -1844,7 +2296,7 @@
 								0 : (__u8)s32);
 
 					if ((true == last) && rump) {
-						pcache = &cache[0];
+						pcache = &peasycap->cache[0];
 						switch (bytesperpixel - rump) {
 						case 1: {
 							*p3 = b;
@@ -1859,7 +2311,7 @@
 							break;
 						}
 						default: {
-							SAY("MISTAKE: " \
+							SAM("MISTAKE: " \
 							"%i=rump\n", \
 							bytesperpixel - rump);
 							return -EFAULT;
@@ -1924,7 +2376,7 @@
 								0 : (__u8)s32);
 
 				if ((true == last) && rump) {
-					pcache = &cache[0];
+					pcache = &peasycap->cache[0];
 					switch (bytesperpixel - rump) {
 					case 1: {
 						*p3 = r;
@@ -1948,7 +2400,7 @@
 						break;
 					}
 					default: {
-						SAY("MISTAKE: %i=rump\n", \
+						SAM("MISTAKE: %i=rump\n", \
 							bytesperpixel - rump);
 						return -EFAULT;
 					}
@@ -2006,7 +2458,7 @@
 								0 : (__u8)s32);
 
 				if ((true == last) && rump) {
-					pcache = &cache[0];
+					pcache = &peasycap->cache[0];
 					switch (bytesperpixel - rump) {
 					case 1: {
 						*p3 = b;
@@ -2030,7 +2482,7 @@
 						break;
 					}
 					default: {
-						SAY("MISTAKE: %i=rump\n", \
+						SAM("MISTAKE: %i=rump\n", \
 							bytesperpixel - rump);
 						return -EFAULT;
 					}
@@ -2093,7 +2545,7 @@
 								0 : (__u8)s32);
 
 					if ((true == last) && rump) {
-						pcache = &cache[0];
+						pcache = &peasycap->cache[0];
 						switch (bytesperpixel - rump) {
 						case 1: {
 							*p3 = r;
@@ -2117,7 +2569,7 @@
 							break;
 						}
 						default: {
-							SAY("MISTAKE: " \
+							SAM("MISTAKE: " \
 							"%i=rump\n", \
 							bytesperpixel - \
 							rump);
@@ -2178,7 +2630,7 @@
 								0 : (__u8)s32);
 
 					if ((true == last) && rump) {
-						pcache = &cache[0];
+						pcache = &peasycap->cache[0];
 						switch (bytesperpixel - rump) {
 						case 1: {
 							*p3 = b;
@@ -2202,7 +2654,7 @@
 							break;
 						}
 						default: {
-							SAY("MISTAKE: " \
+							SAM("MISTAKE: " \
 							"%i=rump\n", \
 							bytesperpixel - rump);
 							return -EFAULT;
@@ -2226,48 +2678,13 @@
 	break;
 	}
 default: {
-	SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
+	SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
 	return -EFAULT;
 	}
 }
 return 0;
 }
 /*****************************************************************************/
-void
-debrief(struct easycap *peasycap)
-{
-if ((struct usb_device *)NULL != peasycap->pusb_device) {
-	check_stk(peasycap->pusb_device);
-	check_saa(peasycap->pusb_device);
-	sayreadonly(peasycap);
-	SAY("%i=peasycap->field_fill\n", peasycap->field_fill);
-	SAY("%i=peasycap->field_read\n", peasycap->field_read);
-	SAY("%i=peasycap->frame_fill\n", peasycap->frame_fill);
-	SAY("%i=peasycap->frame_read\n", peasycap->frame_read);
-}
-return;
-}
-/*****************************************************************************/
-void
-sayreadonly(struct easycap *peasycap)
-{
-static int done;
-int got00, got1F, got60, got61, got62;
-
-if ((!done) && ((struct usb_device *)NULL != peasycap->pusb_device)) {
-	done = 1;
-	got00 = read_saa(peasycap->pusb_device, 0x00);
-	got1F = read_saa(peasycap->pusb_device, 0x1F);
-	got60 = read_saa(peasycap->pusb_device, 0x60);
-	got61 = read_saa(peasycap->pusb_device, 0x61);
-	got62 = read_saa(peasycap->pusb_device, 0x62);
-	SAY("0x%02X=reg0x00  0x%02X=reg0x1F\n", got00, got1F);
-	SAY("0x%02X=reg0x60  0x%02X=reg0x61  0x%02X=reg0x62\n", \
-							got60, got61, got62);
-}
-return;
-}
-/*****************************************************************************/
 /*---------------------------------------------------------------------------*/
 /*
  *  SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
@@ -2292,11 +2709,16 @@
 struct easycap *peasycap;
 
 peasycap = pvma->vm_private_data;
-if (NULL != peasycap)
-	peasycap->vma_many++;
-
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return;
+}
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return;
+}
+peasycap->vma_many++;
 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
-
 return;
 }
 /*****************************************************************************/
@@ -2306,10 +2728,16 @@
 struct easycap *peasycap;
 
 peasycap = pvma->vm_private_data;
-if (NULL != peasycap) {
-	peasycap->vma_many--;
-	JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return;
 }
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return;
+}
+peasycap->vma_many--;
+JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
 return;
 }
 /*****************************************************************************/
@@ -2355,24 +2783,22 @@
 	SAY("ERROR: peasycap is NULL\n");
 	return retcode;
 }
-mutex_lock(&(peasycap->mutex_mmap_video[0]));
 /*---------------------------------------------------------------------------*/
 pbuf = peasycap->frame_buffer[k][m].pgo;
 if (NULL == pbuf) {
-	SAY("ERROR:  pbuf is NULL\n");
+	SAM("ERROR:  pbuf is NULL\n");
 	goto finish;
 }
 page = virt_to_page(pbuf);
 if (NULL == page) {
-	SAY("ERROR:  page is NULL\n");
+	SAM("ERROR:  page is NULL\n");
 	goto finish;
 }
 get_page(page);
 /*---------------------------------------------------------------------------*/
 finish:
-mutex_unlock(&(peasycap->mutex_mmap_video[0]));
 if (NULL == page) {
-	SAY("ERROR:  page is NULL after get_page(page)\n");
+	SAM("ERROR:  page is NULL after get_page(page)\n");
 } else {
 	pvmf->page = page;
 	retcode = VM_FAULT_MINOR;
@@ -2383,7 +2809,7 @@
 /*---------------------------------------------------------------------------*/
 /*
  *  ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
- *  PROVIDED peasycap->video_idle IS ZER0.  REGARDLESS OF THIS BEING TRUE,
+ *  PROVIDED peasycap->video_idle IS ZERO.  REGARDLESS OF THIS BEING TRUE,
  *  IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
  *
  *  THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
@@ -2400,7 +2826,8 @@
  *      0 != (kount & 0x8000)   => AT LEAST ONE URB COMPLETED WITH ERRORS
  *      0 != (kount & 0x4000)   => BUFFER HAS TOO MUCH DATA
  *      0 != (kount & 0x2000)   => BUFFER HAS NOT ENOUGH DATA
- *      0 != (kount & 0x0400)   => FIELD WAS SUBMITTED BY BRIDGER ROUTINE
+ *      0 != (kount & 0x1000)   => BUFFER HAS DATA FROM DISPARATE INPUTS
+ *      0 != (kount & 0x0400)   => RESERVED
  *      0 != (kount & 0x0200)   => FIELD BUFFER NOT YET CHECKED
  *      0 != (kount & 0x0100)   => BUFFER HAS TWO EXTRA BYTES - WHY?
  */
@@ -2408,19 +2835,14 @@
 void
 easycap_complete(struct urb *purb)
 {
-static int mt;
 struct easycap *peasycap;
 struct data_buffer *pfield_buffer;
 char errbuf[16];
 int i, more, much, leap, rc, last;
 int videofieldamount;
-unsigned int override;
+unsigned int override, bad;
 int framestatus, framelength, frameactual, frameoffset;
 __u8 *pu;
-#if defined(BRIDGER)
-struct timeval timeval;
-long long usec;
-#endif /*BRIDGER*/
 
 if (NULL == purb) {
 	SAY("ERROR: easycap_complete(): purb is NULL\n");
@@ -2431,74 +2853,78 @@
 	SAY("ERROR: easycap_complete(): peasycap is NULL\n");
 	return;
 }
-
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return;
+}
 if (peasycap->video_eof)
 	return;
-
 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
 	if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
 		break;
-JOT(16, "%2i=urb\n", i);
+JOM(16, "%2i=urb\n", i);
 last = peasycap->video_isoc_sequence;
 if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \
 						(0 != i)) || \
 	(((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \
 						((last + 1) != i))) {
-	SAY("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
+	JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
 }
 peasycap->video_isoc_sequence = i;
 
 if (peasycap->video_idle) {
-	JOT(16, "%i=video_idle  %i=video_isoc_streaming\n", \
+	JOM(16, "%i=video_idle  %i=video_isoc_streaming\n", \
 			peasycap->video_idle, peasycap->video_isoc_streaming);
 	if (peasycap->video_isoc_streaming) {
 		rc = usb_submit_urb(purb, GFP_ATOMIC);
 		if (0 != rc) {
-			SAY("ERROR: while %i=video_idle, " \
-					"usb_submit_urb() failed with rc:\n", \
-							peasycap->video_idle);
 			switch (rc) {
 			case -ENOMEM: {
-				SAY("ENOMEM\n");
+				SAM("ENOMEM\n");
 				break;
 			}
 			case -ENODEV: {
-				SAY("ENODEV\n");
+				SAM("ENODEV\n");
 				break;
 			}
 			case -ENXIO: {
-				SAY("ENXIO\n");
+				SAM("ENXIO\n");
 				break;
 			}
 			case -EINVAL: {
-				SAY("EINVAL\n");
+				SAM("EINVAL\n");
 				break;
 			}
 			case -EAGAIN: {
-				SAY("EAGAIN\n");
+				SAM("EAGAIN\n");
 				break;
 			}
 			case -EFBIG: {
-				SAY("EFBIG\n");
+				SAM("EFBIG\n");
 				break;
 			}
 			case -EPIPE: {
-				SAY("EPIPE\n");
+				SAM("EPIPE\n");
 				break;
 			}
 			case -EMSGSIZE: {
-				SAY("EMSGSIZE\n");
+				SAM("EMSGSIZE\n");
 				break;
 			}
 			case -ENOSPC: {
-				SAY("ENOSPC\n");
+				SAM("ENOSPC\n");
 				break;
 			}
 			default: {
-				SAY("0x%08X\n", rc);
+				SAM("0x%08X\n", rc);
 				break;
 			}
 			}
+			if (-ENODEV != rc) \
+				SAM("ERROR: while %i=video_idle, " \
+							"usb_submit_urb() " \
+							"failed with rc:\n", \
+							peasycap->video_idle);
 		}
 	}
 return;
@@ -2506,80 +2932,80 @@
 override = 0;
 /*---------------------------------------------------------------------------*/
 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
-	SAY("ERROR: bad peasycap->field_fill\n");
+	SAM("ERROR: bad peasycap->field_fill\n");
 	return;
 }
 if (purb->status) {
 	if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
-		JOT(8, "urb status -ESHUTDOWN or -ENOENT\n");
+		JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
 		return;
 	}
 
 	(peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
-	SAY("ERROR: bad urb status:\n");
+	SAM("ERROR: bad urb status:\n");
 	switch (purb->status) {
 	case -EINPROGRESS: {
-		SAY("-EINPROGRESS\n"); break;
+		SAM("-EINPROGRESS\n"); break;
 	}
 	case -ENOSR: {
-		SAY("-ENOSR\n"); break;
+		SAM("-ENOSR\n"); break;
 	}
 	case -EPIPE: {
-		SAY("-EPIPE\n"); break;
+		SAM("-EPIPE\n"); break;
 	}
 	case -EOVERFLOW: {
-		SAY("-EOVERFLOW\n"); break;
+		SAM("-EOVERFLOW\n"); break;
 	}
 	case -EPROTO: {
-		SAY("-EPROTO\n"); break;
+		SAM("-EPROTO\n"); break;
 	}
 	case -EILSEQ: {
-		SAY("-EILSEQ\n"); break;
+		SAM("-EILSEQ\n"); break;
 	}
 	case -ETIMEDOUT: {
-		SAY("-ETIMEDOUT\n"); break;
+		SAM("-ETIMEDOUT\n"); break;
 	}
 	case -EMSGSIZE: {
-		SAY("-EMSGSIZE\n"); break;
+		SAM("-EMSGSIZE\n"); break;
 	}
 	case -EOPNOTSUPP: {
-		SAY("-EOPNOTSUPP\n"); break;
+		SAM("-EOPNOTSUPP\n"); break;
 	}
 	case -EPFNOSUPPORT: {
-		SAY("-EPFNOSUPPORT\n"); break;
+		SAM("-EPFNOSUPPORT\n"); break;
 	}
 	case -EAFNOSUPPORT: {
-		SAY("-EAFNOSUPPORT\n"); break;
+		SAM("-EAFNOSUPPORT\n"); break;
 	}
 	case -EADDRINUSE: {
-		SAY("-EADDRINUSE\n"); break;
+		SAM("-EADDRINUSE\n"); break;
 	}
 	case -EADDRNOTAVAIL: {
-		SAY("-EADDRNOTAVAIL\n"); break;
+		SAM("-EADDRNOTAVAIL\n"); break;
 	}
 	case -ENOBUFS: {
-		SAY("-ENOBUFS\n"); break;
+		SAM("-ENOBUFS\n"); break;
 	}
 	case -EISCONN: {
-		SAY("-EISCONN\n"); break;
+		SAM("-EISCONN\n"); break;
 	}
 	case -ENOTCONN: {
-		SAY("-ENOTCONN\n"); break;
+		SAM("-ENOTCONN\n"); break;
 	}
 	case -ESHUTDOWN: {
-		SAY("-ESHUTDOWN\n"); break;
+		SAM("-ESHUTDOWN\n"); break;
 	}
 	case -ENOENT: {
-		SAY("-ENOENT\n"); break;
+		SAM("-ENOENT\n"); break;
 	}
 	case -ECONNRESET: {
-		SAY("-ECONNRESET\n"); break;
+		SAM("-ECONNRESET\n"); break;
 	}
 	case -ENOSPC: {
-		SAY("ENOSPC\n"); break;
+		SAM("ENOSPC\n"); break;
 	}
 	default: {
-		SAY("unknown error code 0x%08X\n", purb->status); break;
+		SAM("unknown error code 0x%08X\n", purb->status); break;
 	}
 	}
 /*---------------------------------------------------------------------------*/
@@ -2638,7 +3064,7 @@
 				strcpy(&errbuf[0], "-ECONNRESET"); break;
 			}
 			case -ENOSPC: {
-				SAY("ENOSPC\n"); break;
+				SAM("ENOSPC\n"); break;
 			}
 			case -ESHUTDOWN: {
 				strcpy(&errbuf[0], "-ESHUTDOWN"); break;
@@ -2653,7 +3079,7 @@
 		frameactual = purb->iso_frame_desc[i].actual_length;
 		frameoffset = purb->iso_frame_desc[i].offset;
 
-		JOT(16, "frame[%2i]:" \
+		JOM(16, "frame[%2i]:" \
 				"%4i=status "  \
 				"%4i=actual "  \
 				"%4i=length "  \
@@ -2667,19 +3093,20 @@
 				PAGE_SIZE) + \
 				(int)(pfield_buffer->pto - pfield_buffer->pgo);
 		if (4 == more)
-			mt++;
+			peasycap->video_mt++;
 		if (4 < more) {
-			if (mt) {
-				JOT(8, "%4i empty video urb frames\n", mt);
-				mt = 0;
+			if (peasycap->video_mt) {
+				JOM(8, "%4i empty video urb frames\n", \
+							peasycap->video_mt);
+				peasycap->video_mt = 0;
 			}
 			if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
-				SAY("ERROR: bad peasycap->field_fill\n");
+				SAM("ERROR: bad peasycap->field_fill\n");
 				return;
 			}
 			if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
 							peasycap->field_page) {
-				SAY("ERROR: bad peasycap->field_page\n");
+				SAM("ERROR: bad peasycap->field_page\n");
 				return;
 			}
 			pfield_buffer = &peasycap->field_buffer\
@@ -2712,11 +3139,13 @@
 						peasycap->videofieldamount) {
 					if (2 == videofieldamount - \
 							peasycap->\
-							videofieldamount)
+							videofieldamount) {
 						(peasycap->field_buffer\
 						[peasycap->field_fill]\
 							[0].kount) |= 0x0100;
-					else
+						peasycap->video_junk += (1 + \
+							VIDEO_JUNK_TOLERATE);
+					} else
 						(peasycap->field_buffer\
 						[peasycap->field_fill]\
 							[0].kount) |= 0x4000;
@@ -2727,53 +3156,74 @@
 						[peasycap->field_fill]\
 							[0].kount) |= 0x2000;
 					}
-				if (!(0xFF00 & peasycap->field_buffer\
+					bad = 0xFF00 & peasycap->field_buffer\
 						[peasycap->field_fill]\
-						[0].kount)) {
-					(peasycap->video_junk)--;
-					if (-16 > peasycap->video_junk)
-						peasycap->video_junk = -16;
-					peasycap->field_read = \
+						[0].kount;
+					if (!bad) {
+						(peasycap->video_junk)--;
+						if (-VIDEO_JUNK_TOLERATE > \
+							peasycap->video_junk) \
+							peasycap->video_junk =\
+							-VIDEO_JUNK_TOLERATE;
+						peasycap->field_read = \
 							(peasycap->\
 								field_fill)++;
-
-					if (FIELD_BUFFER_MANY <= \
-						peasycap->field_fill)
-						peasycap->field_fill = 0;
-					peasycap->field_page = 0;
-					pfield_buffer = &peasycap->\
-						field_buffer\
-						[peasycap->field_fill]\
-						[peasycap->field_page];
-					pfield_buffer->pto = \
+						if (FIELD_BUFFER_MANY <= \
+								peasycap->\
+								field_fill)
+							peasycap->\
+								field_fill = 0;
+						peasycap->field_page = 0;
+						pfield_buffer = &peasycap->\
+							field_buffer\
+							[peasycap->\
+							field_fill]\
+							[peasycap->\
+							field_page];
+						pfield_buffer->pto = \
 							pfield_buffer->pgo;
-
-					JOT(8, "bumped to: %i=peasycap->" \
-						"field_fill  %i=parity\n", \
-						peasycap->field_fill, \
-						0x00FF & pfield_buffer->kount);
-					JOT(8, "field buffer %i has %i " \
-						"bytes fit to be read\n", \
-						peasycap->field_read, \
-						videofieldamount);
-					JOT(8, "wakeup call to wq_video, " \
-						"%i=field_read %i=field_fill "\
-						"%i=parity\n", \
-						peasycap->field_read, \
-						peasycap->field_fill, \
-						0x00FF & peasycap->\
-						field_buffer[peasycap->\
-						field_read][0].kount);
-					wake_up_interruptible(&(peasycap->\
-								wq_video));
-					do_gettimeofday(&peasycap->timeval7);
+						JOM(8, "bumped to: %i="\
+							"peasycap->" \
+							"field_fill  %i="\
+							"parity\n", \
+							peasycap->field_fill, \
+							0x00FF & \
+							pfield_buffer->kount);
+						JOM(8, "field buffer %i has "\
+							"%i bytes fit to be "\
+							"read\n", \
+							peasycap->field_read, \
+							videofieldamount);
+						JOM(8, "wakeup call to "\
+							"wq_video, " \
+							"%i=field_read "\
+							"%i=field_fill "\
+							"%i=parity\n", \
+							peasycap->field_read, \
+							peasycap->field_fill, \
+							0x00FF & peasycap->\
+							field_buffer\
+							[peasycap->\
+							field_read][0].kount);
+						wake_up_interruptible\
+							(&(peasycap->\
+								 wq_video));
+						do_gettimeofday\
+							(&peasycap->timeval7);
 					} else {
 					peasycap->video_junk++;
-					JOT(8, "field buffer %i had %i " \
-						"bytes, now discarded\n", \
+					if (bad & 0x0010) \
+						peasycap->video_junk += \
+						(1 + VIDEO_JUNK_TOLERATE/2);
+					JOM(8, "field buffer %i had %i " \
+						"bytes, now discarded: "\
+						"0x%04X\n", \
 						peasycap->field_fill, \
-						videofieldamount);
-
+						videofieldamount,\
+						(0xFF00 & \
+						peasycap->field_buffer\
+						[peasycap->field_fill][0].\
+						kount));
 					(peasycap->field_fill)++;
 
 					if (FIELD_BUFFER_MANY <= \
@@ -2787,20 +3237,22 @@
 					pfield_buffer->pto = \
 							pfield_buffer->pgo;
 
-					JOT(8, "bumped to: %i=peasycap->" \
+					JOM(8, "bumped to: %i=peasycap->" \
 						"field_fill  %i=parity\n", \
 						peasycap->field_fill, \
 						0x00FF & pfield_buffer->kount);
 				}
 				if (8 == more) {
-					JOT(8, "end-of-field: received " \
+					JOM(8, "end-of-field: received " \
 						"parity byte 0x%02X\n", \
 						(0xFF & *pu));
 					if (0x40 & *pu)
 						pfield_buffer->kount = 0x0000;
 					else
 						pfield_buffer->kount = 0x0001;
-					JOT(8, "end-of-field: 0x%02X=kount\n",\
+					pfield_buffer->input = 0x08 | \
+						(0x07 & peasycap->input);
+					JOM(8, "end-of-field: 0x%02X=kount\n",\
 						0xFF & pfield_buffer->kount);
 				}
 			}
@@ -2813,12 +3265,12 @@
 			more -= leap;
 
 			if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
-				SAY("ERROR: bad peasycap->field_fill\n");
+				SAM("ERROR: bad peasycap->field_fill\n");
 				return;
 			}
 			if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
 							peasycap->field_page) {
-				SAY("ERROR: bad peasycap->field_page\n");
+				SAM("ERROR: bad peasycap->field_page\n");
 				return;
 			}
 			pfield_buffer = &peasycap->field_buffer\
@@ -2829,7 +3281,7 @@
 						[peasycap->field_page];
 				if (PAGE_SIZE < (pfield_buffer->pto - \
 							pfield_buffer->pgo)) {
-					SAY("ERROR: bad pfield_buffer->pto\n");
+					SAM("ERROR: bad pfield_buffer->pto\n");
 					return;
 				}
 				if (PAGE_SIZE == (pfield_buffer->pto - \
@@ -2837,7 +3289,7 @@
 					(peasycap->field_page)++;
 					if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
 							peasycap->field_page) {
-						JOT(16, "wrapping peasycap->" \
+						JOM(16, "wrapping peasycap->" \
 							"field_page\n");
 						peasycap->field_page = 0;
 					}
@@ -2847,6 +3299,15 @@
 							[peasycap->field_page];
 					pfield_buffer->pto = \
 							pfield_buffer->pgo;
+					pfield_buffer->input = 0x08 | \
+						(0x07 & peasycap->input);
+					if ((peasycap->field_buffer[peasycap->\
+							field_fill][0]).\
+								input != \
+							pfield_buffer->input)
+						(peasycap->field_buffer\
+							[peasycap->field_fill]\
+							[0]).kount |= 0x1000;
 				}
 
 				much = PAGE_SIZE - (int)(pfield_buffer->pto - \
@@ -2865,55 +3326,6 @@
 }
 /*---------------------------------------------------------------------------*/
 /*
- *
- *
- *             *** UNDER DEVELOPMENT/TESTING - NOT READY YET! ***
- *
- *
- *
- *  VIDEOTAPES MAY HAVE BEEN MANUALLY PAUSED AND RESTARTED DURING RECORDING.
- *  THIS CAUSES LOSS OF SYNC, CONFUSING DOWNSTREAM USERSPACE PROGRAMS WHICH
- *  MAY INTERPRET THE INTERRUPTION AS A SYMPTOM OF LATENCY.  TO OVERCOME THIS
- *  THE DRIVER BRIDGES THE HIATUS BY SENDING DUMMY VIDEO FRAMES AT ROUGHLY
- *  THE RIGHT TIME INTERVALS IN THE HOPE OF PERSUADING THE DOWNSTREAM USERSPACE
- *  PROGRAM TO RESUME NORMAL SERVICE WHEN THE INTERRUPTION IS OVER.
- */
-/*---------------------------------------------------------------------------*/
-#if defined(BRIDGER)
-do_gettimeofday(&timeval);
-if (peasycap->timeval7.tv_sec) {
-	usec = 1000000*(timeval.tv_sec  - peasycap->timeval7.tv_sec) + \
-			(timeval.tv_usec - peasycap->timeval7.tv_usec);
-	if (usec > (peasycap->usec + peasycap->tolerate)) {
-		JOT(8, "bridging hiatus\n");
-		peasycap->video_junk = 0;
-		peasycap->field_buffer[peasycap->field_fill][0].kount |= 0x0400;
-
-		peasycap->field_read = (peasycap->field_fill)++;
-
-		if (FIELD_BUFFER_MANY <= peasycap->field_fill) \
-						peasycap->field_fill = 0;
-		peasycap->field_page = 0;
-		pfield_buffer = &peasycap->field_buffer\
-				[peasycap->field_fill][peasycap->field_page];
-		pfield_buffer->pto = pfield_buffer->pgo;
-
-		JOT(8, "bumped to: %i=peasycap->field_fill  %i=parity\n", \
-			peasycap->field_fill, 0x00FF & pfield_buffer->kount);
-		JOT(8, "field buffer %i has %i bytes to be overwritten\n", \
-			peasycap->field_read, videofieldamount);
-		JOT(8, "wakeup call to wq_video, " \
-			"%i=field_read %i=field_fill %i=parity\n", \
-			peasycap->field_read, peasycap->field_fill, \
-			0x00FF & \
-			peasycap->field_buffer[peasycap->field_read][0].kount);
-		wake_up_interruptible(&(peasycap->wq_video));
-		do_gettimeofday(&peasycap->timeval7);
-	}
-}
-#endif /*BRIDGER*/
-/*---------------------------------------------------------------------------*/
-/*
  *  RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
  *
  *  IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
@@ -2921,51 +3333,57 @@
  */
 /*---------------------------------------------------------------------------*/
 if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
-	SAY("easycap driver shutting down on condition green\n");
+	SAM("easycap driver shutting down on condition green\n");
+	peasycap->status = 1;
 	peasycap->video_eof = 1;
+	peasycap->video_junk = 0;
+	wake_up_interruptible(&peasycap->wq_video);
+#if !defined(PERSEVERE)
 	peasycap->audio_eof = 1;
-	peasycap->video_junk = -VIDEO_ISOC_BUFFER_MANY;
-	wake_up_interruptible(&(peasycap->wq_video));
-	wake_up_interruptible(&(peasycap->wq_audio));
+	wake_up_interruptible(&peasycap->wq_audio);
+#endif /*PERSEVERE*/
 	return;
 }
 if (peasycap->video_isoc_streaming) {
 	rc = usb_submit_urb(purb, GFP_ATOMIC);
 	if (0 != rc) {
-		SAY("ERROR: while %i=video_idle, usb_submit_urb() failed " \
-					"with rc:\n", peasycap->video_idle);
 		switch (rc) {
 		case -ENOMEM: {
-			SAY("ENOMEM\n"); break;
+			SAM("ENOMEM\n"); break;
 		}
 		case -ENODEV: {
-			SAY("ENODEV\n"); break;
+			SAM("ENODEV\n"); break;
 		}
 		case -ENXIO: {
-			SAY("ENXIO\n"); break;
+			SAM("ENXIO\n"); break;
 		}
 		case -EINVAL: {
-			SAY("EINVAL\n"); break;
+			SAM("EINVAL\n"); break;
 		}
 		case -EAGAIN: {
-			SAY("EAGAIN\n"); break;
+			SAM("EAGAIN\n"); break;
 		}
 		case -EFBIG: {
-			SAY("EFBIG\n"); break;
+			SAM("EFBIG\n"); break;
 		}
 		case -EPIPE: {
-			SAY("EPIPE\n"); break;
+			SAM("EPIPE\n"); break;
 		}
 		case -EMSGSIZE: {
-			SAY("EMSGSIZE\n");  break;
+			SAM("EMSGSIZE\n");  break;
 		}
 		case -ENOSPC: {
-			SAY("ENOSPC\n"); break;
+			SAM("ENOSPC\n"); break;
 		}
 		default: {
-			SAY("0x%08X\n", rc); break;
+			SAM("0x%08X\n", rc); break;
 		}
 		}
+		if (-ENODEV != rc) \
+			SAM("ERROR: while %i=video_idle, " \
+						"usb_submit_urb() " \
+						"failed with rc:\n", \
+						peasycap->video_idle);
 	}
 }
 return;
@@ -2977,8 +3395,8 @@
  *                                  FIXME
  *
  *
- *  THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS
- *  PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
+ *  THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE EasyCAP
+ *  IS PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
  *  IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
  *
  *  THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
@@ -2994,7 +3412,7 @@
 struct usb_interface_descriptor *pusb_interface_descriptor;
 struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
 struct urb *purb;
-static struct easycap *peasycap /*=NULL*/;
+struct easycap *peasycap;
 struct data_urb *pdata_urb;
 size_t wMaxPacketSize;
 int ISOCwMaxPacketSize;
@@ -3004,19 +3422,32 @@
 __u8 bEndpointAddress;
 __u8 ISOCbEndpointAddress;
 __u8 INTbEndpointAddress;
-int isin, i, j, k, m;
+int isin, i, j, k, m, rc;
 __u8 bInterfaceNumber;
 __u8 bInterfaceClass;
 __u8 bInterfaceSubClass;
 void *pbuf;
 int okalt[8], isokalt;
-int okepn[8], isokepn;
-int okmps[8], isokmps;
+int okepn[8];
+int okmps[8];
 int maxpacketsize;
-int rc;
+__u16 mask;
+__s32 value;
+struct easycap_format *peasycap_format;
 
 JOT(4, "\n");
 
+if (!dongle_done) {
+	dongle_done = 1;
+	for (k = 0; k < DONGLE_MANY; k++) {
+		easycap_dongle[k].peasycap = (struct easycap *)NULL;
+		mutex_init(&easycap_dongle[k].mutex_video);
+		mutex_init(&easycap_dongle[k].mutex_audio);
+	}
+}
+
+peasycap = (struct easycap *)NULL;
+
 if ((struct usb_interface *)NULL == pusb_interface) {
 	SAY("ERROR: pusb_interface is NULL\n");
 	return -EFAULT;
@@ -3117,46 +3548,83 @@
 /*
  *  A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
  *  IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap.  THIS
- *  SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY
- *  UNPLUGGED.
- */
+ *  SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS
+ *  PHYSICALLY UNPLUGGED.
+ *
+ *  THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
+ *  INTERFACES 1 AND 2 ARE PROBED.
+ *
+ *  IF TWO EasyCAPs ARE PLUGGED IN NEARLY SIMULTANEOUSLY THERE WILL
+ *  BE TROUBLE.  BEWARE.
+*/
 /*---------------------------------------------------------------------------*/
 if (0 == bInterfaceNumber) {
 	peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
 	if (NULL == peasycap) {
 		SAY("ERROR: Could not allocate peasycap\n");
 		return -ENOMEM;
-	} else {
-		peasycap->allocation_video_struct = sizeof(struct easycap);
-		peasycap->allocation_video_page = 0;
-		peasycap->allocation_video_urb = 0;
-		peasycap->allocation_audio_struct = 0;
-		peasycap->allocation_audio_page = 0;
-		peasycap->allocation_audio_urb = 0;
 	}
+	SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap);
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+	SAM("where     0x%08lX=&peasycap->video_device\n", \
+				(unsigned long int) &peasycap->video_device);
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+	SAM("and       0x%08lX=&peasycap->v4l2_device\n", \
+				(unsigned long int) &peasycap->v4l2_device);
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
 /*---------------------------------------------------------------------------*/
 /*
- *  INITIALIZE THE NEW easycap STRUCTURE.
- *  NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS.
- *  THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl().
- */
+ *  PERFORM URGENT INTIALIZATIONS ...
+*/
 /*---------------------------------------------------------------------------*/
-	peasycap->pusb_device = pusb_device;
-	peasycap->pusb_interface = pusb_interface;
-
+	strcpy(&peasycap->telltale[0], TELLTALE);
 	kref_init(&peasycap->kref);
-	JOT(8, "intf[%i]: after kref_init(..._video) " \
+	JOM(8, "intf[%i]: after kref_init(..._video) " \
 			"%i=peasycap->kref.refcount.counter\n", \
 			bInterfaceNumber, peasycap->kref.refcount.counter);
 
-	init_waitqueue_head(&(peasycap->wq_video));
-	init_waitqueue_head(&(peasycap->wq_audio));
+	init_waitqueue_head(&peasycap->wq_video);
+	init_waitqueue_head(&peasycap->wq_audio);
 
-	mutex_init(&(peasycap->mutex_timeval0));
-	mutex_init(&(peasycap->mutex_timeval1));
+	for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) {
+		if (NULL == easycap_dongle[dongle_this].peasycap) {
+			if (0 == mutex_is_locked(&easycap_dongle\
+						[dongle_this].mutex_video)) {
+				if (0 == mutex_is_locked(&easycap_dongle\
+						[dongle_this].mutex_audio)) {
+					easycap_dongle\
+						[dongle_this].peasycap = \
+								peasycap;
+					JOM(8, "intf[%i]: peasycap-->easycap" \
+						"_dongle[%i].peasycap\n", \
+						bInterfaceNumber, dongle_this);
+					break;
+				}
+			}
+		}
+	}
+	if (DONGLE_MANY <= dongle_this) {
+		SAM("ERROR: too many dongles\n");
+		return -ENOMEM;
+	}
 
-	for (k = 0; k < FRAME_BUFFER_MANY; k++)
-		mutex_init(&(peasycap->mutex_mmap_video[k]));
+	peasycap->allocation_video_struct = sizeof(struct easycap);
+	peasycap->allocation_video_page = 0;
+	peasycap->allocation_video_urb = 0;
+	peasycap->allocation_audio_struct = 0;
+	peasycap->allocation_audio_page = 0;
+	peasycap->allocation_audio_urb = 0;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  ... AND FURTHER INITIALIZE THE STRUCTURE
+*/
+/*---------------------------------------------------------------------------*/
+	peasycap->pusb_device = pusb_device;
+	peasycap->pusb_interface = pusb_interface;
 
 	peasycap->ilk = 0;
 	peasycap->microphone = false;
@@ -3177,46 +3645,172 @@
 
 	peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
 
-	if ((struct mutex *)NULL == &(peasycap->mutex_mmap_video[0])) {
-		SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0);
-		return -EFAULT;
-	}
+	for (k = 0; k < INPUT_MANY; k++)
+		peasycap->lost[k] = 0;
+	peasycap->skip = 0;
+	peasycap->skipped = 0;
+	peasycap->offerfields = 0;
 /*---------------------------------------------------------------------------*/
 /*
- *  DYNAMICALLY FILL IN THE AVAILABLE FORMATS.
+ *  DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
  */
 /*---------------------------------------------------------------------------*/
 	rc = fillin_formats();
 	if (0 > rc) {
-		SAY("ERROR: fillin_formats() returned %i\n", rc);
+		SAM("ERROR: fillin_formats() returned %i\n", rc);
 		return -EFAULT;
 	}
-	JOT(4, "%i formats available\n", rc);
-	} else {
+	JOM(4, "%i formats available\n", rc);
 /*---------------------------------------------------------------------------*/
-		if ((struct easycap *)NULL == peasycap) {
-			SAY("ERROR: peasycap is NULL " \
-					"when probing interface %i\n", \
-							bInterfaceNumber);
-			return -EFAULT;
+/*
+ *  ... AND POPULATE easycap.inputset[]
+*/
+/*---------------------------------------------------------------------------*/
+	for (k = 0; k < INPUT_MANY; k++) {
+		peasycap->inputset[k].input_ok = 0;
+		peasycap->inputset[k].standard_offset_ok = 0;
+		peasycap->inputset[k].format_offset_ok = 0;
+		peasycap->inputset[k].brightness_ok = 0;
+		peasycap->inputset[k].contrast_ok = 0;
+		peasycap->inputset[k].saturation_ok = 0;
+		peasycap->inputset[k].hue_ok = 0;
+	}
+	if (true == peasycap->ntsc) {
+		i = 0;
+		m = 0;
+		mask = 0;
+		while (0xFFFF != easycap_standard[i].mask) {
+			if (NTSC_M == easycap_standard[i].\
+							v4l2_standard.index) {
+				m++;
+				for (k = 0; k < INPUT_MANY; k++) {
+					peasycap->inputset[k].\
+							standard_offset = i;
+				}
+			mask = easycap_standard[i].mask;
+			}
+			i++;
 		}
+	} else {
+		i = 0;
+		m = 0;
+		mask = 0;
+		while (0xFFFF != easycap_standard[i].mask) {
+			if (PAL_BGHIN == easycap_standard[i].\
+							v4l2_standard.index) {
+				m++;
+				for (k = 0; k < INPUT_MANY; k++) {
+					peasycap->inputset[k].\
+							standard_offset = i;
+				}
+			mask = easycap_standard[i].mask;
+			}
+			i++;
+		}
+	}
 
-	JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \
-					(int)peasycap->kref.refcount.counter);
-	kref_get(&peasycap->kref);
+	if (1 != m) {
+		SAM("MISTAKE: easycap.inputset[].standard_offset " \
+						"unpopulated, %i=m\n", m);
+		return -ENOENT;
+	}
+
+	peasycap_format = &easycap_format[0];
+	i = 0;
+	m = 0;
+	while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
+		if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \
+				(peasycap_format->\
+					v4l2_format.fmt.pix.field == \
+							V4L2_FIELD_NONE) && \
+				(peasycap_format->\
+					v4l2_format.fmt.pix.pixelformat == \
+							V4L2_PIX_FMT_UYVY) && \
+				(peasycap_format->\
+					v4l2_format.fmt.pix.width  == \
+							640) && \
+				(peasycap_format->\
+					v4l2_format.fmt.pix.height == 480)) {
+			m++;
+			for (k = 0; k < INPUT_MANY; k++)
+				peasycap->inputset[k].format_offset = i;
+			break;
+		}
+	peasycap_format++;
+	i++;
+	}
+	if (1 != m) {
+		SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n");
+	return -ENOENT;
+	}
+
+	i = 0;
+	m = 0;
+	while (0xFFFFFFFF != easycap_control[i].id) {
+		value = easycap_control[i].default_value;
+		if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
+			m++;
+			for (k = 0; k < INPUT_MANY; k++)
+				peasycap->inputset[k].brightness = value;
+		} else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
+			m++;
+			for (k = 0; k < INPUT_MANY; k++)
+				peasycap->inputset[k].contrast = value;
+		} else if (V4L2_CID_SATURATION == easycap_control[i].id) {
+			m++;
+			for (k = 0; k < INPUT_MANY; k++)
+				peasycap->inputset[k].saturation = value;
+		} else if (V4L2_CID_HUE == easycap_control[i].id) {
+			m++;
+			for (k = 0; k < INPUT_MANY; k++)
+				peasycap->inputset[k].hue = value;
+		}
+		i++;
+	}
+	if (4 != m) {
+		SAM("MISTAKE: easycap.inputset[].brightness,... " \
+						"underpopulated\n");
+		return -ENOENT;
+	}
+	for (k = 0; k < INPUT_MANY; k++)
+		peasycap->inputset[k].input = k;
+	JOM(4, "populated easycap.inputset[]\n");
+	JOM(4, "finished initialization\n");
+} else {
+/*---------------------------------------------------------------------------*/
+	/*
+	 *  FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING
+	 *  THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED.  IF
+	 *  THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN
+	 *  SIMULTANEOUSLY, THERE WILL BE SERIOUS TROUBLE.
+	*/
+/*---------------------------------------------------------------------------*/
+	if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) {
+		SAY("ERROR: bad dongle count\n");
+		return -EFAULT;
+	}
+	peasycap = easycap_dongle[dongle_this].peasycap;
+	JOT(8, "intf[%i]: easycap_dongle[%i].peasycap-->peasycap\n", \
+						bInterfaceNumber, dongle_this);
+
+	if ((struct easycap *)NULL == peasycap) {
+		SAY("ERROR: peasycap is NULL when probing interface %i\n", \
+							bInterfaceNumber);
+		return -EFAULT;
+	}
 }
 /*---------------------------------------------------------------------------*/
 if ((USB_CLASS_VIDEO == bInterfaceClass) || \
-	(USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
+		(USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
 	if (-1 == peasycap->video_interface) {
 		peasycap->video_interface = bInterfaceNumber;
-		JOT(4, "setting peasycap->video_interface=%i\n", \
+		JOM(4, "setting peasycap->video_interface=%i\n", \
 						peasycap->video_interface);
 	} else {
 		if (peasycap->video_interface != bInterfaceNumber) {
-			SAY("ERROR: attempting to reset " \
+			SAM("ERROR: attempting to reset " \
 					"peasycap->video_interface\n");
-			SAY("...... continuing with " \
+			SAM("...... continuing with " \
 					"%i=peasycap->video_interface\n", \
 					peasycap->video_interface);
 		}
@@ -3225,13 +3819,13 @@
 						(0x02 == bInterfaceSubClass)) {
 	if (-1 == peasycap->audio_interface) {
 		peasycap->audio_interface = bInterfaceNumber;
-		JOT(4, "setting peasycap->audio_interface=%i\n", \
+		JOM(4, "setting peasycap->audio_interface=%i\n", \
 						 peasycap->audio_interface);
 	} else {
 		if (peasycap->audio_interface != bInterfaceNumber) {
-			SAY("ERROR: attempting to reset " \
+			SAM("ERROR: attempting to reset " \
 					"peasycap->audio_interface\n");
-			SAY("...... continuing with " \
+			SAM("...... continuing with " \
 					"%i=peasycap->audio_interface\n", \
 					peasycap->audio_interface);
 		}
@@ -3244,37 +3838,35 @@
  */
 /*---------------------------------------------------------------------------*/
 isokalt = 0;
-isokepn = 0;
-isokmps = 0;
 
 for (i = 0; i < pusb_interface->num_altsetting; i++) {
 	pusb_host_interface = &(pusb_interface->altsetting[i]);
 	if ((struct usb_host_interface *)NULL == pusb_host_interface) {
-		SAY("ERROR: pusb_host_interface is NULL\n");
+		SAM("ERROR: pusb_host_interface is NULL\n");
 		return -EFAULT;
 	}
 	pusb_interface_descriptor = &(pusb_host_interface->desc);
 	if ((struct usb_interface_descriptor *)NULL == \
 						pusb_interface_descriptor) {
-		SAY("ERROR: pusb_interface_descriptor is NULL\n");
+		SAM("ERROR: pusb_interface_descriptor is NULL\n");
 		return -EFAULT;
 	}
 
-	JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
-	JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
-	JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
-	JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
-	JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
-	JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
-	JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
-	JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
+	JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
 	bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
 
 	ISOCwMaxPacketSize = -1;
@@ -3285,86 +3877,80 @@
 	INTbEndpointAddress = 0;
 
 	if (0 == pusb_interface_descriptor->bNumEndpoints)
-				JOT(4, "intf[%i]alt[%i] has no endpoints\n", \
+				JOM(4, "intf[%i]alt[%i] has no endpoints\n", \
 							bInterfaceNumber, i);
 /*---------------------------------------------------------------------------*/
 	for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
 		pepd = &(pusb_host_interface->endpoint[j].desc);
 		if ((struct usb_endpoint_descriptor *)NULL == pepd) {
-			SAY("ERROR:  pepd is NULL.\n");
-			SAY("...... skipping\n");
+			SAM("ERROR:  pepd is NULL.\n");
+			SAM("...... skipping\n");
 			continue;
 		}
 		wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
 		bEndpointAddress = pepd->bEndpointAddress;
 
-		JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
+		JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
 				bInterfaceNumber, i, j, \
 				pepd->bEndpointAddress);
-		JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
+		JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
 				bInterfaceNumber, i, j, \
 				pepd->bmAttributes);
-		JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
+		JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
 				bInterfaceNumber, i, j, \
 				pepd->wMaxPacketSize);
-		JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
+		JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
 				bInterfaceNumber, i, j, \
 				pepd->bInterval);
 
 		if (pepd->bEndpointAddress & USB_DIR_IN) {
-			JOT(4, "intf[%i]alt[%i]end[%i] is an  IN  endpoint\n",\
+			JOM(4, "intf[%i]alt[%i]end[%i] is an  IN  endpoint\n",\
 						bInterfaceNumber, i, j);
 			isin = 1;
 		} else {
-			JOT(4, "intf[%i]alt[%i]end[%i] is an  OUT endpoint\n",\
+			JOM(4, "intf[%i]alt[%i]end[%i] is an  OUT endpoint\n",\
 						bInterfaceNumber, i, j);
-			SAY("ERROR: OUT endpoint unexpected\n");
-			SAY("...... continuing\n");
+			SAM("ERROR: OUT endpoint unexpected\n");
+			SAM("...... continuing\n");
 			isin = 0;
 		}
 		if ((pepd->bmAttributes & \
 				USB_ENDPOINT_XFERTYPE_MASK) == \
 				USB_ENDPOINT_XFER_ISOC) {
-			JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
+			JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
 						bInterfaceNumber, i, j);
 			if (isin) {
 				switch (bInterfaceClass) {
 				case USB_CLASS_VIDEO:
 				case USB_CLASS_VENDOR_SPEC: {
 					if (!peasycap) {
-						SAY("MISTAKE: " \
+						SAM("MISTAKE: " \
 							"peasycap is NULL\n");
 						return -EFAULT;
 					}
 					if (pepd->wMaxPacketSize) {
 						if (8 > isokalt) {
 							okalt[isokalt] = i;
-							JOT(4,\
+							JOM(4,\
 							"%i=okalt[%i]\n", \
 							okalt[isokalt], \
 							isokalt);
-							isokalt++;
-						}
-						if (8 > isokepn) {
-							okepn[isokepn] = \
+							okepn[isokalt] = \
 							pepd->\
 							bEndpointAddress & \
 							0x0F;
-							JOT(4,\
+							JOM(4,\
 							"%i=okepn[%i]\n", \
-							okepn[isokepn], \
-							isokepn);
-							isokepn++;
-						}
-						if (8 > isokmps) {
-							okmps[isokmps] = \
+							okepn[isokalt], \
+							isokalt);
+							okmps[isokalt] = \
 							le16_to_cpu(pepd->\
 							wMaxPacketSize);
-							JOT(4,\
+							JOM(4,\
 							"%i=okmps[%i]\n", \
-							okmps[isokmps], \
-							isokmps);
-							isokmps++;
+							okmps[isokalt], \
+							isokalt);
+							isokalt++;
 						}
 					} else {
 						if (-1 == peasycap->\
@@ -3372,16 +3958,16 @@
 							peasycap->\
 							video_altsetting_off =\
 									 i;
-							JOT(4, "%i=video_" \
+							JOM(4, "%i=video_" \
 							"altsetting_off " \
 								"<====\n", \
 							peasycap->\
 							video_altsetting_off);
 						} else {
-							SAY("ERROR: peasycap" \
+							SAM("ERROR: peasycap" \
 							"->video_altsetting_" \
 							"off already set\n");
-							SAY("...... " \
+							SAM("...... " \
 							"continuing with " \
 							"%i=peasycap->video_" \
 							"altsetting_off\n", \
@@ -3395,39 +3981,33 @@
 					if (0x02 != bInterfaceSubClass)
 						break;
 					if (!peasycap) {
-						SAY("MISTAKE: " \
+						SAM("MISTAKE: " \
 						"peasycap is NULL\n");
 						return -EFAULT;
 					}
 					if (pepd->wMaxPacketSize) {
 						if (8 > isokalt) {
 							okalt[isokalt] = i ;
-							JOT(4,\
+							JOM(4,\
 							"%i=okalt[%i]\n", \
 							okalt[isokalt], \
 							isokalt);
-							isokalt++;
-						}
-						if (8 > isokepn) {
-							okepn[isokepn] = \
+							okepn[isokalt] = \
 							pepd->\
 							bEndpointAddress & \
 							0x0F;
-							JOT(4,\
+							JOM(4,\
 							"%i=okepn[%i]\n", \
-							okepn[isokepn], \
-							isokepn);
-							isokepn++;
-						}
-						if (8 > isokmps) {
-							okmps[isokmps] = \
+							okepn[isokalt], \
+							isokalt);
+							okmps[isokalt] = \
 							le16_to_cpu(pepd->\
 							wMaxPacketSize);
-							JOT(4,\
+							JOM(4,\
 							"%i=okmps[%i]\n",\
-							okmps[isokmps], \
-							isokmps);
-							isokmps++;
+							okmps[isokalt], \
+							isokalt);
+							isokalt++;
 						}
 					} else {
 						if (-1 == peasycap->\
@@ -3435,16 +4015,16 @@
 							peasycap->\
 							audio_altsetting_off =\
 									 i;
-							JOT(4, "%i=audio_" \
+							JOM(4, "%i=audio_" \
 							"altsetting_off " \
 							"<====\n", \
 							peasycap->\
 							audio_altsetting_off);
 						} else {
-							SAY("ERROR: peasycap" \
+							SAM("ERROR: peasycap" \
 							"->audio_altsetting_" \
 							"off already set\n");
-							SAY("...... " \
+							SAM("...... " \
 							"continuing with " \
 							"%i=peasycap->\
 							audio_altsetting_" \
@@ -3462,19 +4042,19 @@
 		} else if ((pepd->bmAttributes & \
 						USB_ENDPOINT_XFERTYPE_MASK) ==\
 						USB_ENDPOINT_XFER_BULK) {
-			JOT(4, "intf[%i]alt[%i]end[%i] is a  BULK endpoint\n",\
+			JOM(4, "intf[%i]alt[%i]end[%i] is a  BULK endpoint\n",\
 						bInterfaceNumber, i, j);
 		} else if ((pepd->bmAttributes & \
 						USB_ENDPOINT_XFERTYPE_MASK) ==\
 						USB_ENDPOINT_XFER_INT) {
-			JOT(4, "intf[%i]alt[%i]end[%i] is an  INT endpoint\n",\
+			JOM(4, "intf[%i]alt[%i]end[%i] is an  INT endpoint\n",\
 						bInterfaceNumber, i, j);
 		} else {
-			JOT(4, "intf[%i]alt[%i]end[%i] is a  CTRL endpoint\n",\
+			JOM(4, "intf[%i]alt[%i]end[%i] is a  CTRL endpoint\n",\
 						bInterfaceNumber, i, j);
 		}
 		if (0 == pepd->wMaxPacketSize) {
-			JOT(4, "intf[%i]alt[%i]end[%i] " \
+			JOM(4, "intf[%i]alt[%i]end[%i] " \
 						"has zero packet size\n", \
 						bInterfaceNumber, i, j);
 		}
@@ -3485,7 +4065,7 @@
  *  PERFORM INITIALIZATION OF THE PROBED INTERFACE
  */
 /*---------------------------------------------------------------------------*/
-JOT(4, "initialization begins for interface %i\n", \
+JOM(4, "initialization begins for interface %i\n", \
 				pusb_interface_descriptor->bInterfaceNumber);
 switch (bInterfaceNumber) {
 /*---------------------------------------------------------------------------*/
@@ -3495,89 +4075,78 @@
 /*---------------------------------------------------------------------------*/
 case 0: {
 	if (!peasycap) {
-		SAY("MISTAKE: peasycap is NULL\n");
+		SAM("MISTAKE: peasycap is NULL\n");
 		return -EFAULT;
 	}
 	if (!isokalt) {
-		SAY("ERROR:  no viable video_altsetting_on\n");
+		SAM("ERROR:  no viable video_altsetting_on\n");
 		return -ENOENT;
 	} else {
 		peasycap->video_altsetting_on = okalt[isokalt - 1];
-		JOT(4, "%i=video_altsetting_on <====\n", \
+		JOM(4, "%i=video_altsetting_on <====\n", \
 					peasycap->video_altsetting_on);
 	}
-	if (!isokepn) {
-		SAY("ERROR:  no viable video_endpointnumber\n");
-		return -ENOENT;
-	} else {
-		peasycap->video_endpointnumber = okepn[isokepn - 1];
-		JOT(4, "%i=video_endpointnumber\n", \
-					peasycap->video_endpointnumber);
-		}
-	if (!isokmps) {
-		SAY("ERROR:  no viable video_maxpacketsize\n");
-		return -ENOENT;
 /*---------------------------------------------------------------------------*/
 /*
  *  DECIDE THE VIDEO STREAMING PARAMETERS
  */
 /*---------------------------------------------------------------------------*/
+	peasycap->video_endpointnumber = okepn[isokalt - 1];
+	JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber);
+	maxpacketsize = okmps[isokalt - 1];
+	if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
+		peasycap->video_isoc_maxframesize = maxpacketsize;
 	} else {
-		maxpacketsize = okmps[isokmps - 1] - 1024;
-		if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
-			peasycap->video_isoc_maxframesize = maxpacketsize;
-		} else {
-			peasycap->video_isoc_maxframesize = \
-							USB_2_0_MAXPACKETSIZE;
-		}
-		JOT(4, "%i=video_isoc_maxframesize\n", \
-					peasycap->video_isoc_maxframesize);
-		if (0 >= peasycap->video_isoc_maxframesize) {
-			SAY("ERROR:  bad video_isoc_maxframesize\n");
-			return -ENOENT;
-		}
-		peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
-		JOT(4, "%i=video_isoc_framesperdesc\n", \
-					peasycap->video_isoc_framesperdesc);
-		if (0 >= peasycap->video_isoc_framesperdesc) {
-			SAY("ERROR:  bad video_isoc_framesperdesc\n");
-			return -ENOENT;
-		}
-		peasycap->video_isoc_buffer_size = \
-					peasycap->video_isoc_maxframesize * \
-					peasycap->video_isoc_framesperdesc;
-		JOT(4, "%i=video_isoc_buffer_size\n", \
-					peasycap->video_isoc_buffer_size);
-		if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \
-					peasycap->video_isoc_buffer_size) {
-			SAY("MISTAKE: " \
-				"peasycap->video_isoc_buffer_size too big\n");
-			return -EFAULT;
-		}
+		peasycap->video_isoc_maxframesize = \
+						USB_2_0_MAXPACKETSIZE;
+	}
+	JOM(4, "%i=video_isoc_maxframesize\n", \
+				peasycap->video_isoc_maxframesize);
+	if (0 >= peasycap->video_isoc_maxframesize) {
+		SAM("ERROR:  bad video_isoc_maxframesize\n");
+		SAM("        possibly because port is USB 1.1\n");
+		return -ENOENT;
+	}
+	peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
+	JOM(4, "%i=video_isoc_framesperdesc\n", \
+				peasycap->video_isoc_framesperdesc);
+	if (0 >= peasycap->video_isoc_framesperdesc) {
+		SAM("ERROR:  bad video_isoc_framesperdesc\n");
+		return -ENOENT;
+	}
+	peasycap->video_isoc_buffer_size = \
+				peasycap->video_isoc_maxframesize * \
+				peasycap->video_isoc_framesperdesc;
+	JOM(4, "%i=video_isoc_buffer_size\n", \
+				peasycap->video_isoc_buffer_size);
+	if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \
+				peasycap->video_isoc_buffer_size) {
+		SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
+		return -EFAULT;
 	}
 /*---------------------------------------------------------------------------*/
 	if (-1 == peasycap->video_interface) {
-		SAY("MISTAKE:  video_interface is unset\n");
+		SAM("MISTAKE:  video_interface is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->video_altsetting_on) {
-		SAY("MISTAKE:  video_altsetting_on is unset\n");
+		SAM("MISTAKE:  video_altsetting_on is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->video_altsetting_off) {
-		SAY("MISTAKE:  video_interface_off is unset\n");
+		SAM("MISTAKE:  video_interface_off is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->video_endpointnumber) {
-		SAY("MISTAKE:  video_endpointnumber is unset\n");
+		SAM("MISTAKE:  video_endpointnumber is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->video_isoc_maxframesize) {
-		SAY("MISTAKE:  video_isoc_maxframesize is unset\n");
+		SAM("MISTAKE:  video_isoc_maxframesize is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->video_isoc_buffer_size) {
-		SAY("MISTAKE:  video_isoc_buffer_size is unset\n");
+		SAM("MISTAKE:  video_isoc_buffer_size is unset\n");
 		return -EFAULT;
 	}
 /*---------------------------------------------------------------------------*/
@@ -3588,20 +4157,20 @@
 	INIT_LIST_HEAD(&(peasycap->urb_video_head));
 	peasycap->purb_video_head = &(peasycap->urb_video_head);
 /*---------------------------------------------------------------------------*/
-	JOT(4, "allocating %i frame buffers of size %li\n",  \
+	JOM(4, "allocating %i frame buffers of size %li\n",  \
 			FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
-	JOT(4, ".... each scattered over %li pages\n", \
+	JOM(4, ".... each scattered over %li pages\n", \
 						FRAME_BUFFER_SIZE/PAGE_SIZE);
 
 	for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
 		for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
 			if ((void *)NULL != peasycap->frame_buffer[k][m].pgo)
-				SAY("attempting to reallocate frame " \
+				SAM("attempting to reallocate frame " \
 								" buffers\n");
 			else {
 				pbuf = (void *)__get_free_page(GFP_KERNEL);
 				if ((void *)NULL == pbuf) {
-					SAY("ERROR: Could not allocate frame "\
+					SAM("ERROR: Could not allocate frame "\
 						"buffer %i page %i\n", k, m);
 					return -ENOMEM;
 				} else
@@ -3615,23 +4184,23 @@
 
 	peasycap->frame_fill = 0;
 	peasycap->frame_read = 0;
-	JOT(4, "allocation of frame buffers done:  %i pages\n", k * \
+	JOM(4, "allocation of frame buffers done:  %i pages\n", k * \
 								m);
 /*---------------------------------------------------------------------------*/
-	JOT(4, "allocating %i field buffers of size %li\n",  \
+	JOM(4, "allocating %i field buffers of size %li\n",  \
 			FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
-	JOT(4, ".... each scattered over %li pages\n", \
+	JOM(4, ".... each scattered over %li pages\n", \
 					FIELD_BUFFER_SIZE/PAGE_SIZE);
 
 	for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
 		for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
 			if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
-				SAY("ERROR: attempting to reallocate " \
+				SAM("ERROR: attempting to reallocate " \
 							"field buffers\n");
 			} else {
 				pbuf = (void *) __get_free_page(GFP_KERNEL);
 				if ((void *)NULL == pbuf) {
-					SAY("ERROR: Could not allocate field" \
+					SAM("ERROR: Could not allocate field" \
 						" buffer %i page %i\n", k, m);
 					return -ENOMEM;
 					}
@@ -3647,18 +4216,18 @@
 	peasycap->field_fill = 0;
 	peasycap->field_page = 0;
 	peasycap->field_read = 0;
-	JOT(4, "allocation of field buffers done:  %i pages\n", k * \
+	JOM(4, "allocation of field buffers done:  %i pages\n", k * \
 								m);
 /*---------------------------------------------------------------------------*/
-	JOT(4, "allocating %i isoc video buffers of size %i\n",  \
+	JOM(4, "allocating %i isoc video buffers of size %i\n",  \
 					VIDEO_ISOC_BUFFER_MANY, \
 					peasycap->video_isoc_buffer_size);
-	JOT(4, ".... each occupying contiguous memory pages\n");
+	JOM(4, ".... each occupying contiguous memory pages\n");
 
 	for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
 		pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER);
 		if (NULL == pbuf) {
-			SAY("ERROR: Could not allocate isoc video buffer " \
+			SAM("ERROR: Could not allocate isoc video buffer " \
 								"%i\n", k);
 			return -ENOMEM;
 		} else
@@ -3670,26 +4239,26 @@
 					peasycap->video_isoc_buffer_size;
 		peasycap->video_isoc_buffer[k].kount = k;
 	}
-	JOT(4, "allocation of isoc video buffers done: %i pages\n", \
+	JOM(4, "allocation of isoc video buffers done: %i pages\n", \
 					k * (0x01 << VIDEO_ISOC_ORDER));
 /*---------------------------------------------------------------------------*/
 /*
  *  ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
  */
 /*---------------------------------------------------------------------------*/
-	JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
-	JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
+	JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
+	JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
 					peasycap->video_isoc_framesperdesc);
-	JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \
+	JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", \
 					peasycap->video_isoc_maxframesize);
-	JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \
+	JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", \
 					peasycap->video_isoc_buffer_size);
 
 	for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
 		purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \
 								GFP_KERNEL);
 		if (NULL == purb) {
-			SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
+			SAM("ERROR: usb_alloc_urb returned NULL for buffer " \
 								"%i\n", k);
 			return -ENOMEM;
 		} else
@@ -3697,7 +4266,7 @@
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 		pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
 		if (NULL == pdata_urb) {
-			SAY("ERROR: Could not allocate struct data_urb.\n");
+			SAM("ERROR: Could not allocate struct data_urb.\n");
 			return -ENOMEM;
 		} else
 			peasycap->allocation_video_struct += \
@@ -3714,30 +4283,30 @@
  */
 /*---------------------------------------------------------------------------*/
 		if (!k) {
-			JOT(4, "initializing video urbs thus:\n");
-			JOT(4, "  purb->interval = 1;\n");
-			JOT(4, "  purb->dev = peasycap->pusb_device;\n");
-			JOT(4, "  purb->pipe = usb_rcvisocpipe" \
+			JOM(4, "initializing video urbs thus:\n");
+			JOM(4, "  purb->interval = 1;\n");
+			JOM(4, "  purb->dev = peasycap->pusb_device;\n");
+			JOM(4, "  purb->pipe = usb_rcvisocpipe" \
 					"(peasycap->pusb_device,%i);\n", \
 					peasycap->video_endpointnumber);
-			JOT(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
-			JOT(4, "  purb->transfer_buffer = peasycap->" \
+			JOM(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
+			JOM(4, "  purb->transfer_buffer = peasycap->" \
 					"video_isoc_buffer[.].pgo;\n");
-			JOT(4, "  purb->transfer_buffer_length = %i;\n", \
+			JOM(4, "  purb->transfer_buffer_length = %i;\n", \
 					peasycap->video_isoc_buffer_size);
-			JOT(4, "  purb->complete = easycap_complete;\n");
-			JOT(4, "  purb->context = peasycap;\n");
-			JOT(4, "  purb->start_frame = 0;\n");
-			JOT(4, "  purb->number_of_packets = %i;\n", \
+			JOM(4, "  purb->complete = easycap_complete;\n");
+			JOM(4, "  purb->context = peasycap;\n");
+			JOM(4, "  purb->start_frame = 0;\n");
+			JOM(4, "  purb->number_of_packets = %i;\n", \
 					peasycap->video_isoc_framesperdesc);
-			JOT(4, "  for (j = 0; j < %i; j++)\n", \
+			JOM(4, "  for (j = 0; j < %i; j++)\n", \
 					peasycap->video_isoc_framesperdesc);
-			JOT(4, "    {\n");
-			JOT(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
+			JOM(4, "    {\n");
+			JOM(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
 					peasycap->video_isoc_maxframesize);
-			JOT(4, "    purb->iso_frame_desc[j].length = %i;\n", \
+			JOM(4, "    purb->iso_frame_desc[j].length = %i;\n", \
 					peasycap->video_isoc_maxframesize);
-			JOT(4, "    }\n");
+			JOM(4, "    }\n");
 		}
 
 		purb->interval = 1;
@@ -3759,13 +4328,33 @@
 					peasycap->video_isoc_maxframesize;
 		}
 	}
-	JOT(4, "allocation of %i struct urb done.\n", k);
+	JOM(4, "allocation of %i struct urb done.\n", k);
 /*--------------------------------------------------------------------------*/
 /*
  *  SAVE POINTER peasycap IN THIS INTERFACE.
  */
 /*--------------------------------------------------------------------------*/
 	usb_set_intfdata(pusb_interface, peasycap);
+/*---------------------------------------------------------------------------*/
+/*
+ *  IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
+ *  THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE
+ *  CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH.
+ *  BEWARE.
+*/
+/*---------------------------------------------------------------------------*/
+#if defined(PREFER_NTSC)
+	peasycap->ntsc = true;
+	JOM(8, "defaulting initially to NTSC\n");
+#else
+	peasycap->ntsc = false;
+	JOM(8, "defaulting initially to PAL\n");
+#endif /*PREFER_NTSC*/
+	rc = reset(peasycap);
+	if (0 != rc) {
+		SAM("ERROR: reset() returned %i\n", rc);
+		return -EFAULT;
+	}
 /*--------------------------------------------------------------------------*/
 /*
  *  THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
@@ -3776,48 +4365,58 @@
 		err("Not able to get a minor for this device");
 		usb_set_intfdata(pusb_interface, NULL);
 		return -ENODEV;
-	} else
+	} else {
 		(peasycap->registered_video)++;
-	SAY("easycap attached to minor #%d\n", pusb_interface->minor);
-	break;
-/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
-#else
-	pvideo_device = (struct video_device *)\
-			kzalloc(sizeof(struct video_device), GFP_KERNEL);
-	if ((struct video_device *)NULL == pvideo_device) {
-		SAY("ERROR: Could not allocate structure video_device\n");
-		return -ENOMEM;
+		SAM("easycap attached to minor #%d\n", pusb_interface->minor);
+		break;
 	}
-	if (VIDEO_DEVICE_MANY <= video_device_many) {
-		SAY("ERROR: Too many /dev/videos\n");
-		return -ENOMEM;
-	}
-	pvideo_array[video_device_many] = pvideo_device;  video_device_many++;
-
-	strcpy(&pvideo_device->name[0], "easycapdc60");
-#if defined(EASYCAP_NEEDS_V4L2_FOPS)
-	pvideo_device->fops = &v4l2_fops;
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #else
-	pvideo_device->fops = &easycap_fops;
-#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
-	pvideo_device->minor = -1;
-	pvideo_device->release = (void *)(&videodev_release);
-
-	video_set_drvdata(pvideo_device, (void *)peasycap);
-
-	rc = video_register_device(pvideo_device, VFL_TYPE_GRABBER, -1);
-	if (0 != rc) {
-		err("Not able to register with videodev");
-		videodev_release(pvideo_device);
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+	if (0 != (v4l2_device_register(&(pusb_interface->dev), \
+						&(peasycap->v4l2_device)))) {
+		SAM("v4l2_device_register() failed\n");
 		return -ENODEV;
 	} else {
-		peasycap->pvideo_device = pvideo_device;
-		(peasycap->registered_video)++;
-		JOT(4, "registered with videodev: %i=minor\n", \
-							pvideo_device->minor);
+		JOM(4, "registered device instance: %s\n", \
+					&(peasycap->v4l2_device.name[0]));
 	}
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*---------------------------------------------------------------------------*/
+/*
+ *                                   FIXME
+ *
+ *
+ *  THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
+*/
+/*---------------------------------------------------------------------------*/
+	peasycap->video_device.v4l2_dev = (struct v4l2_device *)NULL;
+/*---------------------------------------------------------------------------*/
+
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+
+	strcpy(&peasycap->video_device.name[0], "easycapdc60");
+#if defined(EASYCAP_NEEDS_V4L2_FOPS)
+	peasycap->video_device.fops = &v4l2_fops;
+#else
+	peasycap->video_device.fops = &easycap_fops;
+#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
+	peasycap->video_device.minor = -1;
+	peasycap->video_device.release = (void *)(&videodev_release);
+
+	video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
+
+	if (0 != (video_register_device(&(peasycap->video_device), \
+						VFL_TYPE_GRABBER, -1))) {
+		err("Not able to register with videodev");
+		videodev_release(&(peasycap->video_device));
+		return -ENODEV;
+	} else {
+		(peasycap->registered_video)++;
+		SAM("registered with videodev: %i=minor\n", \
+						peasycap->video_device.minor);
+	}
 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
 	break;
 }
 /*--------------------------------------------------------------------------*/
@@ -3827,125 +4426,118 @@
  */
 /*--------------------------------------------------------------------------*/
 case 1: {
+	if (!peasycap) {
+		SAM("ERROR: peasycap is NULL\n");
+		return -EFAULT;
+	}
 /*--------------------------------------------------------------------------*/
 /*
  *  SAVE POINTER peasycap IN INTERFACE 1
  */
 /*--------------------------------------------------------------------------*/
 	usb_set_intfdata(pusb_interface, peasycap);
-	JOT(4, "no initialization required for interface %i\n", \
+	JOM(4, "no initialization required for interface %i\n", \
 				pusb_interface_descriptor->bInterfaceNumber);
 	break;
 }
 /*--------------------------------------------------------------------------*/
 case 2: {
 	if (!peasycap) {
-		SAY("MISTAKE: peasycap is NULL\n");
+		SAM("MISTAKE: peasycap is NULL\n");
 		return -EFAULT;
 	}
 	if (!isokalt) {
-		SAY("ERROR:  no viable audio_altsetting_on\n");
+		SAM("ERROR:  no viable audio_altsetting_on\n");
 		return -ENOENT;
 	} else {
 		peasycap->audio_altsetting_on = okalt[isokalt - 1];
-		JOT(4, "%i=audio_altsetting_on <====\n", \
+		JOM(4, "%i=audio_altsetting_on <====\n", \
 						peasycap->audio_altsetting_on);
 	}
-	if (!isokepn) {
-		SAY("ERROR:  no viable audio_endpointnumber\n");
-		return -ENOENT;
-	} else {
-		peasycap->audio_endpointnumber = okepn[isokepn - 1];
-		JOT(4, "%i=audio_endpointnumber\n", \
-					peasycap->audio_endpointnumber);
-	}
-	if (!isokmps) {
-		SAY("ERROR:  no viable audio_maxpacketsize\n");
-		return -ENOENT;
-	} else {
-		peasycap->audio_isoc_maxframesize = okmps[isokmps - 1];
-		JOT(4, "%i=audio_isoc_maxframesize\n", \
-					peasycap->audio_isoc_maxframesize);
-		if (0 >= peasycap->audio_isoc_maxframesize) {
-			SAY("ERROR:  bad audio_isoc_maxframesize\n");
-			return -ENOENT;
-		}
-		if (9 == peasycap->audio_isoc_maxframesize) {
-			peasycap->ilk |= 0x02;
-			SAY("hardware is FOUR-CVBS\n");
-			peasycap->microphone = true;
-			peasycap->audio_pages_per_fragment = 4;
-		} else if (256 == peasycap->audio_isoc_maxframesize) {
-			peasycap->ilk &= ~0x02;
-			SAY("hardware is CVBS+S-VIDEO\n");
-			peasycap->microphone = false;
-			peasycap->audio_pages_per_fragment = 4;
-		} else {
-			SAY("hardware is unidentified:\n");
-			SAY("%i=audio_isoc_maxframesize\n", \
-					peasycap->audio_isoc_maxframesize);
-			return -ENOENT;
-		}
 
-		peasycap->audio_bytes_per_fragment = \
+	peasycap->audio_endpointnumber = okepn[isokalt - 1];
+	JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber);
+
+	peasycap->audio_isoc_maxframesize = okmps[isokalt - 1];
+	JOM(4, "%i=audio_isoc_maxframesize\n", \
+					peasycap->audio_isoc_maxframesize);
+	if (0 >= peasycap->audio_isoc_maxframesize) {
+		SAM("ERROR:  bad audio_isoc_maxframesize\n");
+		return -ENOENT;
+	}
+	if (9 == peasycap->audio_isoc_maxframesize) {
+		peasycap->ilk |= 0x02;
+		SAM("hardware is FOUR-CVBS\n");
+		peasycap->microphone = true;
+		peasycap->audio_pages_per_fragment = 4;
+	} else if (256 == peasycap->audio_isoc_maxframesize) {
+		peasycap->ilk &= ~0x02;
+		SAM("hardware is CVBS+S-VIDEO\n");
+		peasycap->microphone = false;
+		peasycap->audio_pages_per_fragment = 4;
+	} else {
+		SAM("hardware is unidentified:\n");
+		SAM("%i=audio_isoc_maxframesize\n", \
+					peasycap->audio_isoc_maxframesize);
+		return -ENOENT;
+	}
+
+	peasycap->audio_bytes_per_fragment = \
 					peasycap->audio_pages_per_fragment * \
 								PAGE_SIZE ;
-		peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \
+	peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \
 					peasycap->audio_pages_per_fragment);
 
-		JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
-		JOT(4, "%6i=audio_pages_per_fragment\n", \
+	JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
+	JOM(4, "%6i=audio_pages_per_fragment\n", \
 					peasycap->audio_pages_per_fragment);
-		JOT(4, "%6i=audio_bytes_per_fragment\n", \
+	JOM(4, "%6i=audio_bytes_per_fragment\n", \
 					peasycap->audio_bytes_per_fragment);
-		JOT(4, "%6i=audio_buffer_page_many\n", \
+	JOM(4, "%6i=audio_buffer_page_many\n", \
 					peasycap->audio_buffer_page_many);
 
-		peasycap->audio_isoc_framesperdesc = 128;
+	peasycap->audio_isoc_framesperdesc = 128;
 
-		JOT(4, "%i=audio_isoc_framesperdesc\n", \
+	JOM(4, "%i=audio_isoc_framesperdesc\n", \
 					peasycap->audio_isoc_framesperdesc);
-		if (0 >= peasycap->audio_isoc_framesperdesc) {
-			SAY("ERROR:  bad audio_isoc_framesperdesc\n");
-			return -ENOENT;
-		}
-
-		peasycap->audio_isoc_buffer_size = \
-				peasycap->audio_isoc_maxframesize * \
-				peasycap->audio_isoc_framesperdesc;
-		JOT(4, "%i=audio_isoc_buffer_size\n", \
-					peasycap->audio_isoc_buffer_size);
-		if (AUDIO_ISOC_BUFFER_SIZE < \
-					peasycap->audio_isoc_buffer_size) {
-			SAY("MISTAKE:  audio_isoc_buffer_size bigger "
-			"than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
-						AUDIO_ISOC_BUFFER_SIZE);
-			return -EFAULT;
-		}
+	if (0 >= peasycap->audio_isoc_framesperdesc) {
+		SAM("ERROR:  bad audio_isoc_framesperdesc\n");
+		return -ENOENT;
 	}
 
+	peasycap->audio_isoc_buffer_size = \
+				peasycap->audio_isoc_maxframesize * \
+				peasycap->audio_isoc_framesperdesc;
+	JOM(4, "%i=audio_isoc_buffer_size\n", \
+					peasycap->audio_isoc_buffer_size);
+	if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) {
+			SAM("MISTAKE:  audio_isoc_buffer_size bigger "
+			"than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
+						AUDIO_ISOC_BUFFER_SIZE);
+		return -EFAULT;
+	}
 	if (-1 == peasycap->audio_interface) {
-		SAY("MISTAKE:  audio_interface is unset\n");
+		SAM("MISTAKE:  audio_interface is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->audio_altsetting_on) {
-		SAY("MISTAKE:  audio_altsetting_on is unset\n");
+		SAM("MISTAKE:  audio_altsetting_on is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->audio_altsetting_off) {
-		SAY("MISTAKE:  audio_interface_off is unset\n");
+		SAM("MISTAKE:  audio_interface_off is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->audio_endpointnumber) {
-		SAY("MISTAKE:  audio_endpointnumber is unset\n");
+		SAM("MISTAKE:  audio_endpointnumber is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->audio_isoc_maxframesize) {
-		SAY("MISTAKE:  audio_isoc_maxframesize is unset\n");
+		SAM("MISTAKE:  audio_isoc_maxframesize is unset\n");
 		return -EFAULT;
 	}
 	if (-1 == peasycap->audio_isoc_buffer_size) {
-		SAY("MISTAKE:  audio_isoc_buffer_size is unset\n");
+		SAM("MISTAKE:  audio_isoc_buffer_size is unset\n");
 		return -EFAULT;
 	}
 /*---------------------------------------------------------------------------*/
@@ -3956,17 +4548,17 @@
 	INIT_LIST_HEAD(&(peasycap->urb_audio_head));
 	peasycap->purb_audio_head = &(peasycap->urb_audio_head);
 
-	JOT(4, "allocating an audio buffer\n");
-	JOT(4, ".... scattered over %i pages\n", \
+	JOM(4, "allocating an audio buffer\n");
+	JOM(4, ".... scattered over %i pages\n", \
 					peasycap->audio_buffer_page_many);
 
 	for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
 		if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
-			SAY("ERROR: attempting to reallocate audio buffers\n");
+			SAM("ERROR: attempting to reallocate audio buffers\n");
 		} else {
 			pbuf = (void *) __get_free_page(GFP_KERNEL);
 			if ((void *)NULL == pbuf) {
-				SAY("ERROR: Could not allocate audio " \
+				SAM("ERROR: Could not allocate audio " \
 							"buffer page %i\n", k);
 				return -ENOMEM;
 			} else
@@ -3979,16 +4571,16 @@
 
 	peasycap->audio_fill = 0;
 	peasycap->audio_read = 0;
-	JOT(4, "allocation of audio buffer done:  %i pages\n", k);
+	JOM(4, "allocation of audio buffer done:  %i pages\n", k);
 /*---------------------------------------------------------------------------*/
-	JOT(4, "allocating %i isoc audio buffers of size %i\n",  \
+	JOM(4, "allocating %i isoc audio buffers of size %i\n",  \
 		AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
-	JOT(4, ".... each occupying contiguous memory pages\n");
+	JOM(4, ".... each occupying contiguous memory pages\n");
 
 	for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
 		pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
 		if (NULL == pbuf) {
-			SAY("ERROR: Could not allocate isoc audio buffer " \
+			SAM("ERROR: Could not allocate isoc audio buffer " \
 							"%i\n", k);
 			return -ENOMEM;
 		} else
@@ -4000,25 +4592,25 @@
 		peasycap->audio_isoc_buffer_size;
 		peasycap->audio_isoc_buffer[k].kount = k;
 	}
-	JOT(4, "allocation of isoc audio buffers done.\n");
+	JOM(4, "allocation of isoc audio buffers done.\n");
 /*---------------------------------------------------------------------------*/
 /*
  *  ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
  */
 /*---------------------------------------------------------------------------*/
-	JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
-	JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
+	JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
+	JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
 					peasycap->audio_isoc_framesperdesc);
-	JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
+	JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
 					peasycap->audio_isoc_maxframesize);
-	JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
+	JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
 					peasycap->audio_isoc_buffer_size);
 
 	for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY; k++) {
 		purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \
 								GFP_KERNEL);
 		if (NULL == purb) {
-			SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
+			SAM("ERROR: usb_alloc_urb returned NULL for buffer " \
 							"%i\n", k);
 			return -ENOMEM;
 		} else
@@ -4026,7 +4618,7 @@
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 		pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
 		if (NULL == pdata_urb) {
-			SAY("ERROR: Could not allocate struct data_urb.\n");
+			SAM("ERROR: Could not allocate struct data_urb.\n");
 			return -ENOMEM;
 		} else
 			peasycap->allocation_audio_struct += \
@@ -4043,30 +4635,30 @@
  */
 /*---------------------------------------------------------------------------*/
 		if (!k) {
-			JOT(4, "initializing audio urbs thus:\n");
-			JOT(4, "  purb->interval = 1;\n");
-			JOT(4, "  purb->dev = peasycap->pusb_device;\n");
-			JOT(4, "  purb->pipe = usb_rcvisocpipe(peasycap->" \
+			JOM(4, "initializing audio urbs thus:\n");
+			JOM(4, "  purb->interval = 1;\n");
+			JOM(4, "  purb->dev = peasycap->pusb_device;\n");
+			JOM(4, "  purb->pipe = usb_rcvisocpipe(peasycap->" \
 					"pusb_device,%i);\n", \
 					peasycap->audio_endpointnumber);
-			JOT(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
-			JOT(4, "  purb->transfer_buffer = " \
+			JOM(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
+			JOM(4, "  purb->transfer_buffer = " \
 				"peasycap->audio_isoc_buffer[.].pgo;\n");
-			JOT(4, "  purb->transfer_buffer_length = %i;\n", \
+			JOM(4, "  purb->transfer_buffer_length = %i;\n", \
 					peasycap->audio_isoc_buffer_size);
-			JOT(4, "  purb->complete = easysnd_complete;\n");
-			JOT(4, "  purb->context = peasycap;\n");
-			JOT(4, "  purb->start_frame = 0;\n");
-			JOT(4, "  purb->number_of_packets = %i;\n", \
+			JOM(4, "  purb->complete = easysnd_complete;\n");
+			JOM(4, "  purb->context = peasycap;\n");
+			JOM(4, "  purb->start_frame = 0;\n");
+			JOM(4, "  purb->number_of_packets = %i;\n", \
 					peasycap->audio_isoc_framesperdesc);
-			JOT(4, "  for (j = 0; j < %i; j++)\n", \
+			JOM(4, "  for (j = 0; j < %i; j++)\n", \
 					peasycap->audio_isoc_framesperdesc);
-			JOT(4, "    {\n");
-			JOT(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
+			JOM(4, "    {\n");
+			JOM(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
 					peasycap->audio_isoc_maxframesize);
-			JOT(4, "    purb->iso_frame_desc[j].length = %i;\n", \
+			JOM(4, "    purb->iso_frame_desc[j].length = %i;\n", \
 					peasycap->audio_isoc_maxframesize);
-			JOT(4, "    }\n");
+			JOM(4, "    }\n");
 			}
 
 		purb->interval = 1;
@@ -4088,7 +4680,7 @@
 					peasycap->audio_isoc_maxframesize;
 		}
 	}
-	JOT(4, "allocation of %i struct urb done.\n", k);
+	JOM(4, "allocation of %i struct urb done.\n", k);
 /*---------------------------------------------------------------------------*/
 /*
  *  SAVE POINTER peasycap IN THIS INTERFACE.
@@ -4105,14 +4697,18 @@
 		err("Not able to get a minor for this device.");
 		usb_set_intfdata(pusb_interface, NULL);
 		return -ENODEV;
-	} else
+	} else {
+		JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\
+					(int)peasycap->kref.refcount.counter);
+		kref_get(&peasycap->kref);
 		(peasycap->registered_audio)++;
+	}
 /*---------------------------------------------------------------------------*/
 /*
  *  LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
  */
 /*---------------------------------------------------------------------------*/
-	SAY("easysnd attached to minor #%d\n", pusb_interface->minor);
+	SAM("easysnd attached to minor #%d\n", pusb_interface->minor);
 	break;
 }
 /*---------------------------------------------------------------------------*/
@@ -4121,20 +4717,19 @@
  */
 /*---------------------------------------------------------------------------*/
 default: {
-	JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
+	JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
 	return -EINVAL;
 }
 }
-JOT(4, "ends successfully for interface %i\n", \
+JOM(4, "ends successfully for interface %i\n", \
 				pusb_interface_descriptor->bInterfaceNumber);
 return 0;
 }
 /*****************************************************************************/
 /*---------------------------------------------------------------------------*/
 /*
- *  WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
- *  UNPLUGGED.
- *  HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
+ *  WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
+ *  UNPLUGGED.  HENCE peasycap->pusb_device IS NO LONGER VALID.
  */
 /*---------------------------------------------------------------------------*/
 void
@@ -4147,7 +4742,14 @@
 
 struct list_head *plist_head;
 struct data_urb *pdata_urb;
-int minor, m;
+int minor, m, kd;
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+struct v4l2_device *pv4l2_device;
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
 
 JOT(4, "\n");
 
@@ -4169,107 +4771,188 @@
 minor = pusb_interface->minor;
 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
 
+if (1 == bInterfaceNumber)
+	return;
+
 peasycap = usb_get_intfdata(pusb_interface);
-if ((struct easycap *)NULL == peasycap)
+if (NULL == peasycap) {
 	SAY("ERROR: peasycap is NULL\n");
-else {
-	peasycap->pusb_device = (struct usb_device *)NULL;
-	switch (bInterfaceNumber) {
+	return;
+}
 /*---------------------------------------------------------------------------*/
-	case 0: {
-		if ((struct list_head *)NULL != peasycap->purb_video_head) {
-			JOT(4, "killing video urbs\n");
-			m = 0;
-			list_for_each(plist_head, (peasycap->purb_video_head))
-				{
-				pdata_urb = list_entry(plist_head, \
-						struct data_urb, list_head);
-				if ((struct data_urb *)NULL != pdata_urb) {
-					if ((struct urb *)NULL != \
-							pdata_urb->purb) {
-						usb_kill_urb(pdata_urb->purb);
-						m++;
-					}
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+#
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+/*---------------------------------------------------------------------------*/
+/*
+ *  SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
+ *  BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
+ *  REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
+ *  TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
+*/
+/*---------------------------------------------------------------------------*/
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	pv4l2_device = usb_get_intfdata(pusb_interface);
+	if ((struct v4l2_device *)NULL == pv4l2_device) {
+		SAY("ERROR: pv4l2_device is NULL\n");
+		return;
+	}
+	peasycap = (struct easycap *) \
+		container_of(pv4l2_device, struct easycap, v4l2_device);
+}
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*---------------------------------------------------------------------------*/
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE.  BEWARE.
+*/
+/*---------------------------------------------------------------------------*/
+peasycap->video_eof = 1;
+peasycap->audio_eof = 1;
+wake_up_interruptible(&(peasycap->wq_video));
+wake_up_interruptible(&(peasycap->wq_audio));
+/*---------------------------------------------------------------------------*/
+switch (bInterfaceNumber) {
+case 0: {
+	if ((struct list_head *)NULL != peasycap->purb_video_head) {
+		JOM(4, "killing video urbs\n");
+		m = 0;
+		list_for_each(plist_head, (peasycap->purb_video_head))
+			{
+			pdata_urb = list_entry(plist_head, \
+					struct data_urb, list_head);
+			if ((struct data_urb *)NULL != pdata_urb) {
+				if ((struct urb *)NULL != \
+						pdata_urb->purb) {
+					usb_kill_urb(pdata_urb->purb);
+					m++;
 				}
 			}
-			JOT(4, "%i video urbs killed\n", m);
-		} else
-			SAY("ERROR: peasycap->purb_video_head is NULL\n");
-		break;
+		}
+		JOM(4, "%i video urbs killed\n", m);
 	}
+	break;
+}
 /*---------------------------------------------------------------------------*/
-	case 2: {
-		if ((struct list_head *)NULL != peasycap->purb_audio_head) {
-			JOT(4, "killing audio urbs\n");
-			m = 0;
-			list_for_each(plist_head, \
-						(peasycap->purb_audio_head)) {
-				pdata_urb = list_entry(plist_head, \
-						struct data_urb, list_head);
-				if ((struct data_urb *)NULL != pdata_urb) {
-					if ((struct urb *)NULL != \
-							pdata_urb->purb) {
-						usb_kill_urb(pdata_urb->purb);
-						m++;
-					}
+case 2: {
+	if ((struct list_head *)NULL != peasycap->purb_audio_head) {
+		JOM(4, "killing audio urbs\n");
+		m = 0;
+		list_for_each(plist_head, \
+					(peasycap->purb_audio_head)) {
+			pdata_urb = list_entry(plist_head, \
+					struct data_urb, list_head);
+			if ((struct data_urb *)NULL != pdata_urb) {
+				if ((struct urb *)NULL != \
+						pdata_urb->purb) {
+					usb_kill_urb(pdata_urb->purb);
+					m++;
 				}
 			}
-			JOT(4, "%i audio urbs killed\n", m);
-		} else
-			SAY("ERROR: peasycap->purb_audio_head is NULL\n");
-		break;
+		}
+		JOM(4, "%i audio urbs killed\n", m);
 	}
+	break;
+}
 /*---------------------------------------------------------------------------*/
-	default:
-		break;
-	}
+default:
+	break;
 }
 /*--------------------------------------------------------------------------*/
 /*
  *  DEREGISTER
+ *
+ *  THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO
+ *  IOCTL ARE ALL UNLOCKED.  IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN
+ *  AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING.  BEWARE.
  */
 /*--------------------------------------------------------------------------*/
+kd = isdongle(peasycap);
 switch (bInterfaceNumber) {
 case 0: {
+	if (0 <= kd && DONGLE_MANY > kd) {
+		wake_up_interruptible(&peasycap->wq_video);
+		JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd);
+		if (mutex_lock_interruptible(&easycap_dongle[kd].\
+								mutex_video)) {
+			SAY("ERROR: cannot lock easycap_dongle[%i]." \
+							"mutex_video\n", kd);
+			return;
+		}
+		JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
+	} else
+		SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
+/*---------------------------------------------------------------------------*/
 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
 	if ((struct easycap *)NULL == peasycap) {
-		SAY("ERROR: peasycap has become NULL\n");
+		SAM("ERROR: peasycap has become NULL\n");
 	} else {
-		lock_kernel();
 		usb_deregister_dev(pusb_interface, &easycap_class);
 		(peasycap->registered_video)--;
-
-		JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
-		unlock_kernel();
-		SAY("easycap detached from minor #%d\n", minor);
+		JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
+		SAM("easycap detached from minor #%d\n", minor);
 	}
-/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #else
-	if ((struct easycap *)NULL == peasycap)
-		SAY("ERROR: peasycap has become NULL\n");
-	else {
-		lock_kernel();
-		video_unregister_device(peasycap->pvideo_device);
-		(peasycap->registered_video)--;
-		unlock_kernel();
-		JOT(4, "unregistered with videodev: %i=minor\n", \
-							pvideo_device->minor);
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+	if (!peasycap->v4l2_device.name[0]) {
+		SAM("ERROR: peasycap->v4l2_device.name is empty\n");
+		if (0 <= kd && DONGLE_MANY > kd)
+			mutex_unlock(&easycap_dongle[kd].mutex_video);
+		return;
 	}
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+	v4l2_device_disconnect(&peasycap->v4l2_device);
+	JOM(4, "v4l2_device_disconnect() OK\n");
+	v4l2_device_unregister(&peasycap->v4l2_device);
+	JOM(4, "v4l2_device_unregister() OK\n");
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+
+	video_unregister_device(&peasycap->video_device);
+	JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber);
+	(peasycap->registered_video)--;
+	JOM(4, "unregistered with videodev: %i=minor\n", minor);
 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+	if (0 <= kd && DONGLE_MANY > kd) {
+		mutex_unlock(&easycap_dongle[kd].mutex_video);
+		JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
+	}
 	break;
 }
 case 2: {
-	lock_kernel();
+	if (0 <= kd && DONGLE_MANY > kd) {
+		wake_up_interruptible(&peasycap->wq_audio);
+		JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd);
+		if (mutex_lock_interruptible(&easycap_dongle[kd].\
+								mutex_audio)) {
+			SAY("ERROR: cannot lock easycap_dongle[%i]." \
+							"mutex_audio\n", kd);
+			return;
+		}
+		JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
+	} else
+		SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
 
 	usb_deregister_dev(pusb_interface, &easysnd_class);
-	if ((struct easycap *)NULL != peasycap)
-		(peasycap->registered_audio)--;
+	(peasycap->registered_audio)--;
 
-	JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
-	unlock_kernel();
+	JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
+	SAM("easysnd detached from minor #%d\n", minor);
 
-	SAY("easysnd detached from minor #%d\n", minor);
+	if (0 <= kd && DONGLE_MANY > kd) {
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		JOM(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd);
+	}
 	break;
 }
 default:
@@ -4280,25 +4963,42 @@
  *  CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
  */
 /*---------------------------------------------------------------------------*/
-if ((struct easycap *)NULL == peasycap) {
-	SAY("ERROR: peasycap has become NULL\n");
-	SAY("cannot call kref_put()\n");
-	SAY("ending unsuccessfully: may cause memory leak\n");
-	return;
-}
 if (!peasycap->kref.refcount.counter) {
-	SAY("ERROR: peasycap->kref.refcount.counter is zero " \
+	SAM("ERROR: peasycap->kref.refcount.counter is zero "
 						"so cannot call kref_put()\n");
-	SAY("ending unsuccessfully: may cause memory leak\n");
+	SAM("ending unsuccessfully: may cause memory leak\n");
 	return;
 }
-JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
+if (0 <= kd && DONGLE_MANY > kd) {
+	JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd);
+	if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
+		SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd);
+		SAM("ending unsuccessfully: may cause memory leak\n");
+	return;
+	}
+	JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
+	JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd);
+	if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) {
+		SAY("ERROR: cannot down easycap_dongle[%i].mutex_audio\n", kd);
+		mutex_unlock(&(easycap_dongle[kd].mutex_video));
+		JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
+		SAM("ending unsuccessfully: may cause memory leak\n");
+		return;
+	}
+	JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
+}
+JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", \
 		bInterfaceNumber, (int)peasycap->kref.refcount.counter);
 kref_put(&peasycap->kref, easycap_delete);
 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
+if (0 <= kd && DONGLE_MANY > kd) {
+	mutex_unlock(&(easycap_dongle[kd].mutex_audio));
+	JOT(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd);
+	mutex_unlock(&easycap_dongle[kd].mutex_video);
+	JOT(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
+}
 /*---------------------------------------------------------------------------*/
-
-JOT(4, "ends\n");
+JOM(4, "ends\n");
 return;
 }
 /*****************************************************************************/
@@ -4308,7 +5008,8 @@
 int result;
 
 SAY("========easycap=======\n");
-JOT(4, "begins.  %i=debug\n", easycap_debug);
+JOT(4, "begins.  %i=debug %i=bars %i=gain\n", debug, bars, \
+						gain);
 SAY("version: " EASYCAP_DRIVER_VERSION "\n");
 /*---------------------------------------------------------------------------*/
 /*
@@ -4349,6 +5050,9 @@
 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
 MODULE_VERSION(EASYCAP_DRIVER_VERSION);
 #if defined(EASYCAP_DEBUG)
-MODULE_PARM_DESC(easycap_debug, "debug: 0 (default), 1, 2,...");
+MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9");
 #endif /*EASYCAP_DEBUG*/
+MODULE_PARM_DESC(bars, \
+	"Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
+MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31");
 /*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c
index 38d9405..df3f17d 100644
--- a/drivers/staging/easycap/easycap_settings.c
+++ b/drivers/staging/easycap/easycap_settings.c
@@ -33,11 +33,15 @@
  *  THE LEAST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
  *                         0 => 25 fps
  *                         1 => 30 fps
+ *
+ *  THE MOST  SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
+ *                         0 => full framerate
+ *                         1 => 20%  framerate
  */
 /*---------------------------------------------------------------------------*/
 const struct easycap_standard easycap_standard[] = {
 {
-.mask = 0x000F & PAL_BGHIN ,
+.mask = 0x00FF & PAL_BGHIN ,
 .v4l2_standard = {
 	.index = PAL_BGHIN,
 	.id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
@@ -50,7 +54,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & NTSC_N_443 ,
+.mask = 0x00FF & NTSC_N_443 ,
 .v4l2_standard = {
 	.index = NTSC_N_443,
 	.id = V4L2_STD_UNKNOWN,
@@ -62,7 +66,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & PAL_Nc ,
+.mask = 0x00FF & PAL_Nc ,
 .v4l2_standard = {
 	.index = PAL_Nc,
 	.id = V4L2_STD_PAL_Nc,
@@ -74,7 +78,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & NTSC_N ,
+.mask = 0x00FF & NTSC_N ,
 .v4l2_standard = {
 	.index = NTSC_N,
 	.id = V4L2_STD_UNKNOWN,
@@ -86,7 +90,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & SECAM ,
+.mask = 0x00FF & SECAM ,
 .v4l2_standard = {
 	.index = SECAM,
 	.id = V4L2_STD_SECAM,
@@ -98,7 +102,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & NTSC_M ,
+.mask = 0x00FF & NTSC_M ,
 .v4l2_standard = {
 	.index = NTSC_M,
 	.id = V4L2_STD_NTSC_M,
@@ -110,7 +114,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & NTSC_M_JP ,
+.mask = 0x00FF & NTSC_M_JP ,
 .v4l2_standard = {
 	.index = NTSC_M_JP,
 	.id = V4L2_STD_NTSC_M_JP,
@@ -122,7 +126,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & PAL_60 ,
+.mask = 0x00FF & PAL_60 ,
 .v4l2_standard = {
 	.index = PAL_60,
 	.id = V4L2_STD_PAL_60,
@@ -134,7 +138,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & NTSC_443 ,
+.mask = 0x00FF & NTSC_443 ,
 .v4l2_standard = {
 	.index = NTSC_443,
 	.id = V4L2_STD_NTSC_443,
@@ -146,7 +150,7 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
-.mask = 0x000F & PAL_M ,
+.mask = 0x00FF & PAL_M ,
 .v4l2_standard = {
 	.index = PAL_M,
 	.id = V4L2_STD_PAL_M,
@@ -158,6 +162,128 @@
 },
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 {
+.mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW),
+.v4l2_standard = {
+	.index = PAL_BGHIN_SLOW,
+	.id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
+				V4L2_STD_PAL_I | V4L2_STD_PAL_N | \
+					(((v4l2_std_id)0x01) << 32)),
+	.name = "PAL_BGHIN_SLOW",
+	.frameperiod = {1, 5},
+	.framelines = 625,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW),
+.v4l2_standard = {
+	.index = NTSC_N_443_SLOW,
+	.id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)),
+	.name = "NTSC_N_443_SLOW",
+	.frameperiod = {1, 5},
+	.framelines = 480,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & PAL_Nc_SLOW),
+.v4l2_standard = {
+	.index = PAL_Nc_SLOW,
+	.id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)),
+	.name = "PAL_Nc_SLOW",
+	.frameperiod = {1, 5},
+	.framelines = 625,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & NTSC_N_SLOW),
+.v4l2_standard = {
+	.index = NTSC_N_SLOW,
+	.id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)),
+	.name = "NTSC_N_SLOW",
+	.frameperiod = {1, 5},
+	.framelines = 525,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & SECAM_SLOW),
+.v4l2_standard = {
+	.index = SECAM_SLOW,
+	.id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)),
+	.name = "SECAM_SLOW",
+	.frameperiod = {1, 5},
+	.framelines = 625,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & NTSC_M_SLOW),
+.v4l2_standard = {
+	.index = NTSC_M_SLOW,
+	.id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)),
+	.name = "NTSC_M_SLOW",
+	.frameperiod = {1, 6},
+	.framelines = 525,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW),
+.v4l2_standard = {
+	.index = NTSC_M_JP_SLOW,
+	.id = (V4L2_STD_NTSC_M_JP | (((v4l2_std_id)0x01) << 32)),
+	.name = "NTSC_M_JP_SLOW",
+	.frameperiod = {1, 6},
+	.framelines = 525,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & PAL_60_SLOW),
+.v4l2_standard = {
+	.index = PAL_60_SLOW,
+	.id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)),
+	.name = "PAL_60_SLOW",
+	.frameperiod = {1, 6},
+	.framelines = 525,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & NTSC_443_SLOW),
+.v4l2_standard = {
+	.index = NTSC_443_SLOW,
+	.id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)),
+	.name = "NTSC_443_SLOW",
+	.frameperiod = {1, 6},
+	.framelines = 525,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
+.mask = 0x8000 | (0x00FF & PAL_M_SLOW),
+.v4l2_standard = {
+	.index = PAL_M_SLOW,
+	.id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)),
+	.name = "PAL_M_SLOW",
+	.frameperiod = {1, 6},
+	.framelines = 525,
+	.reserved = {0, 0, 0, 0}
+}
+},
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+{
 .mask = 0xFFFF
 }
 };
@@ -165,15 +291,16 @@
 /*
  *  THE 16-BIT easycap_format.mask HAS MEANING:
  *    (least significant) BIT  0:     0 => PAL, 25 FPS;   1 => NTSC, 30 FPS
- *                        BITS 1-3:   RESERVED FOR DIFFERENTIATING STANDARDS
- *                        BITS 4-7:   NUMBER OF BYTES PER PIXEL
+ *                        BITS 2-4:   RESERVED FOR DIFFERENTIATING STANDARDS
+ *                        BITS 5-7:   NUMBER OF BYTES PER PIXEL
  *                        BIT  8:     0 => NATIVE BYTE ORDER;  1 => SWAPPED
  *                        BITS 9-10:  RESERVED FOR OTHER BYTE PERMUTATIONS
- *                        BIT 11:     0 => UNDECIMATED;  1 => DECIMATED
- *                        BIT 12:     0 => OFFER FRAMES; 1 => OFFER FIELDS
- *     (most significant) BITS 13-15: RESERVED FOR OTHER FIELD ORDER OPTIONS
+ *                        BIT 11:     0 => UNDECIMATED;    1 => DECIMATED
+ *                        BIT 12:     0 => OFFER FRAMES;   1 => OFFER FIELDS
+ *                        BIT 13:     0 => FULL FRAMERATE; 1 => REDUCED
+ *     (most significant) BITS 14-15: RESERVED FOR OTHER FIELD/FRAME OPTIONS
  *  IT FOLLOWS THAT:
- *     bytesperpixel IS         ((0x00F0 & easycap_format.mask) >> 4)
+ *     bytesperpixel IS         ((0x00E0 & easycap_format.mask) >> 5)
  *     byteswaporder IS true IF (0 != (0x0100 & easycap_format.mask))
  *
  *     decimatepixel IS true IF (0 != (0x0800 & easycap_format.mask))
@@ -197,65 +324,135 @@
 	mask1 = 0x0000;
 	switch (i) {
 	case PAL_BGHIN: {
-		mask1 = PAL_BGHIN;
+		mask1 = 0x1F & PAL_BGHIN;
 		strcpy(&name1[0], "PAL_BGHIN");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
 		break;
 	}
 	case SECAM: {
-		mask1 = SECAM;
+		mask1 = 0x1F & SECAM;
 		strcpy(&name1[0], "SECAM");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
 		break;
 	}
 	case PAL_Nc: {
-		mask1 = PAL_Nc;
+		mask1 = 0x1F & PAL_Nc;
 		strcpy(&name1[0], "PAL_Nc");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
 		break;
 	}
 	case PAL_60: {
-		mask1 = PAL_60;
+		mask1 = 0x1F & PAL_60;
 		strcpy(&name1[0], "PAL_60");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
 		break;
 	}
 	case PAL_M: {
-		mask1 = PAL_M;
+		mask1 = 0x1F & PAL_M;
 		strcpy(&name1[0], "PAL_M");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
 		break;
 	}
 	case NTSC_M: {
-		mask1 = NTSC_M;
+		mask1 = 0x1F & NTSC_M;
 		strcpy(&name1[0], "NTSC_M");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
 		break;
 	}
 	case NTSC_443: {
-		mask1 = NTSC_443;
+		mask1 = 0x1F & NTSC_443;
 		strcpy(&name1[0], "NTSC_443");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
 		break;
 	}
 	case NTSC_M_JP: {
-		mask1 = NTSC_M_JP;
+		mask1 = 0x1F & NTSC_M_JP;
 		strcpy(&name1[0], "NTSC_M_JP");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
 		break;
 	}
 	case NTSC_N: {
-		mask1 = NTSC_M;
+		mask1 = 0x1F & NTSC_M;
 		strcpy(&name1[0], "NTSC_N");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
 		break;
 	}
 	case NTSC_N_443: {
-		mask1 = NTSC_N_443;
+		mask1 = 0x1F & NTSC_N_443;
 		strcpy(&name1[0], "NTSC_N_443");
 		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
 		break;
 	}
+	case PAL_BGHIN_SLOW: {
+		mask1 = 0x001F & PAL_BGHIN_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "PAL_BGHIN_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+		break;
+	}
+	case SECAM_SLOW: {
+		mask1 = 0x001F & SECAM_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "SECAM_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+		break;
+	}
+	case PAL_Nc_SLOW: {
+		mask1 = 0x001F & PAL_Nc_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "PAL_Nc_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+		break;
+	}
+	case PAL_60_SLOW: {
+		mask1 = 0x001F & PAL_60_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "PAL_60_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+		break;
+	}
+	case PAL_M_SLOW: {
+		mask1 = 0x001F & PAL_M_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "PAL_M_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+		break;
+	}
+	case NTSC_M_SLOW: {
+		mask1 = 0x001F & NTSC_M_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "NTSC_M_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+		break;
+	}
+	case NTSC_443_SLOW: {
+		mask1 = 0x001F & NTSC_443_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "NTSC_443_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+		break;
+	}
+	case NTSC_M_JP_SLOW: {
+		mask1 = 0x001F & NTSC_M_JP_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "NTSC_M_JP_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+		break;
+	}
+	case NTSC_N_SLOW: {
+		mask1 = 0x001F & NTSC_N_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "NTSC_N_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+		break;
+	}
+	case NTSC_N_443_SLOW: {
+		mask1 = 0x001F & NTSC_N_443_SLOW;
+		mask1 |= 0x0200;
+		strcpy(&name1[0], "NTSC_N_443_SLOW");
+		colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
+		break;
+	}
 	default:
 		return -1;
 	}
@@ -311,39 +508,39 @@
 			case FMT_UYVY: {
 				strcpy(&name3[0], "_" STRINGIZE(FMT_UYVY));
 				pixelformat = V4L2_PIX_FMT_UYVY;
-				mask3 |= (0x02 << 4);
+				mask3 |= (0x02 << 5);
 				break;
 			}
 			case FMT_YUY2: {
 				strcpy(&name3[0], "_" STRINGIZE(FMT_YUY2));
 				pixelformat = V4L2_PIX_FMT_YUYV;
-				mask3 |= (0x02 << 4);
+				mask3 |= (0x02 << 5);
 				mask3 |= 0x0100;
 				break;
 			}
 			case FMT_RGB24: {
 				strcpy(&name3[0], "_" STRINGIZE(FMT_RGB24));
 				pixelformat = V4L2_PIX_FMT_RGB24;
-				mask3 |= (0x03 << 4);
+				mask3 |= (0x03 << 5);
 				break;
 			}
 			case FMT_RGB32: {
 				strcpy(&name3[0], "_" STRINGIZE(FMT_RGB32));
 				pixelformat = V4L2_PIX_FMT_RGB32;
-				mask3 |= (0x04 << 4);
+				mask3 |= (0x04 << 5);
 				break;
 			}
 			case FMT_BGR24: {
 				strcpy(&name3[0], "_" STRINGIZE(FMT_BGR24));
 				pixelformat = V4L2_PIX_FMT_BGR24;
-				mask3 |= (0x03 << 4);
+				mask3 |= (0x03 << 5);
 				mask3 |= 0x0100;
 				break;
 			}
 			case FMT_BGR32: {
 				strcpy(&name3[0], "_" STRINGIZE(FMT_BGR32));
 				pixelformat = V4L2_PIX_FMT_BGR32;
-				mask3 |= (0x04 << 4);
+				mask3 |= (0x04 << 5);
 				mask3 |= 0x0100;
 				break;
 			}
@@ -363,13 +560,8 @@
 				}
 				case FIELD_INTERLACED: {
 					strcpy(&name4[0], "-i");
-					field = V4L2_FIELD_INTERLACED;
-					break;
-				}
-				case FIELD_ALTERNATE: {
-					strcpy(&name4[0], "-a");
 					mask4 |= 0x1000;
-					field = V4L2_FIELD_ALTERNATE;
+					field = V4L2_FIELD_INTERLACED;
 					break;
 				}
 				default:
@@ -413,7 +605,7 @@
 }
 /*---------------------------------------------------------------------------*/
 struct v4l2_queryctrl easycap_control[] = \
- {{
+{{
 .id       = V4L2_CID_BRIGHTNESS,
 .type     = V4L2_CTRL_TYPE_INTEGER,
 .name     = "Brightness",
@@ -485,5 +677,5 @@
 {
 .id = 0xFFFFFFFF
 }
- };
+};
 /*****************************************************************************/
diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c
index 63562bd..24d8bb4 100644
--- a/drivers/staging/easycap/easycap_sound.c
+++ b/drivers/staging/easycap/easycap_sound.c
@@ -36,17 +36,15 @@
 /*---------------------------------------------------------------------------*/
 /*
  *  ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
- *  PROVIDED peasycap->audio_idle IS ZER0.  REGARDLESS OF THIS BEING TRUE,
+ *  PROVIDED peasycap->audio_idle IS ZERO.  REGARDLESS OF THIS BEING TRUE,
  *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
  */
 /*---------------------------------------------------------------------------*/
 void
 easysnd_complete(struct urb *purb)
 {
-static int mt;
 struct easycap *peasycap;
 struct data_buffer *paudio_buffer;
-char errbuf[16];
 __u8 *p1, *p2;
 __s16 s16;
 int i, j, more, much, leap, rc;
@@ -66,48 +64,62 @@
 	SAY("ERROR: peasycap is NULL\n");
 	return;
 }
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap\n");
+	return;
+}
+
 much = 0;
 
-
 if (peasycap->audio_idle) {
-	JOT(16, "%i=audio_idle  %i=audio_isoc_streaming\n", \
+	JOM(16, "%i=audio_idle  %i=audio_isoc_streaming\n", \
 			peasycap->audio_idle, peasycap->audio_isoc_streaming);
 	if (peasycap->audio_isoc_streaming) {
 		rc = usb_submit_urb(purb, GFP_ATOMIC);
 		if (0 != rc) {
-			SAY("ERROR: while %i=audio_idle, " \
+			if (-ENODEV != rc)
+				SAM("ERROR: while %i=audio_idle, " \
 					"usb_submit_urb() failed with rc:\n", \
 							peasycap->audio_idle);
 			switch (rc) {
 			case -ENOMEM: {
-				SAY("ENOMEM\n");    break;
+				SAM("-ENOMEM\n");
+				break;
 			}
 			case -ENODEV: {
-				SAY("ENODEV\n");    break;
+				break;
 			}
 			case -ENXIO: {
-				SAY("ENXIO\n");     break;
+				SAM("-ENXIO\n");
+				break;
 			}
 			case -EINVAL: {
-				SAY("EINVAL\n");    break;
+				SAM("-EINVAL\n");
+				break;
 			}
 			case -EAGAIN: {
-				SAY("EAGAIN\n");    break;
+				SAM("-EAGAIN\n");
+				break;
 			}
 			case -EFBIG: {
-				SAY("EFBIG\n");     break;
+				SAM("-EFBIG\n");
+				break;
 			}
 			case -EPIPE: {
-				SAY("EPIPE\n");     break;
+				SAM("-EPIPE\n");
+				break;
 			}
 			case -EMSGSIZE: {
-				SAY("EMSGSIZE\n");  break;
+				SAM("-EMSGSIZE\n");
+				break;
 			}
 			case -ENOSPC: {
-				SAY("ENOSPC\n");  break;
+				SAM("-ENOSPC\n");
+				break;
 			}
 			default: {
-				SAY("0x%08X\n", rc); break;
+				SAM("unknown error: 0x%08X\n", rc);
+				break;
 			}
 			}
 		}
@@ -116,74 +128,95 @@
 }
 /*---------------------------------------------------------------------------*/
 if (purb->status) {
-	if (-ESHUTDOWN == purb->status) {
-		JOT(16, "immediate return because -ESHUTDOWN=purb->status\n");
+	if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
+		JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
 		return;
 	}
-	SAY("ERROR: non-zero urb status:\n");
+	SAM("ERROR: non-zero urb status:\n");
 	switch (purb->status) {
 	case -EINPROGRESS: {
-		SAY("-EINPROGRESS\n"); break;
+		SAM("-EINPROGRESS\n");
+		break;
 	}
 	case -ENOSR: {
-		SAY("-ENOSR\n"); break;
+		SAM("-ENOSR\n");
+		break;
 	}
 	case -EPIPE: {
-		SAY("-EPIPE\n"); break;
+		SAM("-EPIPE\n");
+		break;
 	}
 	case -EOVERFLOW: {
-		SAY("-EOVERFLOW\n"); break;
+		SAM("-EOVERFLOW\n");
+		break;
 	}
 	case -EPROTO: {
-		SAY("-EPROTO\n"); break;
+		SAM("-EPROTO\n");
+		break;
 	}
 	case -EILSEQ: {
-		SAY("-EILSEQ\n"); break;
+		SAM("-EILSEQ\n");
+		break;
 	}
 	case -ETIMEDOUT: {
-		SAY("-ETIMEDOUT\n"); break;
+		SAM("-ETIMEDOUT\n");
+		break;
 	}
 	case -EMSGSIZE: {
-		SAY("-EMSGSIZE\n"); break;
+		SAM("-EMSGSIZE\n");
+		break;
 	}
 	case -EOPNOTSUPP: {
-		SAY("-EOPNOTSUPP\n"); break;
+		SAM("-EOPNOTSUPP\n");
+		break;
 	}
 	case -EPFNOSUPPORT: {
-		SAY("-EPFNOSUPPORT\n"); break;
+		SAM("-EPFNOSUPPORT\n");
+		break;
 	}
 	case -EAFNOSUPPORT: {
-		SAY("-EAFNOSUPPORT\n"); break;
+		SAM("-EAFNOSUPPORT\n");
+		break;
 	}
 	case -EADDRINUSE: {
-		SAY("-EADDRINUSE\n"); break;
+		SAM("-EADDRINUSE\n");
+		break;
 	}
 	case -EADDRNOTAVAIL: {
-		SAY("-EADDRNOTAVAIL\n"); break;
+		SAM("-EADDRNOTAVAIL\n");
+		break;
 	}
 	case -ENOBUFS: {
-		SAY("-ENOBUFS\n"); break;
+		SAM("-ENOBUFS\n");
+		break;
 	}
 	case -EISCONN: {
-		SAY("-EISCONN\n"); break;
+		SAM("-EISCONN\n");
+		break;
 	}
 	case -ENOTCONN: {
-		SAY("-ENOTCONN\n"); break;
+		SAM("-ENOTCONN\n");
+		break;
 	}
 	case -ESHUTDOWN: {
-		SAY("-ESHUTDOWN\n"); break;
+		SAM("-ESHUTDOWN\n");
+		break;
 	}
 	case -ENOENT: {
-		SAY("-ENOENT\n"); break;
+		SAM("-ENOENT\n");
+		break;
 	}
 	case -ECONNRESET: {
-		SAY("-ECONNRESET\n"); break;
+		SAM("-ECONNRESET\n");
+		break;
 	}
 	case -ENOSPC: {
-		SAY("ENOSPC\n");  break;
+		SAM("ENOSPC\n");
+		break;
 	}
 	default: {
-		SAY("unknown error code 0x%08X\n", purb->status); break;
+		SAM("unknown error code 0x%08X\n", purb->status);
+		break;
 	}
 	}
 /*---------------------------------------------------------------------------*/
@@ -196,35 +229,43 @@
 	if (peasycap->audio_isoc_streaming) {
 		rc = usb_submit_urb(purb, GFP_ATOMIC);
 		if (0 != rc) {
-			SAY("ERROR: while %i=audio_idle, usb_submit_urb() "
+			SAM("ERROR: while %i=audio_idle, usb_submit_urb() "
 				"failed with rc:\n", peasycap->audio_idle);
 			switch (rc) {
 			case -ENOMEM: {
-				SAY("ENOMEM\n");    break;
+				SAM("-ENOMEM\n");
+				break;
 			}
 			case -ENODEV: {
-				SAY("ENODEV\n");    break;
+				SAM("-ENODEV\n");
+				break;
 			}
 			case -ENXIO: {
-				SAY("ENXIO\n");     break;
+				SAM("-ENXIO\n");
+				break;
 			}
 			case -EINVAL: {
-				SAY("EINVAL\n");    break;
+				SAM("-EINVAL\n");
+				break;
 			}
 			case -EAGAIN: {
-				SAY("EAGAIN\n");    break;
+				SAM("-EAGAIN\n");
+				break;
 			}
 			case -EFBIG: {
-				SAY("EFBIG\n");     break;
+				SAM("-EFBIG\n");
+				break;
 			}
 			case -EPIPE: {
-				SAY("EPIPE\n");     break;
+				SAM("-EPIPE\n");
+				break;
 			}
 			case -EMSGSIZE: {
-				SAY("EMSGSIZE\n");  break;
+				SAM("-EMSGSIZE\n");
+				break;
 			}
 			default: {
-				SAY("0x%08X\n", rc); break;
+				SAM("0x%08X\n", rc); break;
 			}
 			}
 		}
@@ -243,73 +284,81 @@
 for (i = 0;  i < purb->number_of_packets; i++) {
 	switch (purb->iso_frame_desc[i].status) {
 	case  0: {
-		strcpy(&errbuf[0], "OK"); break;
+		break;
 	}
 	case -ENOENT: {
-		strcpy(&errbuf[0], "-ENOENT"); break;
+		SAM("-ENOENT\n");
+		break;
 	}
 	case -EINPROGRESS: {
-		strcpy(&errbuf[0], "-EINPROGRESS"); break;
+		SAM("-EINPROGRESS\n");
+		break;
 	}
 	case -EPROTO: {
-		strcpy(&errbuf[0], "-EPROTO"); break;
+		SAM("-EPROTO\n");
+		break;
 	}
 	case -EILSEQ: {
-		strcpy(&errbuf[0], "-EILSEQ"); break;
+		SAM("-EILSEQ\n");
+		break;
 	}
 	case -ETIME: {
-		strcpy(&errbuf[0], "-ETIME"); break;
+		SAM("-ETIME\n");
+		break;
 	}
 	case -ETIMEDOUT: {
-		strcpy(&errbuf[0], "-ETIMEDOUT"); break;
+		SAM("-ETIMEDOUT\n");
+		break;
 	}
 	case -EPIPE: {
-		strcpy(&errbuf[0], "-EPIPE"); break;
+		SAM("-EPIPE\n");
+		break;
 	}
 	case -ECOMM: {
-		strcpy(&errbuf[0], "-ECOMM"); break;
+		SAM("-ECOMM\n");
+		break;
 	}
 	case -ENOSR: {
-		strcpy(&errbuf[0], "-ENOSR"); break;
+		SAM("-ENOSR\n");
+		break;
 	}
 	case -EOVERFLOW: {
-		strcpy(&errbuf[0], "-EOVERFLOW"); break;
+		SAM("-EOVERFLOW\n");
+		break;
 	}
 	case -EREMOTEIO: {
-		strcpy(&errbuf[0], "-EREMOTEIO"); break;
+		SAM("-EREMOTEIO\n");
+		break;
 	}
 	case -ENODEV: {
-		strcpy(&errbuf[0], "-ENODEV"); break;
+		SAM("-ENODEV\n");
+		break;
 	}
 	case -EXDEV: {
-		strcpy(&errbuf[0], "-EXDEV"); break;
+		SAM("-EXDEV\n");
+		break;
 	}
 	case -EINVAL: {
-		strcpy(&errbuf[0], "-EINVAL"); break;
+		SAM("-EINVAL\n");
+		break;
 	}
 	case -ECONNRESET: {
-		strcpy(&errbuf[0], "-ECONNRESET"); break;
+		SAM("-ECONNRESET\n");
+		break;
 	}
 	case -ENOSPC: {
-		strcpy(&errbuf[0], "-ENOSPC"); break;
+		SAM("-ENOSPC\n");
+		break;
 	}
 	case -ESHUTDOWN: {
-		strcpy(&errbuf[0], "-ESHUTDOWN"); break;
+		SAM("-ESHUTDOWN\n");
+		break;
 	}
 	default: {
-		strcpy(&errbuf[0], "UNKNOWN"); break;
+		SAM("unknown error:0x%08X\n", purb->iso_frame_desc[i].status);
+		break;
 	}
 	}
-	if ((!purb->iso_frame_desc[i].status) && 0) {
-		JOT(16, "frame[%2i]: %i=status{=%16s}  "  \
-						"%5i=actual  "  \
-						"%5i=length  "  \
-						"%3i=offset\n", \
-				i, purb->iso_frame_desc[i].status, &errbuf[0],
-				purb->iso_frame_desc[i].actual_length,
-				purb->iso_frame_desc[i].length,
-				purb->iso_frame_desc[i].offset);
-	}
 	if (!purb->iso_frame_desc[i].status) {
 		more = purb->iso_frame_desc[i].actual_length;
 
@@ -319,11 +368,12 @@
 #endif
 
 		if (!more)
-			mt++;
+			peasycap->audio_mt++;
 		else {
-			if (mt) {
-				JOT(16, "%4i empty audio urb frames\n", mt);
-				mt = 0;
+			if (peasycap->audio_mt) {
+				JOM(16, "%4i empty audio urb frames\n", \
+							peasycap->audio_mt);
+				peasycap->audio_mt = 0;
 			}
 
 			p1 = (__u8 *)(purb->transfer_buffer + \
@@ -340,13 +390,13 @@
 /*---------------------------------------------------------------------------*/
 			while (more) {
 				if (0 > more) {
-					SAY("easysnd_complete: MISTAKE: " \
+					SAM("easysnd_complete: MISTAKE: " \
 							"more is negative\n");
 					return;
 				}
 				if (peasycap->audio_buffer_page_many <= \
 							peasycap->audio_fill) {
-					SAY("ERROR: bad " \
+					SAM("ERROR: bad " \
 						"peasycap->audio_fill\n");
 					return;
 				}
@@ -355,7 +405,7 @@
 							[peasycap->audio_fill];
 				if (PAGE_SIZE < (paudio_buffer->pto - \
 						paudio_buffer->pgo)) {
-					SAY("ERROR: bad paudio_buffer->pto\n");
+					SAM("ERROR: bad paudio_buffer->pto\n");
 					return;
 				}
 				if (PAGE_SIZE == (paudio_buffer->pto - \
@@ -374,7 +424,7 @@
 							peasycap->audio_fill)
 						peasycap->audio_fill = 0;
 
-					JOT(12, "bumped peasycap->" \
+					JOM(12, "bumped peasycap->" \
 							"audio_fill to %i\n", \
 							peasycap->audio_fill);
 
@@ -387,7 +437,7 @@
 					if (!(peasycap->audio_fill % \
 						peasycap->\
 						audio_pages_per_fragment)) {
-						JOT(12, "wakeup call on wq_" \
+						JOM(12, "wakeup call on wq_" \
 						"audio, %i=frag reading  %i" \
 						"=fragment fill\n", \
 						(peasycap->audio_read / \
@@ -414,7 +464,7 @@
 				} else {
 #if defined(UPSAMPLE)
 					if (much % 16)
-						JOT(8, "MISTAKE? much" \
+						JOM(8, "MISTAKE? much" \
 						" is not divisible by 16\n");
 					if (much > (16 * \
 							more))
@@ -468,7 +518,7 @@
 			}
 		}
 	} else {
-		JOT(12, "discarding audio samples because " \
+		JOM(12, "discarding audio samples because " \
 			"%i=purb->iso_frame_desc[i].status\n", \
 				purb->iso_frame_desc[i].status);
 	}
@@ -486,38 +536,50 @@
 if (peasycap->audio_isoc_streaming) {
 	rc = usb_submit_urb(purb, GFP_ATOMIC);
 	if (0 != rc) {
-		SAY("ERROR: while %i=audio_idle, usb_submit_urb() failed " \
+		if (-ENODEV != rc) {
+			SAM("ERROR: while %i=audio_idle, " \
+					"usb_submit_urb() failed " \
 					"with rc:\n", peasycap->audio_idle);
+		}
 		switch (rc) {
 		case -ENOMEM: {
-			SAY("ENOMEM\n");    break;
+			SAM("-ENOMEM\n");
+			break;
 		}
 		case -ENODEV: {
-			SAY("ENODEV\n");    break;
+			break;
 		}
 		case -ENXIO: {
-			SAY("ENXIO\n");     break;
+			SAM("-ENXIO\n");
+			break;
 		}
 		case -EINVAL: {
-			SAY("EINVAL\n");    break;
+			SAM("-EINVAL\n");
+			break;
 		}
 		case -EAGAIN: {
-			SAY("EAGAIN\n");    break;
+			SAM("-EAGAIN\n");
+			break;
 		}
 		case -EFBIG: {
-			SAY("EFBIG\n");     break;
+			SAM("-EFBIG\n");
+			break;
 		}
 		case -EPIPE: {
-			SAY("EPIPE\n");     break;
+			SAM("-EPIPE\n");
+			break;
 		}
 		case -EMSGSIZE: {
-			SAY("EMSGSIZE\n");  break;
+			SAM("-EMSGSIZE\n");
+			break;
 		}
 		case -ENOSPC: {
-			SAY("ENOSPC\n");  break;
+			SAM("-ENOSPC\n");
+			break;
 		}
 		default: {
-			SAY("0x%08X\n", rc); break;
+			SAM("unknown error: 0x%08X\n", rc);
+			break;
 		}
 		}
 	}
@@ -529,8 +591,7 @@
 /*
  *  THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
  *  STREAM FROM /dev/easysnd1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
- *  HAVE AN IOCTL INTERFACE.  THE VIDEO URBS, BY CONTRAST, MUST BE SUBMITTED
- *  MUCH LATER: SEE COMMENTS IN FILE easycap_main.c.
+ *  HAVE AN IOCTL INTERFACE.
  */
 /*---------------------------------------------------------------------------*/
 int
@@ -539,8 +600,15 @@
 struct usb_interface *pusb_interface;
 struct easycap *peasycap;
 int subminor, rc;
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+struct v4l2_device *pv4l2_device;
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
 
-JOT(4, "begins.\n");
+JOT(4, "begins\n");
 
 subminor = iminor(inode);
 
@@ -556,70 +624,90 @@
 	SAY("ending unsuccessfully\n");
 	return -1;
 }
+/*---------------------------------------------------------------------------*/
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+#
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+/*---------------------------------------------------------------------------*/
+/*
+ *  SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
+ *  BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
+ *  REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
+ *  TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
+*/
+/*---------------------------------------------------------------------------*/
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	pv4l2_device = usb_get_intfdata(pusb_interface);
+	if ((struct v4l2_device *)NULL == pv4l2_device) {
+		SAY("ERROR: pv4l2_device is NULL\n");
+		return -EFAULT;
+	}
+	peasycap = (struct easycap *) \
+		container_of(pv4l2_device, struct easycap, v4l2_device);
+}
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*---------------------------------------------------------------------------*/
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
 
 file->private_data = peasycap;
 
 /*---------------------------------------------------------------------------*/
 /*
- *  INITIALIZATION.
+ *  INITIALIZATION
  */
 /*---------------------------------------------------------------------------*/
-JOT(4, "starting initialization\n");
+JOM(4, "starting initialization\n");
 
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
-	return -EFAULT;
-} else {
-	JOT(16, "0x%08lX=peasycap->pusb_device\n", \
-					(long int)peasycap->pusb_device);
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
+	return -ENODEV;
 }
+JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
 
 rc = audio_setup(peasycap);
 if (0 <= rc)
-	JOT(8, "audio_setup() returned %i\n", rc);
+	JOM(8, "audio_setup() returned %i\n", rc);
 else
-	JOT(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc);
+	JOM(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc);
 
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device has become NULL\n");
-	return -EFAULT;
-}
-rc = adjust_volume(peasycap, -8192);
-if (0 != rc) {
-	SAY("ERROR: adjust_volume(default) returned %i\n", rc);
-	return -EFAULT;
+	SAM("ERROR: peasycap->pusb_device has become NULL\n");
+	return -ENODEV;
 }
 /*---------------------------------------------------------------------------*/
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device has become NULL\n");
-	return -EFAULT;
+	SAM("ERROR: peasycap->pusb_device has become NULL\n");
+	return -ENODEV;
 }
 rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \
 					peasycap->audio_altsetting_on);
-JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \
+JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \
 					peasycap->audio_altsetting_on, rc);
 
-if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device has become NULL\n");
-	return -EFAULT;
-}
 rc = wakeup_device(peasycap->pusb_device);
 if (0 == rc)
-	JOT(8, "wakeup_device() returned %i\n", rc);
+	JOM(8, "wakeup_device() returned %i\n", rc);
 else
-	JOT(8, "easysnd open(): ERROR: wakeup_device() returned %i\n", rc);
+	JOM(8, "ERROR: wakeup_device() returned %i\n", rc);
 
-if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device has become NULL\n");
-	return -EFAULT;
-}
-submit_audio_urbs(peasycap);
+peasycap->audio_eof = 0;
 peasycap->audio_idle = 0;
 
 peasycap->timeval1.tv_sec  = 0;
 peasycap->timeval1.tv_usec = 0;
 
-JOT(4, "finished initialization\n");
+submit_audio_urbs(peasycap);
+
+JOM(4, "finished initialization\n");
 return 0;
 }
 /*****************************************************************************/
@@ -635,11 +723,15 @@
 	SAY("ERROR:  peasycap is NULL.\n");
 	return -EFAULT;
 }
-if (0 != kill_audio_urbs(peasycap)) {
-	SAY("ERROR: kill_audio_urbs() failed\n");
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
 	return -EFAULT;
 }
-JOT(4, "ending successfully\n");
+if (0 != kill_audio_urbs(peasycap)) {
+	SAM("ERROR: kill_audio_urbs() failed\n");
+	return -EFAULT;
+}
+JOM(4, "ending successfully\n");
 return 0;
 }
 /*****************************************************************************/
@@ -648,12 +740,11 @@
 						size_t kount, loff_t *poff)
 {
 struct timeval timeval;
-static struct timeval timeval1;
-static long long int audio_bytes, above, below, mean;
+long long int above, below, mean;
 struct signed_div_result sdr;
 unsigned char *p0;
 long int kount1, more, rc, l0, lm;
-int fragment;
+int fragment, kd;
 struct easycap *peasycap;
 struct data_buffer *pdata_buffer;
 size_t szret;
@@ -671,23 +762,89 @@
 
 JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
 
-peasycap = (struct easycap *)(file->private_data);
+if (NULL == file) {
+	SAY("ERROR:  file is NULL\n");
+	return -ERESTARTSYS;
+}
+peasycap = file->private_data;
 if (NULL == peasycap) {
 	SAY("ERROR in easysnd_read(): peasycap is NULL\n");
 	return -EFAULT;
 }
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+if (NULL == peasycap->pusb_device) {
+	SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+kd = isdongle(peasycap);
+if (0 <= kd && DONGLE_MANY > kd) {
+	if (mutex_lock_interruptible(&(easycap_dongle[kd].mutex_audio))) {
+		SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd);
+		return -ERESTARTSYS;
+	}
+	JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
 /*---------------------------------------------------------------------------*/
+/*
+ *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
+ *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
+ *  IF NECESSARY, BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	if (kd != isdongle(peasycap))
+		return -ERESTARTSYS;
+	if (NULL == file) {
+		SAY("ERROR:  file is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	peasycap = file->private_data;
+	if (NULL == peasycap) {
+		SAY("ERROR:  peasycap is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+		SAY("ERROR: bad peasycap: 0x%08lX\n", \
+						(unsigned long int) peasycap);
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (NULL == peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+} else {
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
+ *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	return -ERESTARTSYS;
+}
+/*---------------------------------------------------------------------------*/
+if (file->f_flags & O_NONBLOCK)
+	JOT(16, "NONBLOCK  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+else
+	JOT(8, "BLOCKING  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+
 if ((0 > peasycap->audio_read) || \
 		(peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
-	SAY("ERROR: peasycap->audio_read out of range\n");
+	SAM("ERROR: peasycap->audio_read out of range\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_audio);
 	return -EFAULT;
 }
 pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
 if ((struct data_buffer *)NULL == pdata_buffer) {
-	SAY("ERROR: pdata_buffer is NULL\n");
+	SAM("ERROR: pdata_buffer is NULL\n");
+	mutex_unlock(&easycap_dongle[kd].mutex_audio);
 	return -EFAULT;
 }
-JOT(12, "before wait, %i=frag read  %i=frag fill\n", \
+JOM(12, "before wait, %i=frag read  %i=frag fill\n", \
 		(peasycap->audio_read / peasycap->audio_pages_per_fragment), \
 		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
 fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
@@ -695,7 +852,8 @@
 				peasycap->audio_pages_per_fragment)) || \
 		(0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
 	if (file->f_flags & O_NONBLOCK) {
-		JOT(16, "returning -EAGAIN as instructed\n");
+		JOM(16, "returning -EAGAIN as instructed\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EAGAIN;
 	}
 	rc = wait_event_interruptible(peasycap->wq_audio, \
@@ -704,50 +862,56 @@
 				peasycap->audio_pages_per_fragment)) && \
 		(0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
 	if (0 != rc) {
-		SAY("aborted by signal\n");
+		SAM("aborted by signal\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -ERESTARTSYS;
 	}
 	if (peasycap->audio_eof) {
-		JOT(8, "returning 0 because  %i=audio_eof\n", \
+		JOM(8, "returning 0 because  %i=audio_eof\n", \
 							peasycap->audio_eof);
 		kill_audio_urbs(peasycap);
-		msleep(500);
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return 0;
 	}
 	if (peasycap->audio_idle) {
-		JOT(16, "returning 0 because  %i=audio_idle\n", \
+		JOM(16, "returning 0 because  %i=audio_idle\n", \
 							peasycap->audio_idle);
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return 0;
 	}
 	if (!peasycap->audio_isoc_streaming) {
-		JOT(16, "returning 0 because audio urbs not streaming\n");
+		JOM(16, "returning 0 because audio urbs not streaming\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return 0;
 	}
 }
-JOT(12, "after  wait, %i=frag read  %i=frag fill\n", \
+JOM(12, "after  wait, %i=frag read  %i=frag fill\n", \
 		(peasycap->audio_read / peasycap->audio_pages_per_fragment), \
 		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
 szret = (size_t)0;
 while (fragment == (peasycap->audio_read / \
 				peasycap->audio_pages_per_fragment)) {
 	if (NULL == pdata_buffer->pgo) {
-		SAY("ERROR: pdata_buffer->pgo is NULL\n");
+		SAM("ERROR: pdata_buffer->pgo is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
 	}
 	if (NULL == pdata_buffer->pto) {
-		SAY("ERROR: pdata_buffer->pto is NULL\n");
+		SAM("ERROR: pdata_buffer->pto is NULL\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
 	}
 	kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
 	if (0 > kount1) {
-		SAY("easysnd_read: MISTAKE: kount1 is negative\n");
+		SAM("easysnd_read: MISTAKE: kount1 is negative\n");
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -ERESTARTSYS;
 	}
 	if (!kount1) {
 		(peasycap->audio_read)++;
 		if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
 			peasycap->audio_read = 0;
-		JOT(12, "bumped peasycap->audio_read to %i\n", \
+		JOM(12, "bumped peasycap->audio_read to %i\n", \
 						peasycap->audio_read);
 
 		if (fragment != (peasycap->audio_read / \
@@ -757,30 +921,34 @@
 		if ((0 > peasycap->audio_read) || \
 			(peasycap->audio_buffer_page_many <= \
 					peasycap->audio_read)) {
-			SAY("ERROR: peasycap->audio_read out of range\n");
+			SAM("ERROR: peasycap->audio_read out of range\n");
+			mutex_unlock(&easycap_dongle[kd].mutex_audio);
 			return -EFAULT;
 		}
 		pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
 		if ((struct data_buffer *)NULL == pdata_buffer) {
-			SAY("ERROR: pdata_buffer is NULL\n");
+			SAM("ERROR: pdata_buffer is NULL\n");
+			mutex_unlock(&easycap_dongle[kd].mutex_audio);
 			return -EFAULT;
 		}
 		if (NULL == pdata_buffer->pgo) {
-			SAY("ERROR: pdata_buffer->pgo is NULL\n");
+			SAM("ERROR: pdata_buffer->pgo is NULL\n");
+			mutex_unlock(&easycap_dongle[kd].mutex_audio);
 			return -EFAULT;
 		}
 		if (NULL == pdata_buffer->pto) {
-			SAY("ERROR: pdata_buffer->pto is NULL\n");
+			SAM("ERROR: pdata_buffer->pto is NULL\n");
+			mutex_unlock(&easycap_dongle[kd].mutex_audio);
 			return -EFAULT;
 		}
 		kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
 	}
-	JOT(12, "ready  to send %li bytes\n", (long int) kount1);
-	JOT(12, "still  to send %li bytes\n", (long int) kount);
+	JOM(12, "ready  to send %li bytes\n", (long int) kount1);
+	JOM(12, "still  to send %li bytes\n", (long int) kount);
 	more = kount1;
 	if (more > kount)
 		more = kount;
-	JOT(12, "agreed to send %li bytes from page %i\n", \
+	JOM(12, "agreed to send %li bytes from page %i\n", \
 						more, peasycap->audio_read);
 	if (!more)
 		break;
@@ -798,7 +966,8 @@
 /*---------------------------------------------------------------------------*/
 	rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
 	if (0 != rc) {
-		SAY("ERROR: copy_to_user() returned %li\n", rc);
+		SAM("ERROR: copy_to_user() returned %li\n", rc);
+		mutex_unlock(&easycap_dongle[kd].mutex_audio);
 		return -EFAULT;
 	}
 	*poff += (loff_t)more;
@@ -807,11 +976,11 @@
 	puserspacebuffer += more;
 	kount -= (size_t)more;
 }
-JOT(12, "after  read, %i=frag read  %i=frag fill\n", \
+JOM(12, "after  read, %i=frag read  %i=frag fill\n", \
 		(peasycap->audio_read / peasycap->audio_pages_per_fragment), \
 		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
 if (kount < 0) {
-	SAY("MISTAKE:  %li=kount  %li=szret\n", \
+	SAM("MISTAKE:  %li=kount  %li=szret\n", \
 					(long int)kount, (long int)szret);
 }
 /*---------------------------------------------------------------------------*/
@@ -827,11 +996,11 @@
 	mean = peasycap->audio_niveau;
 	sdr = signed_div(mean, peasycap->audio_sample);
 
-	JOT(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n", \
+	JOM(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n", \
 				sdr.quotient, above, peasycap->audio_sample);
 
 	sdr = signed_div(above, 32768);
-	JOT(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
+	JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
 }
 /*---------------------------------------------------------------------------*/
 /*
@@ -840,33 +1009,28 @@
 /*---------------------------------------------------------------------------*/
 do_gettimeofday(&timeval);
 if (!peasycap->timeval1.tv_sec) {
-	audio_bytes = 0;
-	timeval1 = timeval;
-
-	if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
-		return -ERESTARTSYS;
-	peasycap->timeval1 = timeval1;
-	mutex_unlock(&(peasycap->mutex_timeval1));
+	peasycap->audio_bytes = 0;
+	peasycap->timeval3 = timeval;
+	peasycap->timeval1 = peasycap->timeval3;
 	sdr.quotient = 192000;
 } else {
-	audio_bytes += (long long int) szret;
+	peasycap->audio_bytes += (long long int) szret;
 	below = ((long long int)(1000000)) * \
-		((long long int)(timeval.tv_sec  - timeval1.tv_sec)) + \
-		(long long int)(timeval.tv_usec - timeval1.tv_usec);
-	above = 1000000 * ((long long int) audio_bytes);
+		((long long int)(timeval.tv_sec  - \
+						peasycap->timeval3.tv_sec)) + \
+		(long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec);
+	above = 1000000 * ((long long int) peasycap->audio_bytes);
 
 	if (below)
 		sdr = signed_div(above, below);
 	else
 		sdr.quotient = 192000;
 }
-JOT(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
-if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
-	return -ERESTARTSYS;
+JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
 peasycap->dnbydt = sdr.quotient;
-mutex_unlock(&(peasycap->mutex_timeval1));
 
-JOT(8, "returning %li\n", (long int)szret);
+JOM(8, "returning %li\n", (long int)szret);
+mutex_unlock(&easycap_dongle[kd].mutex_audio);
 return szret;
 }
 /*****************************************************************************/
@@ -881,27 +1045,31 @@
 struct data_urb *pdata_urb;
 struct urb *purb;
 struct list_head *plist_head;
-int j, isbad, m, rc;
+int j, isbad, nospc, m, rc;
 int isbuf;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if ((struct list_head *)NULL == peasycap->purb_audio_head) {
-	SAY("ERROR: peasycap->urb_audio_head uninitialized\n");
+	SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
 	return -EFAULT;
 }
 if ((struct usb_device *)NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	SAM("ERROR: peasycap->pusb_device is NULL\n");
 	return -EFAULT;
 }
 if (!peasycap->audio_isoc_streaming) {
-	JOT(4, "initial submission of all audio urbs\n");
+	JOM(4, "initial submission of all audio urbs\n");
 	rc = usb_set_interface(peasycap->pusb_device,
 					peasycap->audio_interface, \
 					peasycap->audio_altsetting_on);
-	JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", \
+	JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", \
 					peasycap->audio_interface, \
 					peasycap->audio_altsetting_on, rc);
 
-	isbad = 0;  m = 0;
+	isbad = 0;  nospc = 0;  m = 0;
 	list_for_each(plist_head, (peasycap->purb_audio_head)) {
 		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
 		if (NULL != pdata_urb) {
@@ -938,39 +1106,49 @@
 				rc = usb_submit_urb(purb, GFP_KERNEL);
 				if (0 != rc) {
 					isbad++;
-					SAY("ERROR: usb_submit_urb() failed" \
+					SAM("ERROR: usb_submit_urb() failed" \
 							" for urb with rc:\n");
 					switch (rc) {
 					case -ENOMEM: {
-						SAY("ENOMEM\n"); break;
+						SAM("-ENOMEM\n");
+						break;
 					}
 					case -ENODEV: {
-						SAY("ENODEV\n"); break;
+						SAM("-ENODEV\n");
+						break;
 					}
 					case -ENXIO: {
-						SAY("ENXIO\n"); break;
+						SAM("-ENXIO\n");
+						break;
 					}
 					case -EINVAL: {
-						SAY("EINVAL\n"); break;
+						SAM("-EINVAL\n");
+						break;
 					}
 					case -EAGAIN: {
-						SAY("EAGAIN\n"); break;
+						SAM("-EAGAIN\n");
+						break;
 					}
 					case -EFBIG: {
-						SAY("EFBIG\n"); break;
+						SAM("-EFBIG\n");
+						break;
 					}
 					case -EPIPE: {
-						SAY("EPIPE\n"); break;
+						SAM("-EPIPE\n");
+						break;
 					}
 					case -EMSGSIZE: {
-						SAY("EMSGSIZE\n"); break;
+						SAM("-EMSGSIZE\n");
+						break;
 					}
 					case -ENOSPC: {
-						SAY("ENOSPC\n"); break;
+						nospc++;
+						break;
 					}
 					default: {
-						SAY("unknown error code %i\n",\
-								 rc); break;
+						SAM("unknown error code %i\n",\
+								 rc);
+						break;
 					}
 					}
 				} else {
@@ -983,8 +1161,13 @@
 			isbad++;
 		}
 	}
+	if (nospc) {
+		SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
+		SAM(".....  possibly inadequate USB bandwidth\n");
+		peasycap->audio_eof = 1;
+	}
 	if (isbad) {
-		JOT(4, "attempting cleanup instead of submitting\n");
+		JOM(4, "attempting cleanup instead of submitting\n");
 		list_for_each(plist_head, (peasycap->purb_audio_head)) {
 			pdata_urb = list_entry(plist_head, struct data_urb, \
 								list_head);
@@ -997,10 +1180,10 @@
 		peasycap->audio_isoc_streaming = 0;
 	} else {
 		peasycap->audio_isoc_streaming = 1;
-		JOT(4, "submitted %i audio urbs\n", m);
+		JOM(4, "submitted %i audio urbs\n", m);
 	}
 } else
-	JOT(4, "already streaming audio urbs\n");
+	JOM(4, "already streaming audio urbs\n");
 
 return 0;
 }
@@ -1017,10 +1200,14 @@
 struct list_head *plist_head;
 struct data_urb *pdata_urb;
 
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return -EFAULT;
+}
 if (peasycap->audio_isoc_streaming) {
 	if ((struct list_head *)NULL != peasycap->purb_audio_head) {
 		peasycap->audio_isoc_streaming = 0;
-		JOT(4, "killing audio urbs\n");
+		JOM(4, "killing audio urbs\n");
 		m = 0;
 		list_for_each(plist_head, (peasycap->purb_audio_head)) {
 			pdata_urb = list_entry(plist_head, struct data_urb,
@@ -1032,13 +1219,13 @@
 				}
 			}
 		}
-		JOT(4, "%i audio urbs killed\n", m);
+		JOM(4, "%i audio urbs killed\n", m);
 	} else {
-		SAY("ERROR: peasycap->purb_audio_head is NULL\n");
+		SAM("ERROR: peasycap->purb_audio_head is NULL\n");
 		return -EFAULT;
 	}
 } else {
-	JOT(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \
+	JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \
 					peasycap->audio_isoc_streaming);
 }
 return 0;
diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c
index 3c2ce28..e27dfe9 100644
--- a/drivers/staging/easycap/easycap_testcard.c
+++ b/drivers/staging/easycap/easycap_testcard.c
@@ -29,37 +29,69 @@
 #include "easycap_debug.h"
 
 /*****************************************************************************/
-#define TESTCARD_BYTESPERLINE (2 * 1440)
+#define TESTCARD_BYTESPERLINE (2 * 720)
 void
-easycap_testcard(struct easycap *peasycap, int field_fill)
+easycap_testcard(struct easycap *peasycap, int field)
 {
 int total;
 int y, u, v, r, g, b;
 unsigned char uyvy[4];
-
-int i1, line, k, m, n, more, much, barwidth;
+int i1, line, k, m, n, more, much, barwidth, barheight;
 unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2;
 struct data_buffer *pfield_buffer;
 
-JOT(8, "%i=field_fill\n", field_fill);
-
-if ((TESTCARD_BYTESPERLINE / 2) < peasycap->width) {
-	SAY("ERROR: image is too wide\n");
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
 	return;
 }
-if (peasycap->width % 16) {
-	SAY("ERROR: indivisible image width\n");
+JOM(8, "%i=field\n", field);
+switch (peasycap->width) {
+case 720:
+case 360: {
+	barwidth = (2 * 720) / 8;
+	break;
+}
+case 704:
+case 352: {
+	barwidth = (2 * 704) / 8;
+	break;
+}
+case 640:
+case 320: {
+	barwidth = (2 * 640) / 8;
+	break;
+}
+default: {
+	SAM("ERROR:  cannot set barwidth\n");
 	return;
 }
-
+}
+if (TESTCARD_BYTESPERLINE < barwidth) {
+	SAM("ERROR: barwidth is too large\n");
+	return;
+}
+switch (peasycap->height) {
+case 576:
+case 288: {
+	barheight = 576;
+	break;
+}
+case 480:
+case 240: {
+	barheight = 480;
+	break;
+}
+default: {
+	SAM("ERROR: cannot set barheight\n");
+	return;
+}
+}
 total = 0;
-barwidth = (2 * peasycap->width) / 8;
-
-k = field_fill;
+k = field;
 m = 0;
 n = 0;
 
-for (line = 0;  line < (peasycap->height / 2);  line++) {
+for (line = 0;  line < (barheight / 2);  line++) {
 	for (i1 = 0;  i1 < 8;  i1++) {
 		r = (i1 * 256)/8;
 		g = (i1 * 256)/8;
@@ -88,15 +120,15 @@
 
 		while (more) {
 			if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) {
-				SAY("ERROR:  bad m reached\n");
+				SAM("ERROR:  bad m reached\n");
 				return;
 			}
 		if (PAGE_SIZE < n) {
-			SAY("ERROR:  bad n reached\n"); return;
+			SAM("ERROR:  bad n reached\n"); return;
 		}
 
 		if (0 > more) {
-			SAY("ERROR:  internal fault\n");
+			SAM("ERROR:  internal fault\n");
 			return;
 		}
 
@@ -117,10 +149,6 @@
 		}
 	}
 }
-
-JOT(8, "%i=total\n", total);
-if (total != peasycap->width * peasycap->height)
-	SAY("ERROR: wrong number of bytes written:  %i\n", total);
 return;
 }
 /*****************************************************************************/
@@ -157,35 +185,35 @@
 		printf("%6i, ", i2);  printf("%6i\n};\n", i2);
 		}
 	}
-return(0);
+return 0;
 }
 -----------------------------------------------------------------------------*/
 int tones[2048] = {
-     0,     0,   502,   502,  1004,  1004,  1505,  1505,  2005,  2005,
-  2503,  2503,  2998,  2998,  3491,  3491,  3980,  3980,  4466,  4466,
-  4948,  4948,  5424,  5424,  5896,  5896,  6362,  6362,  6822,  6822,
-  7276,  7276,  7723,  7723,  8162,  8162,  8594,  8594,  9018,  9018,
-  9434,  9434,  9840,  9840, 10237, 10237, 10625, 10625, 11002, 11002,
- 11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728,
- 13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155,
- 14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249,
- 15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985,
- 16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346,
- 16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323,
- 16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917,
- 15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136,
- 14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001,
- 13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536,
- 12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777,
- 10393, 10393, 10000, 10000,  9597,  9597,  9185,  9185,  8765,  8765,
-  8336,  8336,  7900,  7900,  7456,  7456,  7005,  7005,  6547,  6547,
-  6083,  6083,  5614,  5614,  5139,  5139,  4659,  4659,  4175,  4175,
-  3687,  3687,  3196,  3196,  2701,  2701,  2204,  2204,  1705,  1705,
-  1205,  1205,   703,   703,   201,   201,  -301,  -301,  -803,  -803,
- -1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294,
- -3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708,
- -6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988,
- -8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079,
+0,     0,   502,   502,  1004,  1004,  1505,  1505,  2005,  2005,
+2503,  2503,  2998,  2998,  3491,  3491,  3980,  3980,  4466,  4466,
+4948,  4948,  5424,  5424,  5896,  5896,  6362,  6362,  6822,  6822,
+7276,  7276,  7723,  7723,  8162,  8162,  8594,  8594,  9018,  9018,
+9434,  9434,  9840,  9840, 10237, 10237, 10625, 10625, 11002, 11002,
+11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728,
+13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155,
+14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249,
+15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985,
+16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346,
+16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323,
+16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917,
+15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136,
+14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001,
+13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536,
+12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777,
+10393, 10393, 10000, 10000,  9597,  9597,  9185,  9185,  8765,  8765,
+8336,  8336,  7900,  7900,  7456,  7456,  7005,  7005,  6547,  6547,
+6083,  6083,  5614,  5614,  5139,  5139,  4659,  4659,  4175,  4175,
+3687,  3687,  3196,  3196,  2701,  2701,  2204,  2204,  1705,  1705,
+1205,  1205,   703,   703,   201,   201,  -301,  -301,  -803,  -803,
+-1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294,
+-3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708,
+-6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988,
+-8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079,
 -10471, -10471, -10853, -10853, -11224, -11224, -11585, -11585, -11935, -11935,
 -12273, -12273, -12600, -12600, -12916, -12916, -13219, -13219, -13510, -13510,
 -13788, -13788, -14053, -14053, -14304, -14304, -14543, -14543, -14767, -14767,
@@ -198,35 +226,35 @@
 -14353, -14353, -14104, -14104, -13842, -13842, -13566, -13566, -13278, -13278,
 -12977, -12977, -12665, -12665, -12340, -12340, -12003, -12003, -11656, -11656,
 -11297, -11297, -10928, -10928, -10548, -10548, -10159, -10159, -9759, -9759,
- -9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634,
- -7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329,
- -4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900,
- -2404, -2404, -1905, -1905, -1405, -1405,  -904,  -904,  -402,  -402,
-   100,   100,   603,   603,  1105,  1105,  1605,  1605,  2105,  2105,
-  2602,  2602,  3097,  3097,  3589,  3589,  4078,  4078,  4563,  4563,
-  5043,  5043,  5519,  5519,  5990,  5990,  6455,  6455,  6914,  6914,
-  7366,  7366,  7811,  7811,  8249,  8249,  8680,  8680,  9102,  9102,
-  9516,  9516,  9920,  9920, 10315, 10315, 10701, 10701, 11077, 11077,
- 11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791,
- 13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205,
- 14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286,
- 15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007,
- 16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353,
- 16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314,
- 16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892,
- 15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098,
- 14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948,
- 13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471,
- 12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701,
- 10315, 10315,  9920,  9920,  9516,  9516,  9102,  9102,  8680,  8680,
-  8249,  8249,  7811,  7811,  7366,  7366,  6914,  6914,  6455,  6455,
-  5990,  5990,  5519,  5519,  5043,  5043,  4563,  4563,  4078,  4078,
-  3589,  3589,  3097,  3097,  2602,  2602,  2105,  2105,  1605,  1605,
-  1105,  1105,   603,   603,   100,   100,  -402,  -402,  -904,  -904,
- -1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393,
- -3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802,
- -6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075,
- -8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159,
+-9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634,
+-7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329,
+-4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900,
+-2404, -2404, -1905, -1905, -1405, -1405,  -904,  -904,  -402,  -402,
+100,   100,   603,   603,  1105,  1105,  1605,  1605,  2105,  2105,
+2602,  2602,  3097,  3097,  3589,  3589,  4078,  4078,  4563,  4563,
+5043,  5043,  5519,  5519,  5990,  5990,  6455,  6455,  6914,  6914,
+7366,  7366,  7811,  7811,  8249,  8249,  8680,  8680,  9102,  9102,
+9516,  9516,  9920,  9920, 10315, 10315, 10701, 10701, 11077, 11077,
+11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791,
+13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205,
+14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286,
+15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007,
+16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353,
+16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314,
+16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892,
+15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098,
+14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948,
+13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471,
+12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701,
+10315, 10315,  9920,  9920,  9516,  9516,  9102,  9102,  8680,  8680,
+8249,  8249,  7811,  7811,  7366,  7366,  6914,  6914,  6455,  6455,
+5990,  5990,  5519,  5519,  5043,  5043,  4563,  4563,  4078,  4078,
+3589,  3589,  3097,  3097,  2602,  2602,  2105,  2105,  1605,  1605,
+1105,  1105,   603,   603,   100,   100,  -402,  -402,  -904,  -904,
+-1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393,
+-3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802,
+-6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075,
+-8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159,
 -10548, -10548, -10928, -10928, -11297, -11297, -11656, -11656, -12003, -12003,
 -12340, -12340, -12665, -12665, -12977, -12977, -13278, -13278, -13566, -13566,
 -13842, -13842, -14104, -14104, -14353, -14353, -14589, -14589, -14810, -14810,
@@ -239,35 +267,35 @@
 -14304, -14304, -14053, -14053, -13788, -13788, -13510, -13510, -13219, -13219,
 -12916, -12916, -12600, -12600, -12273, -12273, -11935, -11935, -11585, -11585,
 -11224, -11224, -10853, -10853, -10471, -10471, -10079, -10079, -9679, -9679,
- -9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545,
- -7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234,
- -4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801,
- -2304, -2304, -1805, -1805, -1305, -1305,  -803,  -803,  -301,  -301,
-   201,   201,   703,   703,  1205,  1205,  1705,  1705,  2204,  2204,
-  2701,  2701,  3196,  3196,  3687,  3687,  4175,  4175,  4659,  4659,
-  5139,  5139,  5614,  5614,  6083,  6083,  6547,  6547,  7005,  7005,
-  7456,  7456,  7900,  7900,  8336,  8336,  8765,  8765,  9185,  9185,
-  9597,  9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150,
- 11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854,
- 13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255,
- 14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322,
- 15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028,
- 16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359,
- 16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305,
- 16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868,
- 15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058,
- 14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895,
- 13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406,
- 12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625,
- 10237, 10237,  9840,  9840,  9434,  9434,  9018,  9018,  8594,  8594,
-  8162,  8162,  7723,  7723,  7276,  7276,  6822,  6822,  6362,  6362,
-  5896,  5896,  5424,  5424,  4948,  4948,  4466,  4466,  3980,  3980,
-  3491,  3491,  2998,  2998,  2503,  2503,  2005,  2005,  1505,  1505,
-  1004,  1004,   502,   502,     0,     0,  -502,  -502, -1004, -1004,
- -1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491,
- -3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896,
- -6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162,
- -8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237,
+-9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545,
+-7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234,
+-4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801,
+-2304, -2304, -1805, -1805, -1305, -1305,  -803,  -803,  -301,  -301,
+201,   201,   703,   703,  1205,  1205,  1705,  1705,  2204,  2204,
+2701,  2701,  3196,  3196,  3687,  3687,  4175,  4175,  4659,  4659,
+5139,  5139,  5614,  5614,  6083,  6083,  6547,  6547,  7005,  7005,
+7456,  7456,  7900,  7900,  8336,  8336,  8765,  8765,  9185,  9185,
+9597,  9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150,
+11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854,
+13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255,
+14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322,
+15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028,
+16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359,
+16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305,
+16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868,
+15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058,
+14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895,
+13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406,
+12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625,
+10237, 10237,  9840,  9840,  9434,  9434,  9018,  9018,  8594,  8594,
+8162,  8162,  7723,  7723,  7276,  7276,  6822,  6822,  6362,  6362,
+5896,  5896,  5424,  5424,  4948,  4948,  4466,  4466,  3980,  3980,
+3491,  3491,  2998,  2998,  2503,  2503,  2005,  2005,  1505,  1505,
+1004,  1004,   502,   502,     0,     0,  -502,  -502, -1004, -1004,
+-1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491,
+-3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896,
+-6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162,
+-8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237,
 -10625, -10625, -11002, -11002, -11370, -11370, -11726, -11726, -12072, -12072,
 -12406, -12406, -12728, -12728, -13038, -13038, -13337, -13337, -13622, -13622,
 -13895, -13895, -14155, -14155, -14401, -14401, -14634, -14634, -14853, -14853,
@@ -280,35 +308,35 @@
 -14255, -14255, -14001, -14001, -13733, -13733, -13452, -13452, -13159, -13159,
 -12854, -12854, -12536, -12536, -12207, -12207, -11866, -11866, -11513, -11513,
 -11150, -11150, -10777, -10777, -10393, -10393, -10000, -10000, -9597, -9597,
- -9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456,
- -7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139,
- -4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701,
- -2204, -2204, -1705, -1705, -1205, -1205,  -703,  -703,  -201,  -201,
-   301,   301,   803,   803,  1305,  1305,  1805,  1805,  2304,  2304,
-  2801,  2801,  3294,  3294,  3785,  3785,  4272,  4272,  4756,  4756,
-  5234,  5234,  5708,  5708,  6176,  6176,  6639,  6639,  7095,  7095,
-  7545,  7545,  7988,  7988,  8423,  8423,  8850,  8850,  9268,  9268,
-  9679,  9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224,
- 11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916,
- 13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304,
- 14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357,
- 15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049,
- 16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364,
- 16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294,
- 16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842,
- 15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018,
- 14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842,
- 13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340,
- 12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548,
- 10159, 10159,  9759,  9759,  9351,  9351,  8934,  8934,  8509,  8509,
-  8075,  8075,  7634,  7634,  7186,  7186,  6731,  6731,  6269,  6269,
-  5802,  5802,  5329,  5329,  4852,  4852,  4369,  4369,  3883,  3883,
-  3393,  3393,  2900,  2900,  2404,  2404,  1905,  1905,  1405,  1405,
-   904,   904,   402,   402,  -100,  -100,  -603,  -603, -1105, -1105,
- -1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589,
- -4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990,
- -6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249,
- -8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315,
+-9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456,
+-7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139,
+-4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701,
+-2204, -2204, -1705, -1705, -1205, -1205,  -703,  -703,  -201,  -201,
+301,   301,   803,   803,  1305,  1305,  1805,  1805,  2304,  2304,
+2801,  2801,  3294,  3294,  3785,  3785,  4272,  4272,  4756,  4756,
+5234,  5234,  5708,  5708,  6176,  6176,  6639,  6639,  7095,  7095,
+7545,  7545,  7988,  7988,  8423,  8423,  8850,  8850,  9268,  9268,
+9679,  9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224,
+11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916,
+13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304,
+14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357,
+15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049,
+16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364,
+16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294,
+16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842,
+15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018,
+14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842,
+13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340,
+12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548,
+10159, 10159,  9759,  9759,  9351,  9351,  8934,  8934,  8509,  8509,
+8075,  8075,  7634,  7634,  7186,  7186,  6731,  6731,  6269,  6269,
+5802,  5802,  5329,  5329,  4852,  4852,  4369,  4369,  3883,  3883,
+3393,  3393,  2900,  2900,  2404,  2404,  1905,  1905,  1405,  1405,
+904,   904,   402,   402,  -100,  -100,  -603,  -603, -1105, -1105,
+-1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589,
+-4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990,
+-6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249,
+-8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315,
 -10701, -10701, -11077, -11077, -11442, -11442, -11796, -11796, -12139, -12139,
 -12471, -12471, -12791, -12791, -13099, -13099, -13395, -13395, -13678, -13678,
 -13948, -13948, -14205, -14205, -14449, -14449, -14679, -14679, -14895, -14895,
@@ -321,35 +349,35 @@
 -14205, -14205, -13948, -13948, -13678, -13678, -13395, -13395, -13099, -13099,
 -12791, -12791, -12471, -12471, -12139, -12139, -11796, -11796, -11442, -11442,
 -11077, -11077, -10701, -10701, -10315, -10315, -9920, -9920, -9516, -9516,
- -9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366,
- -6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043,
- -4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602,
- -2105, -2105, -1605, -1605, -1105, -1105,  -603,  -603,  -100,  -100,
-   402,   402,   904,   904,  1405,  1405,  1905,  1905,  2404,  2404,
-  2900,  2900,  3393,  3393,  3883,  3883,  4369,  4369,  4852,  4852,
-  5329,  5329,  5802,  5802,  6269,  6269,  6731,  6731,  7186,  7186,
-  7634,  7634,  8075,  8075,  8509,  8509,  8934,  8934,  9351,  9351,
-  9759,  9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297,
- 11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977,
- 13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353,
- 14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392,
- 15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069,
- 16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368,
- 16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284,
- 16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817,
- 15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978,
- 14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788,
- 13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273,
- 11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471,
- 10079, 10079,  9679,  9679,  9268,  9268,  8850,  8850,  8423,  8423,
-  7988,  7988,  7545,  7545,  7095,  7095,  6639,  6639,  6176,  6176,
-  5708,  5708,  5234,  5234,  4756,  4756,  4272,  4272,  3785,  3785,
-  3294,  3294,  2801,  2801,  2304,  2304,  1805,  1805,  1305,  1305,
-   803,   803,   301,   301,  -201,  -201,  -703,  -703, -1205, -1205,
- -1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687,
- -4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083,
- -6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336,
- -8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393,
+-9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366,
+-6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043,
+-4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602,
+-2105, -2105, -1605, -1605, -1105, -1105,  -603,  -603,  -100,  -100,
+402,   402,   904,   904,  1405,  1405,  1905,  1905,  2404,  2404,
+2900,  2900,  3393,  3393,  3883,  3883,  4369,  4369,  4852,  4852,
+5329,  5329,  5802,  5802,  6269,  6269,  6731,  6731,  7186,  7186,
+7634,  7634,  8075,  8075,  8509,  8509,  8934,  8934,  9351,  9351,
+9759,  9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297,
+11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977,
+13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353,
+14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392,
+15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069,
+16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368,
+16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284,
+16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817,
+15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978,
+14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788,
+13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273,
+11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471,
+10079, 10079,  9679,  9679,  9268,  9268,  8850,  8850,  8423,  8423,
+7988,  7988,  7545,  7545,  7095,  7095,  6639,  6639,  6176,  6176,
+5708,  5708,  5234,  5234,  4756,  4756,  4272,  4272,  3785,  3785,
+3294,  3294,  2801,  2801,  2304,  2304,  1805,  1805,  1305,  1305,
+803,   803,   301,   301,  -201,  -201,  -703,  -703, -1205, -1205,
+-1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687,
+-4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083,
+-6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336,
+-8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393,
 -10777, -10777, -11150, -11150, -11513, -11513, -11866, -11866, -12207, -12207,
 -12536, -12536, -12854, -12854, -13159, -13159, -13452, -13452, -13733, -13733,
 -14001, -14001, -14255, -14255, -14496, -14496, -14723, -14723, -14937, -14937,
@@ -362,10 +390,10 @@
 -14155, -14155, -13895, -13895, -13622, -13622, -13337, -13337, -13038, -13038,
 -12728, -12728, -12406, -12406, -12072, -12072, -11726, -11726, -11370, -11370,
 -11002, -11002, -10625, -10625, -10237, -10237, -9840, -9840, -9434, -9434,
- -9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276,
- -6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948,
- -4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503,
- -2005, -2005, -1505, -1505, -1004, -1004,  -502,  -502
+-9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276,
+-6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948,
+-4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503,
+-2005, -2005, -1505, -1505, -1004, -1004,  -502,  -502
 };
 /*****************************************************************************/
 void
@@ -375,10 +403,12 @@
 unsigned char *p2;
 struct data_buffer *paudio_buffer;
 
-JOT(8, "%i=audio_fill\n", audio_fill);
-
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return;
+}
+JOM(8, "%i=audio_fill\n", audio_fill);
 paudio_buffer = &peasycap->audio_buffer[audio_fill];
-
 p2 = (unsigned char *)(paudio_buffer->pgo);
 for (i1 = 0;  i1 < PAGE_SIZE;  i1 += 4, p2 += 4) {
 	*p2       = (unsigned char) (0x00FF & tones[i1/2]);
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index ef7fbf8..2babb03 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -89,7 +89,7 @@
 
 /* Use our own dbg macro */
 #define dbg_info(dev, format, arg...) do \
-    { if (debug) dev_info(dev , format , ## arg); } while (0)
+	{ if (debug) dev_info(dev , format , ## arg); } while (0)
 
 #define alphatrack_ocmd_info(dev, cmd, format, arg...)
 
@@ -769,7 +769,7 @@
 	}
 
 	dev->write_buffer =
-	    kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL);
+	    kmalloc(true_size * sizeof(struct alphatrack_ocmd), GFP_KERNEL);
 
 	if (!dev->write_buffer) {
 		dev_err(&intf->dev, "Couldn't allocate write_buffer\n");
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c
index 20d5098..197b3fb 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c
@@ -64,7 +64,7 @@
 int numofmsgbuf = 0;
 
 // Global variable to indicate that all provisioning data is sent to DSP
-//BOOLEAN fProvComplete;
+//bool fProvComplete;
 
 //
 // Table of entry-point routines for char device
@@ -622,10 +622,10 @@
         memcpy(get_stat_data.eui64, info->eui64, EUISZ);
 
             if (info->ProgConStat != 0xFF) {
-                ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (PUCHAR)&ledStat, FT1000_MAG_DSP_LED_INDX);
+                ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX);
                 get_stat_data.LedStat = ntohs(ledStat);
                 DEBUG("FT1000:ft1000_ChIoctl: LedStat = 0x%x\n", get_stat_data.LedStat);
-                ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (PUCHAR)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
+                ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
                 get_stat_data.ConStat = ntohs(conStat);
                 DEBUG("FT1000:ft1000_ChIoctl: ConStat = 0x%x\n", get_stat_data.ConStat);
             }
@@ -652,12 +652,12 @@
         {
             IOCTL_DPRAM_BLK *dpram_data;
             //IOCTL_DPRAM_COMMAND dpram_command;
-            USHORT qtype;
-            USHORT msgsz;
+            u16 qtype;
+            u16 msgsz;
 		struct pseudo_hdr *ppseudo_hdr;
-            PUSHORT pmsg;
-            USHORT total_len;
-            USHORT app_index;
+            u16 *pmsg;
+            u16 total_len;
+            u16 app_index;
             u16 status;
 
             //DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_SET_DPRAM called\n");
@@ -765,8 +765,8 @@
                         // Make sure we are within the limits of the slow queue memory limitation
                         if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) {
                             // Need to put sequence number plus new checksum for message
-                            //pmsg = (PUSHORT)&dpram_command.dpram_blk.pseudohdr;
-                            pmsg = (PUSHORT)&dpram_data->pseudohdr;
+                            //pmsg = (u16 *)&dpram_command.dpram_blk.pseudohdr;
+                            pmsg = (u16 *)&dpram_data->pseudohdr;
 				ppseudo_hdr = (struct pseudo_hdr *)pmsg;
                             total_len = msgsz+2;
                             if (total_len & 0x1) {
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c
index 4dd456f..e4905ad 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c
@@ -123,11 +123,11 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static ULONG check_usb_db (struct ft1000_device *ft1000dev)
+static u32 check_usb_db (struct ft1000_device *ft1000dev)
 {
    int               loopcnt;
-   USHORT            temp;
-   ULONG             status;
+   u16            temp;
+   u32             status;
 
    loopcnt = 0;
    while (loopcnt < 10)
@@ -190,7 +190,7 @@
 // Function:    get_handshake
 //
 // Parameters:  struct ft1000_device  - device structure
-//              USHORT expected_value - the handshake value expected
+//              u16 expected_value - the handshake value expected
 //
 // Returns:     handshakevalue - success
 //              HANDSHAKE_TIMEOUT_VALUE - failure
@@ -200,11 +200,11 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_value)
+static u16 get_handshake(struct ft1000_device *ft1000dev, u16 expected_value)
 {
-   USHORT            handshake;
+   u16            handshake;
    int               loopcnt;
-   ULONG             status=0;
+   u32             status=0;
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
 
    loopcnt = 0;
@@ -228,7 +228,7 @@
                    status = ft1000_write_register (ft1000dev,  FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
                }
 
-                status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
+                status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1);
                 //DEBUG("get_handshake: handshake is %x\n", tempx);
                 handshake = ntohs(handshake);
                 //DEBUG("get_handshake: after swap, handshake is %x\n", handshake);
@@ -259,7 +259,7 @@
 // Function:    put_handshake
 //
 // Parameters:  struct ft1000_device  - device structure
-//              USHORT handshake_value - handshake to be written
+//              u16 handshake_value - handshake to be written
 //
 // Returns:     none
 //
@@ -269,30 +269,30 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static void put_handshake(struct ft1000_device *ft1000dev,USHORT handshake_value)
+static void put_handshake(struct ft1000_device *ft1000dev,u16 handshake_value)
 {
-    ULONG tempx;
-    USHORT tempword;
-    ULONG status;
+    u32 tempx;
+    u16 tempword;
+    u32 status;
 
 
 
-        tempx = (ULONG)handshake_value;
+        tempx = (u32)handshake_value;
         tempx = ntohl(tempx);
 
-        tempword = (USHORT)(tempx & 0xffff);
+        tempword = (u16)(tempx & 0xffff);
         status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 0);
-        tempword = (USHORT)(tempx >> 16);
+        tempword = (u16)(tempx >> 16);
         status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 1);
         status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL);
 }
 
-static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected_value)
+static u16 get_handshake_usb(struct ft1000_device *ft1000dev, u16 expected_value)
 {
-   USHORT            handshake;
+   u16            handshake;
    int               loopcnt;
-   USHORT            temp;
-   ULONG             status=0;
+   u16            temp;
+   u32             status=0;
 
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
    loopcnt = 0;
@@ -300,10 +300,10 @@
    while (loopcnt < 100)
    {
        if (pft1000info->usbboot == 2) {
-           status = ft1000_read_dpram32 (ft1000dev, 0, (PUCHAR)&(pft1000info->tempbuf[0]), 64);
+           status = ft1000_read_dpram32 (ft1000dev, 0, (u8 *)&(pft1000info->tempbuf[0]), 64);
            for (temp=0; temp<16; temp++)
                DEBUG("tempbuf %d = 0x%x\n", temp, pft1000info->tempbuf[temp]);
-           status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
+           status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1);
            DEBUG("handshake from read_dpram16 = 0x%x\n", handshake);
            if (pft1000info->dspalive == pft1000info->tempbuf[6])
                handshake = 0;
@@ -313,7 +313,7 @@
            }
        }
        else {
-           status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
+           status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1);
        }
        loopcnt++;
        msleep(10);
@@ -327,7 +327,7 @@
    return HANDSHAKE_TIMEOUT_VALUE;
 }
 
-static void put_handshake_usb(struct ft1000_device *ft1000dev,USHORT handshake_value)
+static void put_handshake_usb(struct ft1000_device *ft1000dev,u16 handshake_value)
 {
    int i;
 
@@ -346,44 +346,44 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static USHORT get_request_type(struct ft1000_device *ft1000dev)
+static u16 get_request_type(struct ft1000_device *ft1000dev)
 {
-   USHORT   request_type;
-   ULONG    status;
-   USHORT   tempword;
-   ULONG    tempx;
+   u16   request_type;
+   u32    status;
+   u16   tempword;
+   u32    tempx;
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
 
    if ( pft1000info->bootmode == 1)
    {
-       status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx);
+       status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx);
        tempx = ntohl(tempx);
    }
    else
    {
        tempx = 0;
 
-       status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1);
+       status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1);
        tempx |= (tempword << 16);
        tempx = ntohl(tempx);
    }
-   request_type = (USHORT)tempx;
+   request_type = (u16)tempx;
 
    //DEBUG("get_request_type: request_type is %x\n", request_type);
    return request_type;
 
 }
 
-static USHORT get_request_type_usb(struct ft1000_device *ft1000dev)
+static u16 get_request_type_usb(struct ft1000_device *ft1000dev)
 {
-   USHORT   request_type;
-   ULONG    status;
-   USHORT   tempword;
-   ULONG    tempx;
+   u16   request_type;
+   u32    status;
+   u16   tempword;
+   u32    tempx;
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
    if ( pft1000info->bootmode == 1)
    {
-       status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx);
+       status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx);
        tempx = ntohl(tempx);
    }
    else
@@ -394,12 +394,12 @@
        }
        else {
           tempx = 0;
-          status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1);
+          status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1);
        }
        tempx |= (tempword << 16);
        tempx = ntohl(tempx);
    }
-   request_type = (USHORT)tempx;
+   request_type = (u16)tempx;
 
    //DEBUG("get_request_type: request_type is %x\n", request_type);
    return request_type;
@@ -420,22 +420,22 @@
 //---------------------------------------------------------------------------
 static long get_request_value(struct ft1000_device *ft1000dev)
 {
-   ULONG     value;
-   USHORT   tempword;
-   ULONG    status;
+   u32     value;
+   u16   tempword;
+   u32    status;
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
 
 
        if ( pft1000info->bootmode == 1)
        {
-	   status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&value);
+	   status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&value);
 	   value = ntohl(value);
        }
        else
        {
-	   status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 0);
+	   status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0);
 	   value = tempword;
-           status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
+           status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1);
 	   value |= (tempword << 16);
 	   value = ntohl(value);
        }
@@ -449,9 +449,9 @@
 #if 0
 static long get_request_value_usb(struct ft1000_device *ft1000dev)
 {
-   ULONG     value;
-   USHORT   tempword;
-   ULONG    status;
+   u32     value;
+   u16   tempword;
+   u32    status;
    struct ft1000_info * pft1000info = netdev_priv(ft1000dev->net);
 
        if (pft1000info->usbboot == 2) {
@@ -460,7 +460,7 @@
        }
        else {
           value = 0;
-          status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
+          status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1);
        }
 
        value |= (tempword << 16);
@@ -490,11 +490,11 @@
 //---------------------------------------------------------------------------
 static void put_request_value(struct ft1000_device *ft1000dev, long lvalue)
 {
-   ULONG    tempx;
-   ULONG    status;
+   u32    tempx;
+   u32    status;
 
        tempx = ntohl(lvalue);
-       status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempx);
+       status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempx);
 
 
 
@@ -516,10 +516,10 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static USHORT hdr_checksum(struct pseudo_hdr *pHdr)
+static u16 hdr_checksum(struct pseudo_hdr *pHdr)
 {
-   USHORT   *usPtr = (USHORT *)pHdr;
-   USHORT   chksum;
+   u16   *usPtr = (u16 *)pHdr;
+   u16   chksum;
 
 
   chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
@@ -533,8 +533,8 @@
 // Function:    write_blk
 //
 // Parameters:  struct ft1000_device  - device structure
-//              USHORT **pUsFile - DSP image file pointer in USHORT
-//              UCHAR  **pUcFile - DSP image file pointer in UCHAR
+//              u16 **pUsFile - DSP image file pointer in u16
+//              u8  **pUcFile - DSP image file pointer in u8
 //              long   word_length - lenght of the buffer to be written
 //                                   to DPRAM
 //
@@ -546,20 +546,20 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
+static u32 write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length)
 {
-   ULONG Status = STATUS_SUCCESS;
-   USHORT dpram;
+   u32 Status = STATUS_SUCCESS;
+   u16 dpram;
    long temp_word_length;
    int loopcnt, i, j;
-   USHORT *pTempFile;
-   USHORT tempword;
-   USHORT tempbuffer[64];
-   USHORT resultbuffer[64];
+   u16 *pTempFile;
+   u16 tempword;
+   u16 tempbuffer[64];
+   u16 resultbuffer[64];
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
 
    //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
-   dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
+   dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
    tempword = *(*pUsFile);
    (*pUsFile)++;
    Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
@@ -569,7 +569,7 @@
 
    *pUcFile = *pUcFile + 4;
    word_length--;
-   tempword = (USHORT)word_length;
+   tempword = (u16)word_length;
    word_length = (word_length / 16) + 1;
    pTempFile = *pUsFile;
    temp_word_length = word_length;
@@ -602,24 +602,24 @@
 	      if (pft1000info->bootmode == 0)
 	      {
 		 if (dpram >= 0x3F4)
-                     Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 8);
+                     Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 8);
 	         else
-                    Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
+                    Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64);
 	      }
 	      else
 	      {
                  for (j=0; j<10; j++)
                  {
-                   Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
+                   Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64);
 		   if (Status == STATUS_SUCCESS)
 		   {
 		       // Work around for ASIC bit stuffing problem.
 		       if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
 		       {
-      		           Status = ft1000_write_dpram32(ft1000dev, dpram+12, (PUCHAR)&tempbuffer[24], 64);
+      		           Status = ft1000_write_dpram32(ft1000dev, dpram+12, (u8 *)&tempbuffer[24], 64);
 		       }
     		       // Let's check the data written
-	    	       Status = ft1000_read_dpram32 (ft1000dev, dpram, (PUCHAR)&resultbuffer[0], 64);
+	    	       Status = ft1000_read_dpram32 (ft1000dev, dpram, (u8 *)&resultbuffer[0], 64);
 		       if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
 		       {
 		           for (i=0; i<28; i++)
@@ -633,7 +633,7 @@
 				   break;
 				}
 			   }
-   			   Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (PUCHAR)&resultbuffer[0], 64);
+   			   Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (u8 *)&resultbuffer[0], 64);
 		           for (i=0; i<16; i++)
 		           {
     			       if (resultbuffer[i] != tempbuffer[i+24])
@@ -689,8 +689,8 @@
 // Function:    write_blk_fifo
 //
 // Parameters:  struct ft1000_device  - device structure
-//              USHORT **pUsFile - DSP image file pointer in USHORT
-//              UCHAR  **pUcFile - DSP image file pointer in UCHAR
+//              u16 **pUsFile - DSP image file pointer in u16
+//              u8  **pUcFile - DSP image file pointer in u8
 //              long   word_length - lenght of the buffer to be written
 //                                   to DPRAM
 //
@@ -702,9 +702,9 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
+static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length)
 {
-   ULONG Status = STATUS_SUCCESS;
+   u32 Status = STATUS_SUCCESS;
    int byte_length;
    long aligncnt;
 
@@ -770,36 +770,36 @@
 //  Returns:    status                  - return code
 //---------------------------------------------------------------------------
 
-u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG  FileLength)
+u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32  FileLength)
 {
    u16                     Status = STATUS_SUCCESS;
-   UINT                    uiState;
-   USHORT                  handshake;
+   u32                    uiState;
+   u16                  handshake;
 	struct pseudo_hdr *pHdr;
-   USHORT                  usHdrLength;
+   u16                  usHdrLength;
    long                    word_length;
-   USHORT                  request;
-   USHORT                  temp;
-   USHORT                  tempword;
+   u16                  request;
+   u16                  temp;
+   u16                  tempword;
 
 	struct dsp_file_hdr *pFileHdr5;
 	struct dsp_image_info *pDspImageInfoV6 = NULL;
    long                    requested_version;
-   BOOLEAN                 bGoodVersion;
+   bool                 bGoodVersion;
 	struct drv_msg *pMailBoxData;
-   USHORT                  *pUsData = NULL;
-   USHORT                  *pUsFile = NULL;
-   UCHAR                   *pUcFile = NULL;
-   UCHAR                   *pBootEnd = NULL, *pCodeEnd= NULL;
+   u16                  *pUsData = NULL;
+   u16                  *pUsFile = NULL;
+   u8                   *pUcFile = NULL;
+   u8                   *pBootEnd = NULL, *pCodeEnd= NULL;
    int                     imageN;
    long                    loader_code_address, loader_code_size = 0;
    long                    run_address = 0, run_size = 0;
 
-   ULONG                   templong;
-   ULONG                   image_chksum = 0;
+   u32                   templong;
+   u32                   image_chksum = 0;
 
-   USHORT                  dpram = 0;
-   PUCHAR                  pbuffer;
+   u16                  dpram = 0;
+   u8 *pbuffer;
 	struct prov_record *pprov_record;
 	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
 
@@ -820,10 +820,10 @@
 
    ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK);
 
-      pUsFile = (USHORT *)(pFileStart + pFileHdr5->loader_offset);
-      pUcFile = (UCHAR *)(pFileStart + pFileHdr5->loader_offset);
+      pUsFile = (u16 *)(pFileStart + pFileHdr5->loader_offset);
+      pUcFile = (u8 *)(pFileStart + pFileHdr5->loader_offset);
 
-      pBootEnd = (UCHAR *)(pFileStart + pFileHdr5->loader_code_end);
+      pBootEnd = (u8 *)(pFileStart + pFileHdr5->loader_code_end);
 
       loader_code_address = pFileHdr5->loader_code_address;
       loader_code_size = pFileHdr5->loader_code_size;
@@ -878,8 +878,8 @@
             case  REQUEST_DONE_BL:
                DEBUG("FT1000:REQUEST_DONE_BL\n");
                /* Reposition ptrs to beginning of code section */
-               pUsFile = (USHORT *)(pBootEnd);
-               pUcFile = (UCHAR *)(pBootEnd);
+               pUsFile = (u16 *)(pBootEnd);
+               pUcFile = (u8 *)(pBootEnd);
                //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile);
                //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile);
                uiState = STATE_CODE_DWNLD;
@@ -909,7 +909,7 @@
                /*
                 * Position ASIC DPRAM auto-increment pointer.
                 */
-				    dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
+				    dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
 					if (word_length & 0x1)
 						word_length++;
 					word_length = word_length / 2;
@@ -988,8 +988,8 @@
             case  REQUEST_DONE_CL:
                pft1000info->usbboot = 3;
                /* Reposition ptrs to beginning of provisioning section */
-                  pUsFile = (USHORT *)(pFileStart + pFileHdr5->commands_offset);
-                  pUcFile = (UCHAR *)(pFileStart + pFileHdr5->commands_offset);
+                  pUsFile = (u16 *)(pFileStart + pFileHdr5->commands_offset);
+                  pUcFile = (u8 *)(pFileStart + pFileHdr5->commands_offset);
                uiState = STATE_DONE_DWNLD;
                break;
             case  REQUEST_CODE_SEGMENT:
@@ -1027,7 +1027,7 @@
                /*
                 * Position ASIC DPRAM auto-increment pointer.
                 */
-		   dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
+		   dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
 		   if (word_length & 0x1)
 			word_length++;
 		   word_length = word_length / 2;
@@ -1053,8 +1053,8 @@
                 */
 
 
-                   pUsData = (USHORT *)&pMailBoxData->data[0];
-                   dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
+                   pUsData = (u16 *)&pMailBoxData->data[0];
+                   dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
                    if (word_length & 0x1)
                        word_length++;
 
@@ -1066,7 +1066,7 @@
 
                       templong = *pUsData++;
 					  templong |= (*pUsData++ << 16);
-                      Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong);
+                      Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong);
 
                }
                break;
@@ -1079,10 +1079,10 @@
                 * Position ASIC DPRAM auto-increment pointer.
                 */
 
-               pUsFile = (USHORT *)(pFileStart + pFileHdr5->version_data_offset);
+               pUsFile = (u16 *)(pFileStart + pFileHdr5->version_data_offset);
 
 
-                   dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
+                   dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
                    if (word_length & 0x1)
                        word_length++;
 
@@ -1095,7 +1095,7 @@
                       templong = ntohs(*pUsFile++);
 					  temp = ntohs(*pUsFile++);
 					  templong |= (temp << 16);
-                      Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong);
+                      Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong);
 
                }
                break;
@@ -1110,20 +1110,20 @@
                for (imageN = 0; imageN < pFileHdr5->nDspImages; imageN++)
                {
 
-                       temp = (USHORT)(pDspImageInfoV6->version);
+                       temp = (u16)(pDspImageInfoV6->version);
                        templong = temp;
-                       temp = (USHORT)(pDspImageInfoV6->version >> 16);
+                       temp = (u16)(pDspImageInfoV6->version >> 16);
                        templong |= (temp << 16);
-                   if (templong == (ULONG)requested_version)
+                   if (templong == (u32)requested_version)
                        {
                            bGoodVersion = TRUE;
                            DEBUG("FT1000:download: bGoodVersion is TRUE\n");
-                           pUsFile = (USHORT *)(pFileStart + pDspImageInfoV6->begin_offset);
-                           pUcFile = (UCHAR *)(pFileStart + pDspImageInfoV6->begin_offset);
-                           pCodeEnd = (UCHAR *)(pFileStart + pDspImageInfoV6->end_offset);
+                           pUsFile = (u16 *)(pFileStart + pDspImageInfoV6->begin_offset);
+                           pUcFile = (u8 *)(pFileStart + pDspImageInfoV6->begin_offset);
+                           pCodeEnd = (u8 *)(pFileStart + pDspImageInfoV6->end_offset);
                            run_address = pDspImageInfoV6->run_address;
                            run_size = pDspImageInfoV6->image_size;
-                           image_chksum = (ULONG)pDspImageInfoV6->checksum;
+                           image_chksum = (u32)pDspImageInfoV6->checksum;
                            break;
                         }
                         pDspImageInfoV6++;
@@ -1181,14 +1181,14 @@
             // Get buffer for provisioning data
 		pbuffer = kmalloc((usHdrLength + sizeof(struct pseudo_hdr)), GFP_ATOMIC);
             if (pbuffer) {
-		memcpy(pbuffer, (void *)pUcFile, (UINT)(usHdrLength + sizeof(struct pseudo_hdr)));
+		memcpy(pbuffer, (void *)pUcFile, (u32)(usHdrLength + sizeof(struct pseudo_hdr)));
                 // link provisioning data
 		pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC);
                 if (pprov_record) {
                     pprov_record->pprov_data = pbuffer;
                     list_add_tail (&pprov_record->list, &pft1000info->prov_list);
                     // Move to next entry if available
-			pUcFile = (UCHAR *)((unsigned long)pUcFile + (UINT)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
+			pUcFile = (u8 *)((unsigned long)pUcFile + (u32)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
                     if ( (unsigned long)(pUcFile) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) {
                        uiState = STATE_DONE_FILE;
                     }
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
index 5b89ee2..b41884e6 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
@@ -45,33 +45,6 @@
 
 #define MAX_RCV_LOOP   100
 
-/****************************************************************
- *     ft1000_control_complete
- ****************************************************************/
-static void ft1000_control_complete(struct urb *urb)
-{
-    struct ft1000_device *ft1000dev = (struct ft1000_device *)urb->context;
-
-    //DEBUG("FT1000_CONTROL_COMPLETE ENTERED\n");
-    if (ft1000dev == NULL )
-    {
-        DEBUG("NULL ft1000dev, failure\n");
-        return ;
-    }
-    else if ( ft1000dev->dev == NULL )
-    {
-        DEBUG("NULL ft1000dev->dev, failure\n");
-        return ;
-    }
-
-    if(waitqueue_active(&ft1000dev->control_wait))
-    {
-        wake_up(&ft1000dev->control_wait);
-    }
-
-    //DEBUG("FT1000_CONTROL_COMPLETE RETURNED\n");
-}
-
 //---------------------------------------------------------------------------
 // Function:    ft1000_control
 //
@@ -187,7 +160,7 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRegIndx)
+u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx)
 {
      u16 ret = STATUS_SUCCESS;
 
@@ -223,7 +196,7 @@
 //
 //---------------------------------------------------------------------------
 
-u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt)
+u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt)
 {
     u16 ret = STATUS_SUCCESS;
 
@@ -262,7 +235,7 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt)
+u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt)
 {
      u16 ret = STATUS_SUCCESS;
 
@@ -299,7 +272,7 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, u8 highlow)
+u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow)
 {
     u16 ret = STATUS_SUCCESS;
 
@@ -347,7 +320,7 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT value, u8 highlow)
+u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow)
 {
      u16 ret = STATUS_SUCCESS;
 
@@ -392,10 +365,10 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer)
+u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer)
 {
-    UCHAR buf[16];
-    USHORT pos;
+    u8 buf[16];
+    u16 pos;
     u16 ret = STATUS_SUCCESS;
 
     //DEBUG("fix_ft1000_read_dpram32: indx: %d  \n", indx);
@@ -441,14 +414,14 @@
 // Notes:
 //
 //---------------------------------------------------------------------------
-u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer)
+u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer)
 {
-    USHORT pos1;
-    USHORT pos2;
-    USHORT i;
-    UCHAR buf[32];
-    UCHAR resultbuffer[32];
-    PUCHAR pdata;
+    u16 pos1;
+    u16 pos2;
+    u16 i;
+    u8 buf[32];
+    u8 resultbuffer[32];
+    u8 *pdata;
     u16 ret  = STATUS_SUCCESS;
 
     //DEBUG("fix_ft1000_write_dpram32: Entered:\n");
@@ -472,7 +445,7 @@
         return ret;
     }
 
-    ret = ft1000_read_dpram32(ft1000dev, pos1, (PUCHAR)&resultbuffer[0], 16);
+    ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16);
     if (ret == STATUS_SUCCESS)
     {
         buffer = pdata;
@@ -487,8 +460,8 @@
 
     if (ret == STATUS_FAILURE)
     {
-        ret = ft1000_write_dpram32(ft1000dev, pos1, (PUCHAR)&tempbuffer[0], 16);
-        ret = ft1000_read_dpram32(ft1000dev, pos1, (PUCHAR)&resultbuffer[0], 16);
+        ret = ft1000_write_dpram32(ft1000dev, pos1, (u8 *)&tempbuffer[0], 16);
+        ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16);
         if (ret == STATUS_SUCCESS)
         {
             buffer = pdata;
@@ -518,10 +491,10 @@
 //
 //  Returns:    None
 //-----------------------------------------------------------------------
-static void card_reset_dsp (struct ft1000_device *ft1000dev, BOOLEAN value)
+static void card_reset_dsp (struct ft1000_device *ft1000dev, bool value)
 {
     u16 status = STATUS_SUCCESS;
-    USHORT tempword;
+    u16 tempword;
 
     status = ft1000_write_register (ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
     status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_CTRL);
@@ -620,8 +593,8 @@
 int dsp_reload(struct ft1000_device *ft1000dev)
 {
     u16 status;
-    USHORT tempword;
-    ULONG templong;
+    u16 tempword;
+    u32 templong;
 
 	struct ft1000_info *pft1000info;
 
@@ -648,7 +621,7 @@
     status = ft1000_write_register (ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
 
     // Let's check for FEFE
-    status = ft1000_read_dpram32 (ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, (PUCHAR)&templong, 4);
+    status = ft1000_read_dpram32 (ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, (u8 *)&templong, 4);
     DEBUG("templong (fefe) = 0x%8x\n", templong);
 
     // call codeloader
@@ -753,7 +726,7 @@
 
     // Initialize DSP heartbeat area to ho
     ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX);
-    ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (PCHAR)&tempword, FT1000_MAG_HI_HO_INDX);
+    ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *)&tempword, FT1000_MAG_HI_HO_INDX);
     DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword);
 
 
@@ -874,10 +847,7 @@
     pInfo->fCondResetPend = 0;
 	pInfo->usbboot = 0;
 	pInfo->dspalive = 0;
-	for (i=0;i<32 ;i++ )
-	{
-		pInfo->tempbuf[i] = 0;
-	}
+	memset(&pInfo->tempbuf[0], 0, sizeof(pInfo->tempbuf));
 
     INIT_LIST_HEAD(&pInfo->prov_list);
 
@@ -1026,178 +996,6 @@
     //DEBUG("Return from ft1000_usb_transmit_complete\n");
 }
 
-
-/****************************************************************
- *     ft1000_control
- ****************************************************************/
-static int ft1000_read_fifo_reg(struct ft1000_device *ft1000dev,unsigned int pipe,
-                          u8 request,
-                          u8 requesttype,
-                          u16 value,
-                          u16 index,
-                          void *data,
-                          u16 size,
-                          int timeout)
-{
-    u16 ret;
-
-    DECLARE_WAITQUEUE(wait, current);
-    struct urb *urb;
-    struct usb_ctrlrequest *dr;
-    int status;
-
-    if (ft1000dev == NULL )
-    {
-        DEBUG("NULL ft1000dev, failure\n");
-        return STATUS_FAILURE;
-    }
-    else if ( ft1000dev->dev == NULL )
-    {
-        DEBUG("NULL ft1000dev->dev, failure\n");
-        return STATUS_FAILURE;
-    }
-
-    spin_lock(&ft1000dev->device_lock);
-
-    if(in_interrupt())
-    {
-        spin_unlock(&ft1000dev->device_lock);
-        return -EBUSY;
-    }
-
-    urb = usb_alloc_urb(0, GFP_KERNEL);
-    dr = kmalloc(sizeof(struct usb_ctrlrequest), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
-
-    if(!urb || !dr)
-    {
-	kfree(dr);
-	usb_free_urb(urb);
-        spin_unlock(&ft1000dev->device_lock);
-        return -ENOMEM;
-    }
-
-
-
-    dr->bRequestType = requesttype;
-    dr->bRequest = request;
-    dr->wValue = value;
-    dr->wIndex = index;
-    dr->wLength = size;
-
-    usb_fill_control_urb(urb, ft1000dev->dev, pipe, (char*)dr, (void*)data, size, (void *)ft1000_control_complete, (void*)ft1000dev);
-
-
-    init_waitqueue_head(&ft1000dev->control_wait);
-
-	set_current_state(TASK_INTERRUPTIBLE);
-
-    add_wait_queue(&ft1000dev->control_wait, &wait);
-
-
-
-
-    status = usb_submit_urb(urb, GFP_KERNEL);
-
-    if(status)
-    {
-        usb_free_urb(urb);
-        kfree(dr);
-        remove_wait_queue(&ft1000dev->control_wait, &wait);
-        spin_unlock(&ft1000dev->device_lock);
-        return status;
-    }
-
-    if(urb->status == -EINPROGRESS)
-    {
-        while(timeout && urb->status == -EINPROGRESS)
-        {
-            status = timeout = schedule_timeout(timeout);
-        }
-    }
-    else
-    {
-        status = 1;
-    }
-
-    remove_wait_queue(&ft1000dev->control_wait, &wait);
-
-    if(!status)
-    {
-        usb_unlink_urb(urb);
-        printk("ft1000 timeout\n");
-        status = -ETIMEDOUT;
-    }
-    else
-    {
-        status = urb->status;
-
-        if(urb->status)
-        {
-            printk("ft1000 control message failed (urb addr: %p) with error number: %i\n", urb, (int)status);
-
-            usb_clear_halt(ft1000dev->dev, usb_rcvctrlpipe(ft1000dev->dev, 0));
-            usb_clear_halt(ft1000dev->dev, usb_sndctrlpipe(ft1000dev->dev, 0));
-            usb_unlink_urb(urb);
-        }
-    }
-
-
-
-    usb_free_urb(urb);
-    kfree(dr);
-    spin_unlock(&ft1000dev->device_lock);
-    return ret;
-
-
-}
-
-//---------------------------------------------------------------------------
-// Function:    ft1000_read_fifo_len
-//
-// Parameters:  ft1000dev - device structure
-//
-//
-// Returns:     none
-//
-// Description: read the fifo length register content
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static inline u16 ft1000_read_fifo_len (struct net_device *dev)
-{
-    u16 temp;
-    u16 ret;
-
-	struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev);
-    struct ft1000_device *ft1000dev = info->pFt1000Dev;
-//    DEBUG("ft1000_read_fifo_len: enter ft1000dev %x\n", ft1000dev);			//aelias [-] reason: warning: format ???%x??? expects type ???unsigned int???, but argument 2 has type ???struct ft1000_device *???
-    DEBUG("ft1000_read_fifo_len: enter ft1000dev %p\n", ft1000dev);	//aelias [+] reason: up
-
-    ret = STATUS_SUCCESS;
-
-    ret = ft1000_read_fifo_reg(ft1000dev,
-                          usb_rcvctrlpipe(ft1000dev->dev,0),
-                          HARLEY_READ_REGISTER,
-                          HARLEY_READ_OPERATION,
-                          0,
-                          FT1000_REG_MAG_UFSR,
-                          &temp,
-                          2,
-                          LARGE_TIMEOUT);
-
-    if (ret>0)
-        ret = STATUS_SUCCESS;
-    else
-        ret = STATUS_FAILURE;
-
-    DEBUG("ft1000_read_fifo_len: returned %d\n", temp);
-
-    return (temp- 16);
-
-}
-
-
 //---------------------------------------------------------------------------
 //
 // Function:   ft1000_copy_down_pkt
@@ -1219,16 +1017,15 @@
     struct ft1000_device *pFt1000Dev = pInfo->pFt1000Dev;
 
 
-    int i, count, ret;
-    USHORT *pTemp;
-    USHORT checksum;
+	int count, ret;
     u8 *t;
+	struct pseudo_hdr hdr;
 
     if (!pInfo->CardReady)
     {
 
         DEBUG("ft1000_copy_down_pkt::Card Not Ready\n");
-    	return STATUS_FAILURE;
+	return -ENODEV;
 
     }
 
@@ -1240,27 +1037,27 @@
     {
         DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n");
     	DEBUG("size = %d\n", count);
-    	return STATUS_FAILURE;
+	return -EINVAL;
     }
 
     if ( count % 4)
         count = count + (4- (count %4) );
 
-    pTemp = (PUSHORT)&(pFt1000Dev->tx_buf[0]);
-    *pTemp ++ = ntohs(count);
-    *pTemp ++ = 0x1020;
-    *pTemp ++ = 0x2010;
-    *pTemp ++ = 0x9100;
-    *pTemp ++ = 0;
-    *pTemp ++ = 0;
-    *pTemp ++ = 0;
-    pTemp = (PUSHORT)&(pFt1000Dev->tx_buf[0]);
-    checksum = *pTemp ++;
-    for (i=1; i<7; i++)
-    {
-        checksum ^= *pTemp ++;
-    }
-    *pTemp++ = checksum;
+	memset(&hdr, 0, sizeof(struct pseudo_hdr));
+
+	hdr.length = ntohs(count);
+	hdr.source = 0x10;
+	hdr.destination = 0x20;
+	hdr.portdest = 0x20;
+	hdr.portsrc = 0x10;
+	hdr.sh_str_id = 0x91;
+	hdr.control = 0x00;
+
+	hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^
+			hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^
+			hdr.control;
+
+	memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr));
 	memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len);
 
     netif_stop_queue(netdev);
@@ -1283,25 +1080,18 @@
     }*/
 
 
-    ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
-    if(ret)
-    {
+	ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
+	if (ret) {
 		DEBUG("ft1000 failed tx_urb %d\n", ret);
-
-		return STATUS_FAILURE;
-
-    }
-    else
-    {
-        //DEBUG("ft1000 sucess tx_urb %d\n", ret);
-
-        pInfo->stats.tx_packets++;
-        pInfo->stats.tx_bytes += (len+14);
-    }
+		return ret;
+	} else {
+		pInfo->stats.tx_packets++;
+		pInfo->stats.tx_bytes += (len+14);
+	}
 
     //DEBUG("ft1000_copy_down_pkt() exit\n");
 
-    return STATUS_SUCCESS;
+	return 0;
 }
 
 //---------------------------------------------------------------------------
@@ -1331,14 +1121,13 @@
     if ( skb == NULL )
     {
         DEBUG ("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n" );
-        return STATUS_FAILURE;
+	return NETDEV_TX_OK;
     }
 
     if ( pFt1000Dev->status & FT1000_STATUS_CLOSING)
     {
         DEBUG("network driver is closed, return\n");
-        dev_kfree_skb(skb);
-        return STATUS_SUCCESS;
+	goto err;
     }
 
     //DEBUG("ft1000_start_xmit 1:length of packet = %d\n", skb->len);
@@ -1357,28 +1146,24 @@
     {
         /* Drop packet is mediastate is down */
         DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n");
-        dev_kfree_skb(skb);
-        return STATUS_SUCCESS;
+	goto err;
     }
 
     if ( (skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE) )
     {
         /* Drop packet which has invalid size */
         DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n");
-        dev_kfree_skb(skb);
-        return STATUS_SUCCESS;
+	goto err;
     }
 //mbelian
-    if(ft1000_copy_down_pkt (dev, (pdata+ENET_HEADER_SIZE-2), skb->len - ENET_HEADER_SIZE + 2) == STATUS_FAILURE)
-	{
-    	dev_kfree_skb(skb);
-		return STATUS_SUCCESS;
-	}
+	ft1000_copy_down_pkt(dev, (pdata+ENET_HEADER_SIZE-2),
+				skb->len - ENET_HEADER_SIZE + 2);
 
-    dev_kfree_skb(skb);
+err:
+	dev_kfree_skb(skb);
     //DEBUG(" ft1000_start_xmit() exit\n");
 
-    return 0;
+	return NETDEV_TX_OK;
 }
 
 //---------------------------------------------------------------------------
@@ -1424,7 +1209,7 @@
     //DEBUG("ft1000_copy_up_pkt: transfer_buffer_length=%d, actual_buffer_len=%d\n",
       //       urb->transfer_buffer_length, urb->actual_length);
 
-    chksum = (PUSHORT)ft1000dev->rx_buf;
+    chksum = (u16 *)ft1000dev->rx_buf;
 
     tempword = *chksum++;
     for (i=1; i<7; i++)
@@ -1521,7 +1306,7 @@
     {
         DEBUG("network driver is closed, return\n");
         //usb_kill_urb(pFt1000Dev->rx_urb); //mbelian
-        return STATUS_SUCCESS;
+	return -ENODEV;
     }
 
     usb_fill_bulk_urb(pFt1000Dev->rx_urb,
@@ -1536,12 +1321,12 @@
     if((result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC)))
     {
         printk("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", result);
-        return STATUS_FAILURE;
+	return result;
     }
 
     //DEBUG("ft1000_submit_rx_urb exit: result=%d\n", result);
 
-    return STATUS_SUCCESS;
+	return 0;
 }
 
 //---------------------------------------------------------------------------
@@ -1562,6 +1347,7 @@
 {
 	struct ft1000_info *pInfo = (struct ft1000_info *)netdev_priv(dev);
     struct timeval tv; //mbelian
+	int ret;
 
     DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber);
     //DEBUG("ft1000_open: dev->addr=%x, dev->addr_len=%d\n", dev->addr, dev->addr_len);
@@ -1579,8 +1365,9 @@
 
     netif_carrier_on(dev); //mbelian
 
-    ft1000_submit_rx_urb(pInfo);
-    return 0;
+	ret = ft1000_submit_rx_urb(pInfo);
+
+	return ret;
 }
 
 //---------------------------------------------------------------------------
@@ -1692,13 +1479,13 @@
 //          = 1 (successful)
 //
 //---------------------------------------------------------------------------
-static BOOLEAN ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) {
+static bool ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) {
     u16 size, ret;
     u16 *ppseudohdr;
     int i;
     u16 tempword;
 
-    ret = ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (PUCHAR)&size, FT1000_MAG_PH_LEN_INDX);
+    ret = ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *)&size, FT1000_MAG_PH_LEN_INDX);
     size = ntohs(size) + PSEUDOSZ;
     if (size > maxsz) {
         DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", size);
@@ -1754,9 +1541,9 @@
     u16 i=0;
 	struct prov_record *ptr;
 	struct pseudo_hdr *ppseudo_hdr;
-    PUSHORT pmsg;
+    u16 *pmsg;
     u16 status;
-    USHORT TempShortBuf [256];
+    u16 TempShortBuf [256];
 
     DEBUG("*** DspProv Entered\n");
 
@@ -1792,7 +1579,7 @@
             len = htons(len);
             len += PSEUDOSZ;
 
-            pmsg = (PUSHORT)ptr->pprov_data;
+            pmsg = (u16 *)ptr->pprov_data;
 		ppseudo_hdr = (struct pseudo_hdr *)pmsg;
             // Insert slow queue sequence number
             ppseudo_hdr->seq_num = info->squeseqnum++;
@@ -1809,7 +1596,7 @@
             TempShortBuf[1] = htons (len);
             memcpy(&TempShortBuf[2], ppseudo_hdr, len);
 
-            status = ft1000_write_dpram32 (dev, 0, (PUCHAR)&TempShortBuf[0], (unsigned short)(len+2));
+            status = ft1000_write_dpram32 (dev, 0, (u8 *)&TempShortBuf[0], (unsigned short)(len+2));
             status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL);
 
             list_del(&ptr->list);
@@ -1839,7 +1626,7 @@
 	struct drv_msg *pdrvmsg;
     u16 i;
 	struct pseudo_hdr *ppseudo_hdr;
-    PUSHORT pmsg;
+    u16 *pmsg;
     u16 status;
     union {
         u8  byte[2];
@@ -1971,7 +1758,7 @@
                 tempword = ntohs(pdrvmsg->length);
                 info->DSPInfoBlklen = tempword;
                 if (tempword < (MAX_DSP_SESS_REC-4) ) {
-                    pmsg = (PUSHORT)&pdrvmsg->data[0];
+                    pmsg = (u16 *)&pdrvmsg->data[0];
                     for (i=0; i<((tempword+1)/2); i++) {
                         DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg);
                         info->DSPInfoBlk[i+10] = *pmsg++;
@@ -2003,10 +1790,10 @@
 
                 // Put message into Slow Queue
                 // Form Pseudo header
-                pmsg = (PUSHORT)info->DSPInfoBlk;
+                pmsg = (u16 *)info->DSPInfoBlk;
                 *pmsg++ = 0;
                 *pmsg++ = htons(info->DSPInfoBlklen+20+info->DSPInfoBlklen);
-		ppseudo_hdr = (struct pseudo_hdr *)(PUSHORT)&info->DSPInfoBlk[2];
+		ppseudo_hdr = (struct pseudo_hdr *)(u16 *)&info->DSPInfoBlk[2];
                 ppseudo_hdr->length = htons(info->DSPInfoBlklen+4+info->DSPInfoBlklen);
                 ppseudo_hdr->source = 0x10;
                 ppseudo_hdr->destination = 0x20;
@@ -2028,7 +1815,7 @@
                 }
                 info->DSPInfoBlk[10] = 0x7200;
                 info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen);
-                status = ft1000_write_dpram32 (dev, 0, (PUCHAR)&info->DSPInfoBlk[0], (unsigned short)(info->DSPInfoBlklen+22));
+                status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPInfoBlk[0], (unsigned short)(info->DSPInfoBlklen+22));
                 status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL);
                 info->DrvMsgPend = 0;
 
@@ -2053,7 +1840,7 @@
               if ( (tempword & FT1000_DB_DPRAM_TX) == 0) {
                   // Put message into Slow Queue
                   // Form Pseudo header
-                  pmsg = (PUSHORT)&tempbuffer[0];
+                  pmsg = (u16 *)&tempbuffer[0];
 			ppseudo_hdr = (struct pseudo_hdr *)pmsg;
                   ppseudo_hdr->length = htons(0x0012);
                   ppseudo_hdr->source = 0x10;
@@ -2074,7 +1861,7 @@
                   for (i=1; i<7; i++) {
                       ppseudo_hdr->checksum ^= *pmsg++;
                   }
-                  pmsg = (PUSHORT)&tempbuffer[16];
+                  pmsg = (u16 *)&tempbuffer[16];
                   *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
                   *pmsg++ = htons(0x000e);
                   *pmsg++ = htons(info->DSP_TIME[0]);
@@ -2089,7 +1876,7 @@
                   *pmsg++ = convert.wrd;
                   *pmsg++ = htons(info->DrvErrNum);
 
-                  CardSendCommand (dev, (unsigned char*)&tempbuffer[0], (USHORT)(0x0012 + PSEUDOSZ));
+                  CardSendCommand (dev, (unsigned char*)&tempbuffer[0], (u16)(0x0012 + PSEUDOSZ));
                   info->DrvErrNum = 0;
               }
               info->DrvMsgPend = 0;
@@ -2120,9 +1907,9 @@
     u16 status;
     u16 size;
     int i;
-    USHORT data;
-    USHORT modulo;
-    USHORT portid;
+    u16 data;
+    u16 modulo;
+    u16 portid;
     u16 nxtph;
 	struct dpram_blk *pdpram_blk;
 	struct pseudo_hdr *ppseudo_hdr;
@@ -2143,14 +1930,14 @@
         if (tempword & FT1000_DB_DPRAM_RX) {
             //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_DPRAM_RX\n");
 
-            status = ft1000_read_dpram16(dev, 0x200, (PUCHAR)&data, 0);
+            status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0);
             //DEBUG("ft1000_poll:FT1000_DB_DPRAM_RX:ft1000_read_dpram16:size = 0x%x\n", data);
             size = ntohs(data) + 16 + 2; //wai
             if (size % 4) {
                 modulo = 4 - (size % 4);
                 size = size + modulo;
             }
-            status = ft1000_read_dpram16(dev, 0x201, (PUCHAR)&portid, 1);
+            status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1);
             portid &= 0xff;
             //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid 0x%x\n", portid);
 
@@ -2285,7 +2072,7 @@
             status = ft1000_write_register (dev, FT1000_ASIC_RESET_REQ, FT1000_REG_DOORBELL);
             status = ft1000_write_register (dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL);
             // copy dsp session record from Adapter block
-            status = ft1000_write_dpram32 (dev, 0, (PUCHAR)&info->DSPSess.Rec[0], 1024);
+            status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPSess.Rec[0], 1024);
             // Program WMARK register
             status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK);
             // ring doorbell to tell DSP that ASIC is out of reset
@@ -2299,10 +2086,10 @@
             if (info->fAppMsgPend == 0) {
                // Reset ASIC and DSP
 
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (PUCHAR)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX);
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (PUCHAR)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX);
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (PUCHAR)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX);
-                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (PUCHAR)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX);
+                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX);
+                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (u8 *)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX);
+                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (u8 *)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX);
+                status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (u8 *)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX);
                 info->CardReady = 0;
                 info->DrvErrNum = DSP_CONDRESET_INFO;
                 DEBUG("ft1000_hw:DSP conditional reset requested\n");
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h
index c580741..ab9312f 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h
@@ -4,7 +4,7 @@
 
 #include "ft1000_usb.h"
 
-extern u16 ft1000_read_register(struct usb_device *dev, PUSHORT Data, u8 nRegIndx);
-extern u16 ft1000_write_register(struct usb_device *dev, USHORT value, u8 nRegIndx);
+extern u16 ft1000_read_register(struct usb_device *dev, u16 *Data, u8 nRegIndx);
+extern u16 ft1000_write_register(struct usb_device *dev, u16 value, u8 nRegIndx);
 
 #endif
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
index 36cdd58..f665640 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
@@ -38,8 +38,8 @@
 //#endif
 
 
-u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, USHORT indx,
-			 PUCHAR buffer, u8 highlow);
+u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, u16 indx,
+			 u8 *buffer, u8 highlow);
 
 
 static int
@@ -77,11 +77,11 @@
   if (info->ProgConStat != 0xFF)
     {
       ft1000_read_dpram16 (info->pFt1000Dev, FT1000_MAG_DSP_LED,
-			   (PUCHAR) & ledStat, FT1000_MAG_DSP_LED_INDX);
+			   (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX);
       info->LedStat = ntohs (ledStat);
 
       ft1000_read_dpram16 (info->pFt1000Dev, FT1000_MAG_DSP_CON_STATE,
-			   (PUCHAR) & conStat, FT1000_MAG_DSP_CON_STATE_INDX);
+			   (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
       info->ConStat = ntohs (conStat);
       do_gettimeofday (&tv);
       delta = (tv.tv_sec - info->ConTm);
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
index 28f55b2..99e3339 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
@@ -36,7 +36,7 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static BOOLEAN gPollingfailed = FALSE;
+static bool gPollingfailed = FALSE;
 int ft1000_poll_thread(void *arg)
 {
 	int ret = STATUS_SUCCESS;
@@ -84,7 +84,6 @@
 	ft1000dev->dev = dev;
 	ft1000dev->status = 0;
 	ft1000dev->net = NULL;
-	spin_lock_init(&ft1000dev->device_lock);
 	ft1000dev->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
 	ft1000dev->rx_urb = usb_alloc_urb(0, GFP_ATOMIC);
 
@@ -176,12 +175,16 @@
 	gPollingfailed = FALSE;
 	pft1000info->pPollThread =
 	    kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll");
+
+	if (IS_ERR(pft1000info->pPollThread)) {
+		ret = PTR_ERR(pft1000info->pPollThread);
+		goto err_thread;
+	}
+
 	msleep(500);
 
 	while (!pft1000info->CardReady) {
 		if (gPollingfailed) {
-			if (pft1000info->pPollThread)
-				kthread_stop(pft1000info->pPollThread);
 			ret = -EIO;
 			goto err_load;
 		}
@@ -202,6 +205,8 @@
 	return 0;
 
 err_load:
+	kthread_stop(pft1000info->pPollThread);
+err_thread:
 	kfree(pFileStart);
 err_fw:
 	kfree(ft1000dev);
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
index a9d419a..a07db26 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
@@ -98,16 +98,6 @@
 /*end of Jim*/
 #define DEBUG(args...) printk(KERN_INFO args)
 
-#define UCHAR               u8
-#define USHORT              u16
-#define ULONG               u32 /* WTF ??? */
-#define BOOLEAN             u8
-#define PULONG              u32 *
-#define PUSHORT             u16 *
-#define PUCHAR              u8 *
-#define PCHAR               u8 *
-#define UINT                u32
-
 #define FALSE           0
 #define TRUE            1
 
@@ -372,15 +362,15 @@
 
 
 
-#define ISR_EMPTY			(UCHAR)0x00 	 // no bits set in ISR
+#define ISR_EMPTY			(u8)0x00 	 // no bits set in ISR
 
-#define ISR_DOORBELL_ACK	(UCHAR)0x01		 //  the doorbell i sent has been recieved.
+#define ISR_DOORBELL_ACK	(u8)0x01		 //  the doorbell i sent has been recieved.
 
-#define ISR_DOORBELL_PEND	(UCHAR)0x02 	 //  doorbell for me
+#define ISR_DOORBELL_PEND	(u8)0x02 	 //  doorbell for me
 
-#define ISR_RCV				(UCHAR)0x04 	 // packet received with no errors
+#define ISR_RCV				(u8)0x04 	 // packet received with no errors
 
-#define ISR_WATERMARK		(UCHAR)0x08 	 //
+#define ISR_WATERMARK		(u8)0x08 	 //
 
 
 
@@ -466,12 +456,9 @@
 {
 	struct usb_device *dev;
 	struct net_device *net;
-	spinlock_t device_lock;
 
 	u32 status;
 
-	wait_queue_head_t control_wait;
-
 	struct urb *rx_urb;
 	struct urb *tx_urb;
 
@@ -497,9 +484,9 @@
 	unsigned char usbboot;
     unsigned short dspalive;
     u16 ASIC_ID;
-    BOOLEAN fProvComplete;
-    BOOLEAN fCondResetPend;
-    BOOLEAN fAppMsgPend;
+    bool fProvComplete;
+    bool fCondResetPend;
+    bool fAppMsgPend;
     char *pfwimg;
     int fwimgsz;
     u16 DrvErrNum;
@@ -567,20 +554,20 @@
 } __attribute__ ((packed));
 
 u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx);
-u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRegIndx);
-u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt);
-u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt);
-u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, u8 highlow);
-u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT value, u8 highlow);
-u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer);
-u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer);
+u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx);
+u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt);
+u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt);
+u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow);
+u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow);
+u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer);
+u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer);
 
 extern void *pFileStart;
 extern size_t FileLength;
 extern int numofmsgbuf;
 
 int ft1000_close (struct net_device *dev);
-u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG  FileLength);
+u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32  FileLength);
 
 extern struct list_head freercvpool;
 extern spinlock_t free_buff_lock;   // lock to arbitrate free buffer list for receive command data
diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c
index 26ebc77..45a627d 100644
--- a/drivers/staging/hv/channel.c
+++ b/drivers/staging/hv/channel.c
@@ -43,24 +43,24 @@
 	int j = 0;
 
 	DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d",
-		   MonitorPage, MonitorPage->TriggerState);
+		   MonitorPage, MonitorPage->trigger_state);
 
 	for (i = 0; i < 4; i++)
 		DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i,
-			   MonitorPage->TriggerGroup[i].AsUINT64);
+			   MonitorPage->trigger_group[i].as_uint64);
 
 	for (i = 0; i < 4; i++) {
 		for (j = 0; j < 32; j++) {
 			DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j,
-				   MonitorPage->Latency[i][j]);
+				   MonitorPage->latency[i][j]);
 		}
 	}
 	for (i = 0; i < 4; i++) {
 		for (j = 0; j < 32; j++) {
 			DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j,
-			       MonitorPage->Parameter[i][j].ConnectionId.Asu32);
+			       MonitorPage->parameter[i][j].connectionid.asu32);
 			DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j,
-				MonitorPage->Parameter[i][j].FlagNumber);
+				MonitorPage->parameter[i][j].flag_number);
 		}
 	}
 }
@@ -74,21 +74,21 @@
 {
 	struct hv_monitor_page *monitorpage;
 
-	if (channel->OfferMsg.MonitorAllocated) {
+	if (channel->offermsg.monitor_allocated) {
 		/* Each u32 represents 32 channels */
-		set_bit(channel->OfferMsg.ChildRelId & 31,
+		set_bit(channel->offermsg.child_relid & 31,
 			(unsigned long *) gVmbusConnection.SendInterruptPage +
-			(channel->OfferMsg.ChildRelId >> 5));
+			(channel->offermsg.child_relid >> 5));
 
 		monitorpage = gVmbusConnection.MonitorPages;
 		monitorpage++; /* Get the child to parent monitor page */
 
-		set_bit(channel->MonitorBit,
-			(unsigned long *)&monitorpage->TriggerGroup
-					[channel->MonitorGroup].Pending);
+		set_bit(channel->monitor_bit,
+			(unsigned long *)&monitorpage->trigger_group
+					[channel->monitor_grp].pending);
 
 	} else {
-		VmbusSetEvent(channel->OfferMsg.ChildRelId);
+		VmbusSetEvent(channel->offermsg.child_relid);
 	}
 }
 
@@ -97,19 +97,19 @@
 {
 	struct hv_monitor_page *monitorPage;
 
-	if (Channel->OfferMsg.MonitorAllocated) {
+	if (Channel->offermsg.monitor_allocated) {
 		/* Each u32 represents 32 channels */
-		clear_bit(Channel->OfferMsg.ChildRelId & 31,
+		clear_bit(Channel->offermsg.child_relid & 31,
 			  (unsigned long *)gVmbusConnection.SendInterruptPage +
-			  (Channel->OfferMsg.ChildRelId >> 5));
+			  (Channel->offermsg.child_relid >> 5));
 
 		monitorPage =
 			(struct hv_monitor_page *)gVmbusConnection.MonitorPages;
 		monitorPage++; /* Get the child to parent monitor page */
 
-		clear_bit(Channel->MonitorBit,
-			  (unsigned long *)&monitorPage->TriggerGroup
-					[Channel->MonitorGroup].Pending);
+		clear_bit(Channel->monitor_bit,
+			  (unsigned long *)&monitorPage->trigger_group
+					[Channel->monitor_grp].Pending);
 	}
 }
 
@@ -121,42 +121,42 @@
 			      struct vmbus_channel_debug_info *debuginfo)
 {
 	struct hv_monitor_page *monitorpage;
-	u8 monitor_group = (u8)channel->OfferMsg.MonitorId / 32;
-	u8 monitor_offset = (u8)channel->OfferMsg.MonitorId % 32;
+	u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
+	u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
 	/* u32 monitorBit	= 1 << monitorOffset; */
 
-	debuginfo->RelId = channel->OfferMsg.ChildRelId;
-	debuginfo->State = channel->State;
-	memcpy(&debuginfo->InterfaceType,
-	       &channel->OfferMsg.Offer.InterfaceType, sizeof(struct hv_guid));
-	memcpy(&debuginfo->InterfaceInstance,
-	       &channel->OfferMsg.Offer.InterfaceInstance,
+	debuginfo->relid = channel->offermsg.child_relid;
+	debuginfo->state = channel->state;
+	memcpy(&debuginfo->interfacetype,
+	       &channel->offermsg.offer.InterfaceType, sizeof(struct hv_guid));
+	memcpy(&debuginfo->interface_instance,
+	       &channel->offermsg.offer.InterfaceInstance,
 	       sizeof(struct hv_guid));
 
 	monitorpage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages;
 
-	debuginfo->MonitorId = channel->OfferMsg.MonitorId;
+	debuginfo->monitorid = channel->offermsg.monitorid;
 
-	debuginfo->ServerMonitorPending =
-			monitorpage->TriggerGroup[monitor_group].Pending;
-	debuginfo->ServerMonitorLatency =
-			monitorpage->Latency[monitor_group][monitor_offset];
-	debuginfo->ServerMonitorConnectionId =
-			monitorpage->Parameter[monitor_group]
-					[monitor_offset].ConnectionId.u.Id;
+	debuginfo->servermonitor_pending =
+			monitorpage->trigger_group[monitor_group].pending;
+	debuginfo->servermonitor_latency =
+			monitorpage->latency[monitor_group][monitor_offset];
+	debuginfo->servermonitor_connectionid =
+			monitorpage->parameter[monitor_group]
+					[monitor_offset].connectionid.u.id;
 
 	monitorpage++;
 
-	debuginfo->ClientMonitorPending =
-			monitorpage->TriggerGroup[monitor_group].Pending;
-	debuginfo->ClientMonitorLatency =
-			monitorpage->Latency[monitor_group][monitor_offset];
-	debuginfo->ClientMonitorConnectionId =
-			monitorpage->Parameter[monitor_group]
-					[monitor_offset].ConnectionId.u.Id;
+	debuginfo->clientmonitor_pending =
+			monitorpage->trigger_group[monitor_group].pending;
+	debuginfo->clientmonitor_latency =
+			monitorpage->latency[monitor_group][monitor_offset];
+	debuginfo->clientmonitor_connectionid =
+			monitorpage->parameter[monitor_group]
+					[monitor_offset].connectionid.u.id;
 
-	RingBufferGetDebugInfo(&channel->Inbound, &debuginfo->Inbound);
-	RingBufferGetDebugInfo(&channel->Outbound, &debuginfo->Outbound);
+	ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
+	ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
 }
 
 /*
@@ -176,11 +176,11 @@
 	/* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */
 	/* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */
 
-	newchannel->OnChannelCallback = onchannelcallback;
-	newchannel->ChannelCallbackContext = context;
+	newchannel->onchannel_callback = onchannelcallback;
+	newchannel->channel_callback_context = context;
 
 	/* Allocate the ring buffer */
-	out = osd_PageAlloc((send_ringbuffer_size + recv_ringbuffer_size)
+	out = osd_page_alloc((send_ringbuffer_size + recv_ringbuffer_size)
 			     >> PAGE_SHIFT);
 	if (!out)
 		return -ENOMEM;
@@ -189,17 +189,17 @@
 
 	in = (void *)((unsigned long)out + send_ringbuffer_size);
 
-	newchannel->RingBufferPages = out;
-	newchannel->RingBufferPageCount = (send_ringbuffer_size +
+	newchannel->ringbuffer_pages = out;
+	newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
 					   recv_ringbuffer_size) >> PAGE_SHIFT;
 
-	ret = RingBufferInit(&newchannel->Outbound, out, send_ringbuffer_size);
+	ret = ringbuffer_init(&newchannel->outbound, out, send_ringbuffer_size);
 	if (ret != 0) {
 		err = ret;
 		goto errorout;
 	}
 
-	ret = RingBufferInit(&newchannel->Inbound, in, recv_ringbuffer_size);
+	ret = ringbuffer_init(&newchannel->inbound, in, recv_ringbuffer_size);
 	if (ret != 0) {
 		err = ret;
 		goto errorout;
@@ -210,13 +210,13 @@
 	DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...",
 		   newchannel);
 
-	newchannel->RingBufferGpadlHandle = 0;
+	newchannel->ringbuffer_gpadlhandle = 0;
 
 	ret = vmbus_establish_gpadl(newchannel,
-					 newchannel->Outbound.RingBuffer,
+					 newchannel->outbound.ring_buffer,
 					 send_ringbuffer_size +
 					 recv_ringbuffer_size,
-					 &newchannel->RingBufferGpadlHandle);
+					 &newchannel->ringbuffer_gpadlhandle);
 
 	if (ret != 0) {
 		err = ret;
@@ -225,12 +225,12 @@
 
 	DPRINT_DBG(VMBUS, "channel %p <relid %d gpadl 0x%x send ring %p "
 		   "size %d recv ring %p size %d, downstreamoffset %d>",
-		   newchannel, newchannel->OfferMsg.ChildRelId,
-		   newchannel->RingBufferGpadlHandle,
-		   newchannel->Outbound.RingBuffer,
-		   newchannel->Outbound.RingSize,
-		   newchannel->Inbound.RingBuffer,
-		   newchannel->Inbound.RingSize,
+		   newchannel, newchannel->offermsg.child_relid,
+		   newchannel->ringbuffer_gpadlhandle,
+		   newchannel->outbound.ring_buffer,
+		   newchannel->outbound.ring_size,
+		   newchannel->inbound.ring_buffer,
+		   newchannel->inbound.ring_size,
 		   send_ringbuffer_size);
 
 	/* Create and init the channel open message */
@@ -242,20 +242,20 @@
 		goto errorout;
 	}
 
-	openInfo->WaitEvent = osd_WaitEventCreate();
-	if (!openInfo->WaitEvent) {
+	openInfo->waitevent = osd_waitevent_create();
+	if (!openInfo->waitevent) {
 		err = -ENOMEM;
 		goto errorout;
 	}
 
-	openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg;
-	openMsg->Header.MessageType = ChannelMessageOpenChannel;
-	openMsg->OpenId = newchannel->OfferMsg.ChildRelId; /* FIXME */
-	openMsg->ChildRelId = newchannel->OfferMsg.ChildRelId;
-	openMsg->RingBufferGpadlHandle = newchannel->RingBufferGpadlHandle;
-	openMsg->DownstreamRingBufferPageOffset = send_ringbuffer_size >>
+	openMsg = (struct vmbus_channel_open_channel *)openInfo->msg;
+	openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL;
+	openMsg->openid = newchannel->offermsg.child_relid; /* FIXME */
+	openMsg->child_relid = newchannel->offermsg.child_relid;
+	openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
+	openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
 						  PAGE_SHIFT;
-	openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */
+	openMsg->server_contextarea_gpadlhandle = 0; /* TODO */
 
 	if (userdatalen > MAX_USER_DEFINED_BYTES) {
 		err = -EINVAL;
@@ -263,10 +263,10 @@
 	}
 
 	if (userdatalen)
-		memcpy(openMsg->UserData, userdata, userdatalen);
+		memcpy(openMsg->userdata, userdata, userdatalen);
 
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_add_tail(&openInfo->MsgListEntry,
+	list_add_tail(&openInfo->msglistentry,
 		      &gVmbusConnection.ChannelMsgList);
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
 
@@ -280,27 +280,27 @@
 	}
 
 	/* FIXME: Need to time-out here */
-	osd_WaitEventWait(openInfo->WaitEvent);
+	osd_waitevent_wait(openInfo->waitevent);
 
-	if (openInfo->Response.OpenResult.Status == 0)
+	if (openInfo->response.open_result.status == 0)
 		DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel);
 	else
 		DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!",
-			    newchannel, openInfo->Response.OpenResult.Status);
+			    newchannel, openInfo->response.open_result.status);
 
 Cleanup:
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_del(&openInfo->MsgListEntry);
+	list_del(&openInfo->msglistentry);
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
 
-	kfree(openInfo->WaitEvent);
+	kfree(openInfo->waitevent);
 	kfree(openInfo);
 	return 0;
 
 errorout:
-	RingBufferCleanup(&newchannel->Outbound);
-	RingBufferCleanup(&newchannel->Inbound);
-	osd_PageFree(out, (send_ringbuffer_size + recv_ringbuffer_size)
+	ringbuffer_cleanup(&newchannel->outbound);
+	ringbuffer_cleanup(&newchannel->inbound);
+	osd_page_free(out, (send_ringbuffer_size + recv_ringbuffer_size)
 		     >> PAGE_SHIFT);
 	kfree(openInfo);
 	return err;
@@ -322,7 +322,7 @@
 
 	for (i = 0; i < pfncount; i++)
 		DPRINT_DBG(VMBUS, "gpadl body  - %d) pfn %llu",
-			   i, gpadl->Pfn[i]);
+			   i, gpadl->pfn[i]);
 }
 
 /*
@@ -336,18 +336,18 @@
 
 	DPRINT_DBG(VMBUS,
 		   "gpadl header - relid %d, range count %d, range buflen %d",
-		   gpadl->ChildRelId, gpadl->RangeCount, gpadl->RangeBufLen);
-	for (i = 0; i < gpadl->RangeCount; i++) {
-		pagecount = gpadl->Range[i].ByteCount >> PAGE_SHIFT;
+		   gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen);
+	for (i = 0; i < gpadl->rangecount; i++) {
+		pagecount = gpadl->range[i].ByteCount >> PAGE_SHIFT;
 		pagecount = (pagecount > 26) ? 26 : pagecount;
 
 		DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
-			   "page count %d", i, gpadl->Range[i].ByteCount,
-			   gpadl->Range[i].ByteOffset, pagecount);
+			   "page count %d", i, gpadl->range[i].ByteCount,
+			   gpadl->range[i].ByteOffset, pagecount);
 
 		for (j = 0; j < pagecount; j++)
 			DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
-				   gpadl->Range[i].PfnArray[j]);
+				   gpadl->range[i].PfnArray[j]);
 	}
 }
 
@@ -391,18 +391,18 @@
 		if (!msgheader)
 			goto nomem;
 
-		INIT_LIST_HEAD(&msgheader->SubMsgList);
-		msgheader->MessageSize = msgsize;
+		INIT_LIST_HEAD(&msgheader->submsglist);
+		msgheader->msgsize = msgsize;
 
 		gpadl_header = (struct vmbus_channel_gpadl_header *)
-			msgheader->Msg;
-		gpadl_header->RangeCount = 1;
-		gpadl_header->RangeBufLen = sizeof(struct gpa_range) +
+			msgheader->msg;
+		gpadl_header->rangecount = 1;
+		gpadl_header->range_buflen = sizeof(struct gpa_range) +
 					 pagecount * sizeof(u64);
-		gpadl_header->Range[0].ByteOffset = 0;
-		gpadl_header->Range[0].ByteCount = size;
+		gpadl_header->range[0].ByteOffset = 0;
+		gpadl_header->range[0].ByteCount = size;
 		for (i = 0; i < pfncount; i++)
-			gpadl_header->Range[0].PfnArray[i] = pfn+i;
+			gpadl_header->range[0].PfnArray[i] = pfn+i;
 		*msginfo = msgheader;
 		*messagecount = 1;
 
@@ -428,10 +428,10 @@
 			/* FIXME: we probably need to more if this fails */
 			if (!msgbody)
 				goto nomem;
-			msgbody->MessageSize = msgsize;
+			msgbody->msgsize = msgsize;
 			(*messagecount)++;
 			gpadl_body =
-				(struct vmbus_channel_gpadl_body *)msgbody->Msg;
+				(struct vmbus_channel_gpadl_body *)msgbody->msg;
 
 			/*
 			 * FIXME:
@@ -440,11 +440,11 @@
 			 */
 			/* gpadl_body->Gpadl = kbuffer; */
 			for (i = 0; i < pfncurr; i++)
-				gpadl_body->Pfn[i] = pfn + pfnsum + i;
+				gpadl_body->pfn[i] = pfn + pfnsum + i;
 
 			/* add to msg header */
-			list_add_tail(&msgbody->MsgListEntry,
-				      &msgheader->SubMsgList);
+			list_add_tail(&msgbody->msglistentry,
+				      &msgheader->submsglist);
 			pfnsum += pfncurr;
 			pfnleft -= pfncurr;
 		}
@@ -456,17 +456,17 @@
 		msgheader = kzalloc(msgsize, GFP_KERNEL);
 		if (msgheader == NULL)
 			goto nomem;
-		msgheader->MessageSize = msgsize;
+		msgheader->msgsize = msgsize;
 
 		gpadl_header = (struct vmbus_channel_gpadl_header *)
-			msgheader->Msg;
-		gpadl_header->RangeCount = 1;
-		gpadl_header->RangeBufLen = sizeof(struct gpa_range) +
+			msgheader->msg;
+		gpadl_header->rangecount = 1;
+		gpadl_header->range_buflen = sizeof(struct gpa_range) +
 					 pagecount * sizeof(u64);
-		gpadl_header->Range[0].ByteOffset = 0;
-		gpadl_header->Range[0].ByteCount = size;
+		gpadl_header->range[0].ByteOffset = 0;
+		gpadl_header->range[0].ByteCount = size;
 		for (i = 0; i < pagecount; i++)
-			gpadl_header->Range[0].PfnArray[i] = pfn+i;
+			gpadl_header->range[0].PfnArray[i] = pfn+i;
 
 		*msginfo = msgheader;
 		*messagecount = 1;
@@ -508,21 +508,21 @@
 	if (ret)
 		return ret;
 
-	msginfo->WaitEvent = osd_WaitEventCreate();
-	if (!msginfo->WaitEvent) {
+	msginfo->waitevent = osd_waitevent_create();
+	if (!msginfo->waitevent) {
 		ret = -ENOMEM;
 		goto Cleanup;
 	}
 
-	gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->Msg;
-	gpadlmsg->Header.MessageType = ChannelMessageGpadlHeader;
-	gpadlmsg->ChildRelId = channel->OfferMsg.ChildRelId;
-	gpadlmsg->Gpadl = next_gpadl_handle;
+	gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
+	gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
+	gpadlmsg->child_relid = channel->offermsg.child_relid;
+	gpadlmsg->gpadl = next_gpadl_handle;
 
 	dump_gpadl_header(gpadlmsg);
 
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_add_tail(&msginfo->MsgListEntry,
+	list_add_tail(&msginfo->msglistentry,
 		      &gVmbusConnection.ChannelMsgList);
 
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
@@ -530,9 +530,9 @@
 		   kbuffer, size, msgcount);
 
 	DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd",
-		   msginfo->MessageSize - sizeof(*msginfo));
+		   msginfo->msgsize - sizeof(*msginfo));
 
-	ret = VmbusPostMessage(gpadlmsg, msginfo->MessageSize -
+	ret = VmbusPostMessage(gpadlmsg, msginfo->msgsize -
 			       sizeof(*msginfo));
 	if (ret != 0) {
 		DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret);
@@ -540,48 +540,48 @@
 	}
 
 	if (msgcount > 1) {
-		list_for_each(curr, &msginfo->SubMsgList) {
+		list_for_each(curr, &msginfo->submsglist) {
 
 			/* FIXME: should this use list_entry() instead ? */
 			submsginfo = (struct vmbus_channel_msginfo *)curr;
 			gpadl_body =
-			     (struct vmbus_channel_gpadl_body *)submsginfo->Msg;
+			     (struct vmbus_channel_gpadl_body *)submsginfo->msg;
 
-			gpadl_body->Header.MessageType =
-				ChannelMessageGpadlBody;
-			gpadl_body->Gpadl = next_gpadl_handle;
+			gpadl_body->header.msgtype =
+				CHANNELMSG_GPADL_BODY;
+			gpadl_body->gpadl = next_gpadl_handle;
 
 			DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd",
-				   submsginfo->MessageSize -
+				   submsginfo->msgsize -
 				   sizeof(*submsginfo));
 
-			dump_gpadl_body(gpadl_body, submsginfo->MessageSize -
+			dump_gpadl_body(gpadl_body, submsginfo->msgsize -
 				      sizeof(*submsginfo));
 			ret = VmbusPostMessage(gpadl_body,
-					       submsginfo->MessageSize -
+					       submsginfo->msgsize -
 					       sizeof(*submsginfo));
 			if (ret != 0)
 				goto Cleanup;
 
 		}
 	}
-	osd_WaitEventWait(msginfo->WaitEvent);
+	osd_waitevent_wait(msginfo->waitevent);
 
 	/* At this point, we received the gpadl created msg */
 	DPRINT_DBG(VMBUS, "Received GPADL created "
 		   "(relid %d, status %d handle %x)",
-		   channel->OfferMsg.ChildRelId,
-		   msginfo->Response.GpadlCreated.CreationStatus,
-		   gpadlmsg->Gpadl);
+		   channel->offermsg.child_relid,
+		   msginfo->response.gpadl_created.creation_status,
+		   gpadlmsg->gpadl);
 
-	*gpadl_handle = gpadlmsg->Gpadl;
+	*gpadl_handle = gpadlmsg->gpadl;
 
 Cleanup:
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_del(&msginfo->MsgListEntry);
+	list_del(&msginfo->msglistentry);
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
 
-	kfree(msginfo->WaitEvent);
+	kfree(msginfo->waitevent);
 	kfree(msginfo);
 	return ret;
 }
@@ -604,20 +604,20 @@
 	if (!info)
 		return -ENOMEM;
 
-	info->WaitEvent = osd_WaitEventCreate();
-	if (!info->WaitEvent) {
+	info->waitevent = osd_waitevent_create();
+	if (!info->waitevent) {
 		kfree(info);
 		return -ENOMEM;
 	}
 
-	msg = (struct vmbus_channel_gpadl_teardown *)info->Msg;
+	msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
 
-	msg->Header.MessageType = ChannelMessageGpadlTeardown;
-	msg->ChildRelId = channel->OfferMsg.ChildRelId;
-	msg->Gpadl = gpadl_handle;
+	msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN;
+	msg->child_relid = channel->offermsg.child_relid;
+	msg->gpadl = gpadl_handle;
 
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_add_tail(&info->MsgListEntry,
+	list_add_tail(&info->msglistentry,
 		      &gVmbusConnection.ChannelMsgList);
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
 
@@ -628,14 +628,14 @@
 		/* something... */
 	}
 
-	osd_WaitEventWait(info->WaitEvent);
+	osd_waitevent_wait(info->waitevent);
 
 	/* Received a torndown response */
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_del(&info->MsgListEntry);
+	list_del(&info->msglistentry);
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
 
-	kfree(info->WaitEvent);
+	kfree(info->waitevent);
 	kfree(info);
 	return ret;
 }
@@ -652,7 +652,7 @@
 	int ret;
 
 	/* Stop callback and cancel the timer asap */
-	channel->OnChannelCallback = NULL;
+	channel->onchannel_callback = NULL;
 	del_timer_sync(&channel->poll_timer);
 
 	/* Send a closing message */
@@ -663,11 +663,11 @@
 	if (!info)
 		return;
 
-	/* info->waitEvent = osd_WaitEventCreate(); */
+	/* info->waitEvent = osd_waitevent_create(); */
 
-	msg = (struct vmbus_channel_close_channel *)info->Msg;
-	msg->Header.MessageType = ChannelMessageCloseChannel;
-	msg->ChildRelId = channel->OfferMsg.ChildRelId;
+	msg = (struct vmbus_channel_close_channel *)info->msg;
+	msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
+	msg->child_relid = channel->offermsg.child_relid;
 
 	ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel));
 	if (ret != 0) {
@@ -676,17 +676,17 @@
 	}
 
 	/* Tear down the gpadl for the channel's ring buffer */
-	if (channel->RingBufferGpadlHandle)
+	if (channel->ringbuffer_gpadlhandle)
 		vmbus_teardown_gpadl(channel,
-					  channel->RingBufferGpadlHandle);
+					  channel->ringbuffer_gpadlhandle);
 
 	/* TODO: Send a msg to release the childRelId */
 
 	/* Cleanup the ring buffers for this channel */
-	RingBufferCleanup(&channel->Outbound);
-	RingBufferCleanup(&channel->Inbound);
+	ringbuffer_cleanup(&channel->outbound);
+	ringbuffer_cleanup(&channel->inbound);
 
-	osd_PageFree(channel->RingBufferPages, channel->RingBufferPageCount);
+	osd_page_free(channel->ringbuffer_pages, channel->ringbuffer_pagecount);
 
 	kfree(info);
 
@@ -696,9 +696,9 @@
 	 * caller will free the channel
 	 */
 
-	if (channel->State == CHANNEL_OPEN_STATE) {
+	if (channel->state == CHANNEL_OPEN_STATE) {
 		spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
-		list_del(&channel->ListEntry);
+		list_del(&channel->listentry);
 		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
 
 		free_channel(channel);
@@ -752,10 +752,10 @@
 	sg_set_buf(&bufferlist[2], &aligned_data,
 		   packetlen_aligned - packetlen);
 
-	ret = RingBufferWrite(&channel->Outbound, bufferlist, 3);
+	ret = ringbuffer_write(&channel->outbound, bufferlist, 3);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && !GetRingBufferInterruptMask(&channel->Outbound))
+	if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -817,10 +817,10 @@
 	sg_set_buf(&bufferlist[2], &aligned_data,
 		packetlen_aligned - packetlen);
 
-	ret = RingBufferWrite(&channel->Outbound, bufferlist, 3);
+	ret = ringbuffer_write(&channel->outbound, bufferlist, 3);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && !GetRingBufferInterruptMask(&channel->Outbound))
+	if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -886,10 +886,10 @@
 	sg_set_buf(&bufferlist[2], &aligned_data,
 		packetlen_aligned - packetlen);
 
-	ret = RingBufferWrite(&channel->Outbound, bufferlist, 3);
+	ret = ringbuffer_write(&channel->outbound, bufferlist, 3);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && !GetRingBufferInterruptMask(&channel->Outbound))
+	if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -923,7 +923,7 @@
 
 	spin_lock_irqsave(&channel->inbound_lock, flags);
 
-	ret = RingBufferPeek(&channel->Inbound, &desc,
+	ret = ringbuffer_peek(&channel->inbound, &desc,
 			     sizeof(struct vmpacket_descriptor));
 	if (ret != 0) {
 		spin_unlock_irqrestore(&channel->inbound_lock, flags);
@@ -940,7 +940,7 @@
 
 	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
 		   "flag %d tid %llx pktlen %d datalen %d> ",
-		   channel, channel->OfferMsg.ChildRelId, desc.Type,
+		   channel, channel->offermsg.child_relid, desc.Type,
 		   desc.Flags, desc.TransactionId, packetlen, userlen);
 
 	*buffer_actual_len = userlen;
@@ -956,7 +956,7 @@
 	*requestid = desc.TransactionId;
 
 	/* Copy over the packet to the user buffer */
-	ret = RingBufferRead(&channel->Inbound, buffer, userlen,
+	ret = ringbuffer_read(&channel->inbound, buffer, userlen,
 			     (desc.DataOffset8 << 3));
 
 	spin_unlock_irqrestore(&channel->inbound_lock, flags);
@@ -983,7 +983,7 @@
 
 	spin_lock_irqsave(&channel->inbound_lock, flags);
 
-	ret = RingBufferPeek(&channel->Inbound, &desc,
+	ret = ringbuffer_peek(&channel->inbound, &desc,
 			     sizeof(struct vmpacket_descriptor));
 	if (ret != 0) {
 		spin_unlock_irqrestore(&channel->inbound_lock, flags);
@@ -999,7 +999,7 @@
 
 	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
 		   "flag %d tid %llx pktlen %d datalen %d> ",
-		   channel, channel->OfferMsg.ChildRelId, desc.Type,
+		   channel, channel->offermsg.child_relid, desc.Type,
 		   desc.Flags, desc.TransactionId, packetlen, userlen);
 
 	*buffer_actual_len = packetlen;
@@ -1015,7 +1015,7 @@
 	*requestid = desc.TransactionId;
 
 	/* Copy over the entire packet to the user buffer */
-	ret = RingBufferRead(&channel->Inbound, buffer, packetlen, 0);
+	ret = ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
 
 	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 	return 0;
@@ -1030,7 +1030,7 @@
 	dump_vmbus_channel(channel);
 	/* ASSERT(Channel->OnChannelCallback); */
 
-	channel->OnChannelCallback(channel->ChannelCallbackContext);
+	channel->onchannel_callback(channel->channel_callback_context);
 
 	mod_timer(&channel->poll_timer, jiffies + usecs_to_jiffies(100));
 }
@@ -1042,8 +1042,8 @@
 {
 	struct vmbus_channel *channel = (struct vmbus_channel *)data;
 
-	if (channel->OnChannelCallback)
-		channel->OnChannelCallback(channel->ChannelCallbackContext);
+	if (channel->onchannel_callback)
+		channel->onchannel_callback(channel->channel_callback_context);
 }
 
 /*
@@ -1051,7 +1051,7 @@
  */
 static void dump_vmbus_channel(struct vmbus_channel *channel)
 {
-	DPRINT_DBG(VMBUS, "Channel (%d)", channel->OfferMsg.ChildRelId);
-	DumpRingInfo(&channel->Outbound, "Outbound ");
-	DumpRingInfo(&channel->Inbound, "Inbound ");
+	DPRINT_DBG(VMBUS, "Channel (%d)", channel->offermsg.child_relid);
+	dump_ring_info(&channel->outbound, "Outbound ");
+	dump_ring_info(&channel->inbound, "Inbound ");
 }
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index 45dbe30..ae830f2 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -251,8 +251,8 @@
 	channel->poll_timer.data = (unsigned long)channel;
 	channel->poll_timer.function = vmbus_ontimer;
 
-	channel->ControlWQ = create_workqueue("hv_vmbus_ctl");
-	if (!channel->ControlWQ) {
+	channel->controlwq = create_workqueue("hv_vmbus_ctl");
+	if (!channel->controlwq) {
 		kfree(channel);
 		return NULL;
 	}
@@ -268,7 +268,7 @@
 	struct vmbus_channel *channel = context;
 
 	DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
-	destroy_workqueue(channel->ControlWQ);
+	destroy_workqueue(channel->controlwq);
 	DPRINT_DBG(VMBUS, "channel released (%p)", channel);
 
 	kfree(channel);
@@ -325,12 +325,12 @@
 	/* Make sure this is a new offer */
 	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
 
-	list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) {
-		if (!memcmp(&channel->OfferMsg.Offer.InterfaceType,
-			    &newchannel->OfferMsg.Offer.InterfaceType,
+	list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) {
+		if (!memcmp(&channel->offermsg.offer.InterfaceType,
+			    &newchannel->offermsg.offer.InterfaceType,
 			    sizeof(struct hv_guid)) &&
-		    !memcmp(&channel->OfferMsg.Offer.InterfaceInstance,
-			    &newchannel->OfferMsg.Offer.InterfaceInstance,
+		    !memcmp(&channel->offermsg.offer.InterfaceInstance,
+			    &newchannel->offermsg.offer.InterfaceInstance,
 			    sizeof(struct hv_guid))) {
 			fnew = false;
 			break;
@@ -338,14 +338,14 @@
 	}
 
 	if (fnew)
-		list_add_tail(&newchannel->ListEntry,
+		list_add_tail(&newchannel->listentry,
 			      &gVmbusConnection.ChannelList);
 
 	spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
 
 	if (!fnew) {
 		DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)",
-			   newchannel->OfferMsg.ChildRelId);
+			   newchannel->offermsg.child_relid);
 		free_channel(newchannel);
 		return;
 	}
@@ -355,27 +355,27 @@
 	 * We need to set the DeviceObject field before calling
 	 * VmbusChildDeviceAdd()
 	 */
-	newchannel->DeviceObject = VmbusChildDeviceCreate(
-		&newchannel->OfferMsg.Offer.InterfaceType,
-		&newchannel->OfferMsg.Offer.InterfaceInstance,
+	newchannel->device_obj = VmbusChildDeviceCreate(
+		&newchannel->offermsg.offer.InterfaceType,
+		&newchannel->offermsg.offer.InterfaceInstance,
 		newchannel);
 
 	DPRINT_DBG(VMBUS, "child device object allocated - %p",
-		   newchannel->DeviceObject);
+		   newchannel->device_obj);
 
 	/*
 	 * Add the new device to the bus. This will kick off device-driver
 	 * binding which eventually invokes the device driver's AddDevice()
 	 * method.
 	 */
-	ret = VmbusChildDeviceAdd(newchannel->DeviceObject);
+	ret = VmbusChildDeviceAdd(newchannel->device_obj);
 	if (ret != 0) {
 		DPRINT_ERR(VMBUS,
 			   "unable to add child device object (relid %d)",
-			   newchannel->OfferMsg.ChildRelId);
+			   newchannel->offermsg.child_relid);
 
 		spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
-		list_del(&newchannel->ListEntry);
+		list_del(&newchannel->listentry);
 		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
 
 		free_channel(newchannel);
@@ -385,11 +385,11 @@
 		 * so that when we do close the channel normally, we
 		 * can cleanup properly
 		 */
-		newchannel->State = CHANNEL_OPEN_STATE;
+		newchannel->state = CHANNEL_OPEN_STATE;
 
 		/* Open IC channels */
 		for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
-			if (memcmp(&newchannel->OfferMsg.Offer.InterfaceType,
+			if (memcmp(&newchannel->offermsg.offer.InterfaceType,
 				   &hv_cb_utils[cnt].data,
 				   sizeof(struct hv_guid)) == 0 &&
 				vmbus_open(newchannel, 2 * PAGE_SIZE,
@@ -413,7 +413,7 @@
 {
 	struct vmbus_channel *channel = context;
 
-	VmbusChildDeviceRemove(channel->DeviceObject);
+	VmbusChildDeviceRemove(channel->device_obj);
 }
 
 /*
@@ -434,7 +434,7 @@
 
 	offer = (struct vmbus_channel_offer_channel *)hdr;
 	for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
-		if (memcmp(&offer->Offer.InterfaceType,
+		if (memcmp(&offer->offer.InterfaceType,
 		    &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) {
 			fsupported = 1;
 			break;
@@ -443,12 +443,12 @@
 
 	if (!fsupported) {
 		DPRINT_DBG(VMBUS, "Ignoring channel offer notification for "
-			   "child relid %d", offer->ChildRelId);
+			   "child relid %d", offer->child_relid);
 		return;
 	}
 
-	guidtype = &offer->Offer.InterfaceType;
-	guidinstance = &offer->Offer.InterfaceInstance;
+	guidtype = &offer->offer.InterfaceType;
+	guidinstance = &offer->offer.InterfaceInstance;
 
 	DPRINT_INFO(VMBUS, "Channel offer notification - "
 		    "child relid %d monitor id %d allocated %d, "
@@ -456,8 +456,8 @@
 		    "%02x%02x%02x%02x%02x%02x%02x%02x} "
 		    "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
 		    "%02x%02x%02x%02x%02x%02x%02x%02x}",
-		    offer->ChildRelId, offer->MonitorId,
-		    offer->MonitorAllocated,
+		    offer->child_relid, offer->monitorid,
+		    offer->monitor_allocated,
 		    guidtype->data[3], guidtype->data[2],
 		    guidtype->data[1], guidtype->data[0],
 		    guidtype->data[5], guidtype->data[4],
@@ -484,13 +484,13 @@
 
 	DPRINT_DBG(VMBUS, "channel object allocated - %p", newchannel);
 
-	memcpy(&newchannel->OfferMsg, offer,
+	memcpy(&newchannel->offermsg, offer,
 	       sizeof(struct vmbus_channel_offer_channel));
-	newchannel->MonitorGroup = (u8)offer->MonitorId / 32;
-	newchannel->MonitorBit = (u8)offer->MonitorId % 32;
+	newchannel->monitor_grp = (u8)offer->monitorid / 32;
+	newchannel->monitor_bit = (u8)offer->monitorid % 32;
 
 	/* TODO: Make sure the offer comes from our parent partition */
-	osd_schedule_callback(newchannel->ControlWQ, vmbus_process_offer,
+	osd_schedule_callback(newchannel->controlwq, vmbus_process_offer,
 			      newchannel);
 }
 
@@ -505,14 +505,14 @@
 	struct vmbus_channel *channel;
 
 	rescind = (struct vmbus_channel_rescind_offer *)hdr;
-	channel = GetChannelFromRelId(rescind->ChildRelId);
+	channel = GetChannelFromRelId(rescind->child_relid);
 	if (channel == NULL) {
 		DPRINT_DBG(VMBUS, "channel not found for relId %d",
-			   rescind->ChildRelId);
+			   rescind->child_relid);
 		return;
 	}
 
-	osd_schedule_callback(channel->ControlWQ,
+	osd_schedule_callback(channel->controlwq,
 			      vmbus_process_rescind_offer,
 			      channel);
 }
@@ -545,7 +545,7 @@
 	unsigned long flags;
 
 	result = (struct vmbus_channel_open_result *)hdr;
-	DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status);
+	DPRINT_DBG(VMBUS, "vmbus open result - %d", result->status);
 
 	/*
 	 * Find the open msg, copy the result and signal/unblock the wait event
@@ -556,17 +556,17 @@
 /* FIXME: this should probably use list_entry() instead */
 		msginfo = (struct vmbus_channel_msginfo *)curr;
 		requestheader =
-			(struct vmbus_channel_message_header *)msginfo->Msg;
+			(struct vmbus_channel_message_header *)msginfo->msg;
 
-		if (requestheader->MessageType == ChannelMessageOpenChannel) {
+		if (requestheader->msgtype == CHANNELMSG_OPENCHANNEL) {
 			openmsg =
-			(struct vmbus_channel_open_channel *)msginfo->Msg;
-			if (openmsg->ChildRelId == result->ChildRelId &&
-			    openmsg->OpenId == result->OpenId) {
-				memcpy(&msginfo->Response.OpenResult,
+			(struct vmbus_channel_open_channel *)msginfo->msg;
+			if (openmsg->child_relid == result->child_relid &&
+			    openmsg->openid == result->openid) {
+				memcpy(&msginfo->response.open_result,
 				       result,
 				       sizeof(struct vmbus_channel_open_result));
-				osd_WaitEventSet(msginfo->WaitEvent);
+				osd_waitevent_set(msginfo->waitevent);
 				break;
 			}
 		}
@@ -592,7 +592,7 @@
 
 	gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr;
 	DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d",
-		   gpadlcreated->CreationStatus);
+		   gpadlcreated->creation_status);
 
 	/*
 	 * Find the establish msg, copy the result and signal/unblock the wait
@@ -604,19 +604,19 @@
 /* FIXME: this should probably use list_entry() instead */
 		msginfo = (struct vmbus_channel_msginfo *)curr;
 		requestheader =
-			(struct vmbus_channel_message_header *)msginfo->Msg;
+			(struct vmbus_channel_message_header *)msginfo->msg;
 
-		if (requestheader->MessageType == ChannelMessageGpadlHeader) {
+		if (requestheader->msgtype == CHANNELMSG_GPADL_HEADER) {
 			gpadlheader =
 			(struct vmbus_channel_gpadl_header *)requestheader;
 
-			if ((gpadlcreated->ChildRelId ==
-			     gpadlheader->ChildRelId) &&
-			    (gpadlcreated->Gpadl == gpadlheader->Gpadl)) {
-				memcpy(&msginfo->Response.GpadlCreated,
+			if ((gpadlcreated->child_relid ==
+			     gpadlheader->child_relid) &&
+			    (gpadlcreated->gpadl == gpadlheader->gpadl)) {
+				memcpy(&msginfo->response.gpadl_created,
 				       gpadlcreated,
 				       sizeof(struct vmbus_channel_gpadl_created));
-				osd_WaitEventSet(msginfo->WaitEvent);
+				osd_waitevent_set(msginfo->waitevent);
 				break;
 			}
 		}
@@ -652,17 +652,17 @@
 /* FIXME: this should probably use list_entry() instead */
 		msginfo = (struct vmbus_channel_msginfo *)curr;
 		requestheader =
-			(struct vmbus_channel_message_header *)msginfo->Msg;
+			(struct vmbus_channel_message_header *)msginfo->msg;
 
-		if (requestheader->MessageType == ChannelMessageGpadlTeardown) {
+		if (requestheader->msgtype == CHANNELMSG_GPADL_TEARDOWN) {
 			gpadl_teardown =
 			(struct vmbus_channel_gpadl_teardown *)requestheader;
 
-			if (gpadl_torndown->Gpadl == gpadl_teardown->Gpadl) {
-				memcpy(&msginfo->Response.GpadlTorndown,
+			if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) {
+				memcpy(&msginfo->response.gpadl_torndown,
 				       gpadl_torndown,
 				       sizeof(struct vmbus_channel_gpadl_torndown));
-				osd_WaitEventSet(msginfo->WaitEvent);
+				osd_waitevent_set(msginfo->waitevent);
 				break;
 			}
 		}
@@ -694,16 +694,16 @@
 /* FIXME: this should probably use list_entry() instead */
 		msginfo = (struct vmbus_channel_msginfo *)curr;
 		requestheader =
-			(struct vmbus_channel_message_header *)msginfo->Msg;
+			(struct vmbus_channel_message_header *)msginfo->msg;
 
-		if (requestheader->MessageType ==
-		    ChannelMessageInitiateContact) {
+		if (requestheader->msgtype ==
+		    CHANNELMSG_INITIATE_CONTACT) {
 			initiate =
 			(struct vmbus_channel_initiate_contact *)requestheader;
-			memcpy(&msginfo->Response.VersionResponse,
+			memcpy(&msginfo->response.version_response,
 			      version_response,
 			      sizeof(struct vmbus_channel_version_response));
-			osd_WaitEventSet(msginfo->WaitEvent);
+			osd_waitevent_set(msginfo->waitevent);
 		}
 	}
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
@@ -711,24 +711,24 @@
 
 /* Channel message dispatch table */
 static struct vmbus_channel_message_table_entry
-	gChannelMessageTable[ChannelMessageCount] = {
-	{ChannelMessageInvalid,			NULL},
-	{ChannelMessageOfferChannel,		vmbus_onoffer},
-	{ChannelMessageRescindChannelOffer,	vmbus_onoffer_rescind},
-	{ChannelMessageRequestOffers,		NULL},
-	{ChannelMessageAllOffersDelivered,	vmbus_onoffers_delivered},
-	{ChannelMessageOpenChannel,		NULL},
-	{ChannelMessageOpenChannelResult,	vmbus_onopen_result},
-	{ChannelMessageCloseChannel,		NULL},
-	{ChannelMessageGpadlHeader,		NULL},
-	{ChannelMessageGpadlBody,		NULL},
-	{ChannelMessageGpadlCreated,		vmbus_ongpadl_created},
-	{ChannelMessageGpadlTeardown,		NULL},
-	{ChannelMessageGpadlTorndown,		vmbus_ongpadl_torndown},
-	{ChannelMessageRelIdReleased,		NULL},
-	{ChannelMessageInitiateContact,		NULL},
-	{ChannelMessageVersionResponse,		vmbus_onversion_response},
-	{ChannelMessageUnload,			NULL},
+	gChannelMessageTable[CHANNELMSG_COUNT] = {
+	{CHANNELMSG_INVALID,			NULL},
+	{CHANNELMSG_OFFERCHANNEL,		vmbus_onoffer},
+	{CHANNELMSG_RESCIND_CHANNELOFFER,	vmbus_onoffer_rescind},
+	{CHANNELMSG_REQUESTOFFERS,		NULL},
+	{CHANNELMSG_ALLOFFERS_DELIVERED,	vmbus_onoffers_delivered},
+	{CHANNELMSG_OPENCHANNEL,		NULL},
+	{CHANNELMSG_OPENCHANNEL_RESULT,	vmbus_onopen_result},
+	{CHANNELMSG_CLOSECHANNEL,		NULL},
+	{CHANNELMSG_GPADL_HEADER,		NULL},
+	{CHANNELMSG_GPADL_BODY,		NULL},
+	{CHANNELMSG_GPADL_CREATED,		vmbus_ongpadl_created},
+	{CHANNELMSG_GPADL_TEARDOWN,		NULL},
+	{CHANNELMSG_GPADL_TORNDOWN,		vmbus_ongpadl_torndown},
+	{CHANNELMSG_RELID_RELEASED,		NULL},
+	{CHANNELMSG_INITIATE_CONTACT,		NULL},
+	{CHANNELMSG_VERSION_RESPONSE,		vmbus_onversion_response},
+	{CHANNELMSG_UNLOAD,			NULL},
 };
 
 /*
@@ -742,26 +742,26 @@
 	struct vmbus_channel_message_header *hdr;
 	int size;
 
-	hdr = (struct vmbus_channel_message_header *)msg->u.Payload;
-	size = msg->Header.PayloadSize;
+	hdr = (struct vmbus_channel_message_header *)msg->u.payload;
+	size = msg->header.payload_size;
 
-	DPRINT_DBG(VMBUS, "message type %d size %d", hdr->MessageType, size);
+	DPRINT_DBG(VMBUS, "message type %d size %d", hdr->msgtype, size);
 
-	if (hdr->MessageType >= ChannelMessageCount) {
+	if (hdr->msgtype >= CHANNELMSG_COUNT) {
 		DPRINT_ERR(VMBUS,
 			   "Received invalid channel message type %d size %d",
-			   hdr->MessageType, size);
+			   hdr->msgtype, size);
 		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
-				     (unsigned char *)msg->u.Payload, size);
+				     (unsigned char *)msg->u.payload, size);
 		kfree(msg);
 		return;
 	}
 
-	if (gChannelMessageTable[hdr->MessageType].messageHandler)
-		gChannelMessageTable[hdr->MessageType].messageHandler(hdr);
+	if (gChannelMessageTable[hdr->msgtype].messageHandler)
+		gChannelMessageTable[hdr->msgtype].messageHandler(hdr);
 	else
 		DPRINT_ERR(VMBUS, "Unhandled channel message type %d",
-			   hdr->MessageType);
+			   hdr->msgtype);
 
 	/* Free the msg that was allocated in VmbusOnMsgDPC() */
 	kfree(msg);
@@ -782,15 +782,15 @@
 	if (!msginfo)
 		return -ENOMEM;
 
-	msginfo->WaitEvent = osd_WaitEventCreate();
-	if (!msginfo->WaitEvent) {
+	msginfo->waitevent = osd_waitevent_create();
+	if (!msginfo->waitevent) {
 		kfree(msginfo);
 		return -ENOMEM;
 	}
 
-	msg = (struct vmbus_channel_message_header *)msginfo->Msg;
+	msg = (struct vmbus_channel_message_header *)msginfo->msg;
 
-	msg->MessageType = ChannelMessageRequestOffers;
+	msg->msgtype = CHANNELMSG_REQUESTOFFERS;
 
 	/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
 	INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList,
@@ -808,7 +808,7 @@
 
 		goto Cleanup;
 	}
-	/* osd_WaitEventWait(msgInfo->waitEvent); */
+	/* osd_waitevent_wait(msgInfo->waitEvent); */
 
 	/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
 	REMOVE_ENTRY_LIST(&msgInfo->msgListEntry);
@@ -817,7 +817,7 @@
 
 Cleanup:
 	if (msginfo) {
-		kfree(msginfo->WaitEvent);
+		kfree(msginfo->waitevent);
 		kfree(msginfo);
 	}
 
@@ -837,17 +837,17 @@
 	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
 
 	list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList,
-				 ListEntry) {
+				 listentry) {
 		if (channel == start)
 			break;
 
-		if (!channel->DeviceObject->Driver) {
-			list_del(&channel->ListEntry);
+		if (!channel->device_obj->Driver) {
+			list_del(&channel->listentry);
 			DPRINT_INFO(VMBUS,
 				    "Releasing unattached device object %p",
-				    channel->DeviceObject);
+				    channel->device_obj);
 
-			VmbusChildDeviceRemove(channel->DeviceObject);
+			VmbusChildDeviceRemove(channel->device_obj);
 			free_channel(channel);
 		} else {
 			if (!start)
diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h
index d16cc081..12f30af 100644
--- a/drivers/staging/hv/channel_mgmt.h
+++ b/drivers/staging/hv/channel_mgmt.h
@@ -33,60 +33,60 @@
 
 /* Version 1 messages */
 enum vmbus_channel_message_type {
-	ChannelMessageInvalid			=  0,
-	ChannelMessageOfferChannel		=  1,
-	ChannelMessageRescindChannelOffer	=  2,
-	ChannelMessageRequestOffers		=  3,
-	ChannelMessageAllOffersDelivered	=  4,
-	ChannelMessageOpenChannel		=  5,
-	ChannelMessageOpenChannelResult		=  6,
-	ChannelMessageCloseChannel		=  7,
-	ChannelMessageGpadlHeader		=  8,
-	ChannelMessageGpadlBody			=  9,
-	ChannelMessageGpadlCreated		= 10,
-	ChannelMessageGpadlTeardown		= 11,
-	ChannelMessageGpadlTorndown		= 12,
-	ChannelMessageRelIdReleased		= 13,
-	ChannelMessageInitiateContact		= 14,
-	ChannelMessageVersionResponse		= 15,
-	ChannelMessageUnload			= 16,
+	CHANNELMSG_INVALID			=  0,
+	CHANNELMSG_OFFERCHANNEL		=  1,
+	CHANNELMSG_RESCIND_CHANNELOFFER	=  2,
+	CHANNELMSG_REQUESTOFFERS		=  3,
+	CHANNELMSG_ALLOFFERS_DELIVERED	=  4,
+	CHANNELMSG_OPENCHANNEL		=  5,
+	CHANNELMSG_OPENCHANNEL_RESULT		=  6,
+	CHANNELMSG_CLOSECHANNEL		=  7,
+	CHANNELMSG_GPADL_HEADER		=  8,
+	CHANNELMSG_GPADL_BODY			=  9,
+	CHANNELMSG_GPADL_CREATED		= 10,
+	CHANNELMSG_GPADL_TEARDOWN		= 11,
+	CHANNELMSG_GPADL_TORNDOWN		= 12,
+	CHANNELMSG_RELID_RELEASED		= 13,
+	CHANNELMSG_INITIATE_CONTACT		= 14,
+	CHANNELMSG_VERSION_RESPONSE		= 15,
+	CHANNELMSG_UNLOAD			= 16,
 #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
-	ChannelMessageViewRangeAdd		= 17,
-	ChannelMessageViewRangeRemove		= 18,
+	CHANNELMSG_VIEWRANGE_ADD		= 17,
+	CHANNELMSG_VIEWRANGE_REMOVE		= 18,
 #endif
-	ChannelMessageCount
+	CHANNELMSG_COUNT
 };
 
 struct vmbus_channel_message_header {
-	enum vmbus_channel_message_type MessageType;
-	u32 Padding;
+	enum vmbus_channel_message_type msgtype;
+	u32 padding;
 } __attribute__((packed));
 
 /* Query VMBus Version parameters */
 struct vmbus_channel_query_vmbus_version {
-	struct vmbus_channel_message_header Header;
-	u32 Version;
+	struct vmbus_channel_message_header header;
+	u32 version;
 } __attribute__((packed));
 
 /* VMBus Version Supported parameters */
 struct vmbus_channel_version_supported {
-	struct vmbus_channel_message_header Header;
-	bool VersionSupported;
+	struct vmbus_channel_message_header header;
+	bool version_supported;
 } __attribute__((packed));
 
 /* Offer Channel parameters */
 struct vmbus_channel_offer_channel {
-	struct vmbus_channel_message_header Header;
-	struct vmbus_channel_offer Offer;
-	u32 ChildRelId;
-	u8 MonitorId;
-	bool MonitorAllocated;
+	struct vmbus_channel_message_header header;
+	struct vmbus_channel_offer offer;
+	u32 child_relid;
+	u8 monitorid;
+	bool monitor_allocated;
 } __attribute__((packed));
 
 /* Rescind Offer parameters */
 struct vmbus_channel_rescind_offer {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
 } __attribute__((packed));
 
 /*
@@ -100,43 +100,43 @@
 
 /* Open Channel parameters */
 struct vmbus_channel_open_channel {
-	struct vmbus_channel_message_header Header;
+	struct vmbus_channel_message_header header;
 
 	/* Identifies the specific VMBus channel that is being opened. */
-	u32 ChildRelId;
+	u32 child_relid;
 
 	/* ID making a particular open request at a channel offer unique. */
-	u32 OpenId;
+	u32 openid;
 
 	/* GPADL for the channel's ring buffer. */
-	u32 RingBufferGpadlHandle;
+	u32 ringbuffer_gpadlhandle;
 
 	/* GPADL for the channel's server context save area. */
-	u32 ServerContextAreaGpadlHandle;
+	u32 server_contextarea_gpadlhandle;
 
 	/*
 	* The upstream ring buffer begins at offset zero in the memory
 	* described by RingBufferGpadlHandle. The downstream ring buffer
 	* follows it at this offset (in pages).
 	*/
-	u32 DownstreamRingBufferPageOffset;
+	u32 downstream_ringbuffer_pageoffset;
 
 	/* User-specific data to be passed along to the server endpoint. */
-	unsigned char UserData[MAX_USER_DEFINED_BYTES];
+	unsigned char userdata[MAX_USER_DEFINED_BYTES];
 } __attribute__((packed));
 
 /* Open Channel Result parameters */
 struct vmbus_channel_open_result {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
-	u32 OpenId;
-	u32 Status;
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 openid;
+	u32 status;
 } __attribute__((packed));
 
 /* Close channel parameters; */
 struct vmbus_channel_close_channel {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
 } __attribute__((packed));
 
 /* Channel Message GPADL */
@@ -151,72 +151,72 @@
  * follow-up packet that contains more.
  */
 struct vmbus_channel_gpadl_header {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
-	u32 Gpadl;
-	u16 RangeBufLen;
-	u16 RangeCount;
-	struct gpa_range Range[0];
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 gpadl;
+	u16 range_buflen;
+	u16 rangecount;
+	struct gpa_range range[0];
 } __attribute__((packed));
 
 /* This is the followup packet that contains more PFNs. */
 struct vmbus_channel_gpadl_body {
-	struct vmbus_channel_message_header Header;
-	u32 MessageNumber;
-	u32 Gpadl;
-	u64 Pfn[0];
+	struct vmbus_channel_message_header header;
+	u32 msgnumber;
+	u32 gpadl;
+	u64 pfn[0];
 } __attribute__((packed));
 
 struct vmbus_channel_gpadl_created {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
-	u32 Gpadl;
-	u32 CreationStatus;
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 gpadl;
+	u32 creation_status;
 } __attribute__((packed));
 
 struct vmbus_channel_gpadl_teardown {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
-	u32 Gpadl;
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 gpadl;
 } __attribute__((packed));
 
 struct vmbus_channel_gpadl_torndown {
-	struct vmbus_channel_message_header Header;
-	u32 Gpadl;
+	struct vmbus_channel_message_header header;
+	u32 gpadl;
 } __attribute__((packed));
 
 #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
 struct vmbus_channel_view_range_add {
-	struct vmbus_channel_message_header Header;
-	PHYSICAL_ADDRESS ViewRangeBase;
-	u64 ViewRangeLength;
-	u32 ChildRelId;
+	struct vmbus_channel_message_header header;
+	PHYSICAL_ADDRESS viewrange_base;
+	u64 viewrange_length;
+	u32 child_relid;
 } __attribute__((packed));
 
 struct vmbus_channel_view_range_remove {
-	struct vmbus_channel_message_header Header;
-	PHYSICAL_ADDRESS ViewRangeBase;
-	u32 ChildRelId;
+	struct vmbus_channel_message_header header;
+	PHYSICAL_ADDRESS viewrange_base;
+	u32 child_relid;
 } __attribute__((packed));
 #endif
 
 struct vmbus_channel_relid_released {
-	struct vmbus_channel_message_header Header;
-	u32 ChildRelId;
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
 } __attribute__((packed));
 
 struct vmbus_channel_initiate_contact {
-	struct vmbus_channel_message_header Header;
-	u32 VMBusVersionRequested;
-	u32 Padding2;
-	u64 InterruptPage;
-	u64 MonitorPage1;
-	u64 MonitorPage2;
+	struct vmbus_channel_message_header header;
+	u32 vmbus_version_requested;
+	u32 padding2;
+	u64 interrupt_page;
+	u64 monitor_page1;
+	u64 monitor_page2;
 } __attribute__((packed));
 
 struct vmbus_channel_version_response {
-	struct vmbus_channel_message_header Header;
-	bool VersionSupported;
+	struct vmbus_channel_message_header header;
+	bool version_supported;
 } __attribute__((packed));
 
 enum vmbus_channel_state {
@@ -226,54 +226,54 @@
 };
 
 struct vmbus_channel {
-	struct list_head ListEntry;
+	struct list_head listentry;
 
-	struct hv_device *DeviceObject;
+	struct hv_device *device_obj;
 
 	struct timer_list poll_timer; /* SA-111 workaround */
 
-	enum vmbus_channel_state State;
+	enum vmbus_channel_state state;
 
-	struct vmbus_channel_offer_channel OfferMsg;
+	struct vmbus_channel_offer_channel offermsg;
 	/*
 	 * These are based on the OfferMsg.MonitorId.
 	 * Save it here for easy access.
 	 */
-	u8 MonitorGroup;
-	u8 MonitorBit;
+	u8 monitor_grp;
+	u8 monitor_bit;
 
-	u32 RingBufferGpadlHandle;
+	u32 ringbuffer_gpadlhandle;
 
 	/* Allocated memory for ring buffer */
-	void *RingBufferPages;
-	u32 RingBufferPageCount;
-	struct hv_ring_buffer_info Outbound;	/* send to parent */
-	struct hv_ring_buffer_info Inbound;	/* receive from parent */
+	void *ringbuffer_pages;
+	u32 ringbuffer_pagecount;
+	struct hv_ring_buffer_info outbound;	/* send to parent */
+	struct hv_ring_buffer_info inbound;	/* receive from parent */
 	spinlock_t inbound_lock;
-	struct workqueue_struct *ControlWQ;
+	struct workqueue_struct *controlwq;
 
 	/* Channel callback are invoked in this workqueue context */
 	/* HANDLE dataWorkQueue; */
 
-	void (*OnChannelCallback)(void *context);
-	void *ChannelCallbackContext;
+	void (*onchannel_callback)(void *context);
+	void *channel_callback_context;
 };
 
 struct vmbus_channel_debug_info {
-	u32 RelId;
-	enum vmbus_channel_state State;
-	struct hv_guid InterfaceType;
-	struct hv_guid InterfaceInstance;
-	u32 MonitorId;
-	u32 ServerMonitorPending;
-	u32 ServerMonitorLatency;
-	u32 ServerMonitorConnectionId;
-	u32 ClientMonitorPending;
-	u32 ClientMonitorLatency;
-	u32 ClientMonitorConnectionId;
+	u32 relid;
+	enum vmbus_channel_state state;
+	struct hv_guid interfacetype;
+	struct hv_guid interface_instance;
+	u32 monitorid;
+	u32 servermonitor_pending;
+	u32 servermonitor_latency;
+	u32 servermonitor_connectionid;
+	u32 clientmonitor_pending;
+	u32 clientmonitor_latency;
+	u32 clientmonitor_connectionid;
 
-	struct hv_ring_buffer_debug_info Inbound;
-	struct hv_ring_buffer_debug_info Outbound;
+	struct hv_ring_buffer_debug_info inbound;
+	struct hv_ring_buffer_debug_info outbound;
 };
 
 /*
@@ -282,28 +282,28 @@
  */
 struct vmbus_channel_msginfo {
 	/* Bookkeeping stuff */
-	struct list_head MsgListEntry;
+	struct list_head msglistentry;
 
 	/* So far, this is only used to handle gpadl body message */
-	struct list_head SubMsgList;
+	struct list_head submsglist;
 
 	/* Synchronize the request/response if needed */
-	struct osd_waitevent *WaitEvent;
+	struct osd_waitevent *waitevent;
 
 	union {
-		struct vmbus_channel_version_supported VersionSupported;
-		struct vmbus_channel_open_result OpenResult;
-		struct vmbus_channel_gpadl_torndown GpadlTorndown;
-		struct vmbus_channel_gpadl_created GpadlCreated;
-		struct vmbus_channel_version_response VersionResponse;
-	} Response;
+		struct vmbus_channel_version_supported version_supported;
+		struct vmbus_channel_open_result open_result;
+		struct vmbus_channel_gpadl_torndown gpadl_torndown;
+		struct vmbus_channel_gpadl_created gpadl_created;
+		struct vmbus_channel_version_response version_response;
+	} response;
 
-	u32 MessageSize;
+	u32 msgsize;
 	/*
 	 * The channel message that goes out on the "wire".
 	 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
 	 */
-	unsigned char Msg[0];
+	unsigned char msg[0];
 };
 
 
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index f847707..c2e298f 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -66,7 +66,7 @@
 	 * Setup the vmbus event connection for channel interrupt
 	 * abstraction stuff
 	 */
-	gVmbusConnection.InterruptPage = osd_PageAlloc(1);
+	gVmbusConnection.InterruptPage = osd_page_alloc(1);
 	if (gVmbusConnection.InterruptPage == NULL) {
 		ret = -1;
 		goto Cleanup;
@@ -81,7 +81,7 @@
 	 * Setup the monitor notification facility. The 1st page for
 	 * parent->child and the 2nd page for child->parent
 	 */
-	gVmbusConnection.MonitorPages = osd_PageAlloc(2);
+	gVmbusConnection.MonitorPages = osd_page_alloc(2);
 	if (gVmbusConnection.MonitorPages == NULL) {
 		ret = -1;
 		goto Cleanup;
@@ -95,19 +95,19 @@
 		goto Cleanup;
 	}
 
-	msgInfo->WaitEvent = osd_WaitEventCreate();
-	if (!msgInfo->WaitEvent) {
+	msgInfo->waitevent = osd_waitevent_create();
+	if (!msgInfo->waitevent) {
 		ret = -ENOMEM;
 		goto Cleanup;
 	}
 
-	msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg;
+	msg = (struct vmbus_channel_initiate_contact *)msgInfo->msg;
 
-	msg->Header.MessageType = ChannelMessageInitiateContact;
-	msg->VMBusVersionRequested = VMBUS_REVISION_NUMBER;
-	msg->InterruptPage = virt_to_phys(gVmbusConnection.InterruptPage);
-	msg->MonitorPage1 = virt_to_phys(gVmbusConnection.MonitorPages);
-	msg->MonitorPage2 = virt_to_phys(
+	msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
+	msg->vmbus_version_requested = VMBUS_REVISION_NUMBER;
+	msg->interrupt_page = virt_to_phys(gVmbusConnection.InterruptPage);
+	msg->monitor_page1 = virt_to_phys(gVmbusConnection.MonitorPages);
+	msg->monitor_page2 = virt_to_phys(
 			(void *)((unsigned long)gVmbusConnection.MonitorPages +
 				 PAGE_SIZE));
 
@@ -116,30 +116,30 @@
 	 * receive the response before returning from this routine
 	 */
 	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
-	list_add_tail(&msgInfo->MsgListEntry,
+	list_add_tail(&msgInfo->msglistentry,
 		      &gVmbusConnection.ChannelMsgList);
 
 	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
 
 	DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, "
 		   "monitor1 pfn %llx,, monitor2 pfn %llx",
-		   msg->InterruptPage, msg->MonitorPage1, msg->MonitorPage2);
+		   msg->interrupt_page, msg->monitor_page1, msg->monitor_page2);
 
 	DPRINT_DBG(VMBUS, "Sending channel initiate msg...");
 	ret = VmbusPostMessage(msg,
 			       sizeof(struct vmbus_channel_initiate_contact));
 	if (ret != 0) {
-		list_del(&msgInfo->MsgListEntry);
+		list_del(&msgInfo->msglistentry);
 		goto Cleanup;
 	}
 
 	/* Wait for the connection response */
-	osd_WaitEventWait(msgInfo->WaitEvent);
+	osd_waitevent_wait(msgInfo->waitevent);
 
-	list_del(&msgInfo->MsgListEntry);
+	list_del(&msgInfo->msglistentry);
 
 	/* Check if successful */
-	if (msgInfo->Response.VersionResponse.VersionSupported) {
+	if (msgInfo->response.version_response.version_supported) {
 		DPRINT_INFO(VMBUS, "Vmbus connected!!");
 		gVmbusConnection.ConnectState = Connected;
 
@@ -151,7 +151,7 @@
 		goto Cleanup;
 	}
 
-	kfree(msgInfo->WaitEvent);
+	kfree(msgInfo->waitevent);
 	kfree(msgInfo);
 	return 0;
 
@@ -162,17 +162,17 @@
 		destroy_workqueue(gVmbusConnection.WorkQueue);
 
 	if (gVmbusConnection.InterruptPage) {
-		osd_PageFree(gVmbusConnection.InterruptPage, 1);
+		osd_page_free(gVmbusConnection.InterruptPage, 1);
 		gVmbusConnection.InterruptPage = NULL;
 	}
 
 	if (gVmbusConnection.MonitorPages) {
-		osd_PageFree(gVmbusConnection.MonitorPages, 2);
+		osd_page_free(gVmbusConnection.MonitorPages, 2);
 		gVmbusConnection.MonitorPages = NULL;
 	}
 
 	if (msgInfo) {
-		kfree(msgInfo->WaitEvent);
+		kfree(msgInfo->waitevent);
 		kfree(msgInfo);
 	}
 
@@ -195,14 +195,14 @@
 	if (!msg)
 		return -ENOMEM;
 
-	msg->MessageType = ChannelMessageUnload;
+	msg->msgtype = CHANNELMSG_UNLOAD;
 
 	ret = VmbusPostMessage(msg,
 			       sizeof(struct vmbus_channel_message_header));
 	if (ret != 0)
 		goto Cleanup;
 
-	osd_PageFree(gVmbusConnection.InterruptPage, 1);
+	osd_page_free(gVmbusConnection.InterruptPage, 1);
 
 	/* TODO: iterate thru the msg list and free up */
 	destroy_workqueue(gVmbusConnection.WorkQueue);
@@ -226,8 +226,8 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
-	list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) {
-		if (channel->OfferMsg.ChildRelId == relId) {
+	list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) {
+		if (channel->offermsg.child_relid == relId) {
 			foundChannel = channel;
 			break;
 		}
@@ -309,9 +309,9 @@
 {
 	union hv_connection_id connId;
 
-	connId.Asu32 = 0;
-	connId.u.Id = VMBUS_MESSAGE_CONNECTION_ID;
-	return HvPostMessage(connId, 1, buffer, bufferLen);
+	connId.asu32 = 0;
+	connId.u.id = VMBUS_MESSAGE_CONNECTION_ID;
+	return hv_post_message(connId, 1, buffer, bufferLen);
 }
 
 /*
@@ -324,5 +324,5 @@
 		(unsigned long *)gVmbusConnection.SendInterruptPage +
 		(childRelId >> 5));
 
-	return HvSignalEvent();
+	return hv_signal_event();
 }
diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c
index 86b1ddd..a34d713 100644
--- a/drivers/staging/hv/hv.c
+++ b/drivers/staging/hv/hv.c
@@ -28,17 +28,18 @@
 #include "vmbus_private.h"
 
 /* The one and only */
-struct hv_context gHvContext = {
-	.SynICInitialized	= false,
-	.HypercallPage		= NULL,
-	.SignalEventParam	= NULL,
-	.SignalEventBuffer	= NULL,
+struct hv_context hv_context = {
+	.synic_initialized	= false,
+	.hypercall_page		= NULL,
+	.signal_event_param	= NULL,
+	.signal_event_buffer	= NULL,
 };
 
 /*
- * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor
+ * query_hypervisor_presence
+ * - Query the cpuid for presense of windows hypervisor
  */
-static int HvQueryHypervisorPresence(void)
+static int query_hypervisor_presence(void)
 {
 	unsigned int eax;
 	unsigned int ebx;
@@ -50,22 +51,22 @@
 	ebx = 0;
 	ecx = 0;
 	edx = 0;
-	op = HvCpuIdFunctionVersionAndFeatures;
+	op = HVCPUID_VERSION_FEATURES;
 	cpuid(op, &eax, &ebx, &ecx, &edx);
 
 	return ecx & HV_PRESENT_BIT;
 }
 
 /*
- * HvQueryHypervisorInfo - Get version info of the windows hypervisor
+ * query_hypervisor_info - Get version info of the windows hypervisor
  */
-static int HvQueryHypervisorInfo(void)
+static int query_hypervisor_info(void)
 {
 	unsigned int eax;
 	unsigned int ebx;
 	unsigned int ecx;
 	unsigned int edx;
-	unsigned int maxLeaf;
+	unsigned int max_leaf;
 	unsigned int op;
 
 	/*
@@ -76,7 +77,7 @@
 	ebx = 0;
 	ecx = 0;
 	edx = 0;
-	op = HvCpuIdFunctionHvVendorAndMaxFunction;
+	op = HVCPUID_VENDOR_MAXFUNCTION;
 	cpuid(op, &eax, &ebx, &ecx, &edx);
 
 	DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
@@ -93,12 +94,12 @@
 		    ((edx >> 16) & 0xFF),
 		    ((edx >> 24) & 0xFF));
 
-	maxLeaf = eax;
+	max_leaf = eax;
 	eax = 0;
 	ebx = 0;
 	ecx = 0;
 	edx = 0;
-	op = HvCpuIdFunctionHvInterface;
+	op = HVCPUID_INTERFACE;
 	cpuid(op, &eax, &ebx, &ecx, &edx);
 
 	DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
@@ -107,12 +108,12 @@
 		    ((eax >> 16) & 0xFF),
 		    ((eax >> 24) & 0xFF));
 
-	if (maxLeaf >= HvCpuIdFunctionMsHvVersion) {
+	if (max_leaf >= HVCPUID_VERSION) {
 		eax = 0;
 		ebx = 0;
 		ecx = 0;
 		edx = 0;
-		op = HvCpuIdFunctionMsHvVersion;
+		op = HVCPUID_VERSION;
 		cpuid(op, &eax, &ebx, &ecx, &edx);
 		DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\
 			    eax,
@@ -122,80 +123,81 @@
 			    edx >> 24,
 			    edx & 0xFFFFFF);
 	}
-	return maxLeaf;
+	return max_leaf;
 }
 
 /*
- * HvDoHypercall - Invoke the specified hypercall
+ * do_hypercall- Invoke the specified hypercall
  */
-static u64 HvDoHypercall(u64 Control, void *Input, void *Output)
+static u64 do_hypercall(u64 control, void *input, void *output)
 {
 #ifdef CONFIG_X86_64
-	u64 hvStatus = 0;
-	u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
-	u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
-	volatile void *hypercallPage = gHvContext.HypercallPage;
+	u64 hv_status = 0;
+	u64 input_address = (input) ? virt_to_phys(input) : 0;
+	u64 output_address = (output) ? virt_to_phys(output) : 0;
+	volatile void *hypercall_page = hv_context.hypercall_page;
 
 	DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p "
 		   "output phys %llx virt %p hypercall %p>",
-		   Control, inputAddress, Input,
-		   outputAddress, Output, hypercallPage);
+		   control, input_address, input,
+		   output_address, output, hypercall_page);
 
-	__asm__ __volatile__("mov %0, %%r8" : : "r" (outputAddress) : "r8");
-	__asm__ __volatile__("call *%3" : "=a" (hvStatus) :
-			     "c" (Control), "d" (inputAddress),
-			     "m" (hypercallPage));
+	__asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
+	__asm__ __volatile__("call *%3" : "=a" (hv_status) :
+			     "c" (control), "d" (input_address),
+			     "m" (hypercall_page));
 
-	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",  hvStatus);
+	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",  hv_status);
 
-	return hvStatus;
+	return hv_status;
 
 #else
 
-	u32 controlHi = Control >> 32;
-	u32 controlLo = Control & 0xFFFFFFFF;
-	u32 hvStatusHi = 1;
-	u32 hvStatusLo = 1;
-	u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
-	u32 inputAddressHi = inputAddress >> 32;
-	u32 inputAddressLo = inputAddress & 0xFFFFFFFF;
-	u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
-	u32 outputAddressHi = outputAddress >> 32;
-	u32 outputAddressLo = outputAddress & 0xFFFFFFFF;
-	volatile void *hypercallPage = gHvContext.HypercallPage;
+	u32 control_hi = control >> 32;
+	u32 control_lo = control & 0xFFFFFFFF;
+	u32 hv_status_hi = 1;
+	u32 hv_status_lo = 1;
+	u64 input_address = (input) ? virt_to_phys(input) : 0;
+	u32 input_address_hi = input_address >> 32;
+	u32 input_address_lo = input_address & 0xFFFFFFFF;
+	u64 output_address = (output) ? virt_to_phys(output) : 0;
+	u32 output_address_hi = output_address >> 32;
+	u32 output_address_lo = output_address & 0xFFFFFFFF;
+	volatile void *hypercall_page = hv_context.hypercall_page;
 
 	DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
-		   Control, Input, Output);
+		   control, input, output);
 
-	__asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi),
-			      "=a"(hvStatusLo) : "d" (controlHi),
-			      "a" (controlLo), "b" (inputAddressHi),
-			      "c" (inputAddressLo), "D"(outputAddressHi),
-			      "S"(outputAddressLo), "m" (hypercallPage));
+	__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
+			      "=a"(hv_status_lo) : "d" (control_hi),
+			      "a" (control_lo), "b" (input_address_hi),
+			      "c" (input_address_lo), "D"(output_address_hi),
+			      "S"(output_address_lo), "m" (hypercall_page));
 
 	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",
-		   hvStatusLo | ((u64)hvStatusHi << 32));
+		   hv_status_lo | ((u64)hv_status_hi << 32));
 
-	return hvStatusLo | ((u64)hvStatusHi << 32);
+	return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
 
 /*
- * HvInit - Main initialization routine.
+ * hv_init - Main initialization routine.
  *
  * This routine must be called before any other routines in here are called
  */
-int HvInit(void)
+int hv_init(void)
 {
 	int ret = 0;
-	int maxLeaf;
-	union hv_x64_msr_hypercall_contents hypercallMsr;
-	void *virtAddr = NULL;
+	int max_leaf;
+	union hv_x64_msr_hypercall_contents hypercall_msr;
+	void *virtaddr = NULL;
 
-	memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS);
-	memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS);
+	memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS);
+	memset(hv_context.synic_message_page, 0,
+	       sizeof(void *) * MAX_NUM_CPUS);
 
-	if (!HvQueryHypervisorPresence()) {
+	if (!query_hypervisor_presence()) {
 		DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!");
 		goto Cleanup;
 	}
@@ -203,146 +205,148 @@
 	DPRINT_INFO(VMBUS,
 		    "Windows hypervisor detected! Retrieving more info...");
 
-	maxLeaf = HvQueryHypervisorInfo();
+	max_leaf = query_hypervisor_info();
 	/* HvQueryHypervisorFeatures(maxLeaf); */
 
 	/*
 	 * We only support running on top of Hyper-V
 	 */
-	rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
+	rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
 
-	if (gHvContext.GuestId != 0) {
+	if (hv_context.guestid != 0) {
 		DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
-				gHvContext.GuestId);
+				hv_context.guestid);
 		goto Cleanup;
 	}
 
 	/* Write our OS info */
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
-	gHvContext.GuestId = HV_LINUX_GUEST_ID;
+	hv_context.guestid = HV_LINUX_GUEST_ID;
 
 	/* See if the hypercall page is already set */
-	rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
 	/*
 	* Allocate the hypercall page memory
-	* virtAddr = osd_PageAlloc(1);
+	* virtaddr = osd_page_alloc(1);
 	*/
-	virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
+	virtaddr = osd_virtual_alloc_exec(PAGE_SIZE);
 
-	if (!virtAddr) {
+	if (!virtaddr) {
 		DPRINT_ERR(VMBUS,
 			   "unable to allocate hypercall page!!");
 		goto Cleanup;
 	}
 
-	hypercallMsr.Enable = 1;
+	hypercall_msr.enable = 1;
 
-	hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
-	wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+	hypercall_msr.guest_physical_address = vmalloc_to_pfn(virtaddr);
+	wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
 	/* Confirm that hypercall page did get setup. */
-	hypercallMsr.AsUINT64 = 0;
-	rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+	hypercall_msr.as_uint64 = 0;
+	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-	if (!hypercallMsr.Enable) {
+	if (!hypercall_msr.enable) {
 		DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
 		goto Cleanup;
 	}
 
-	gHvContext.HypercallPage = virtAddr;
+	hv_context.hypercall_page = virtaddr;
 
 	DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
-		    gHvContext.HypercallPage,
-		    (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
+		    hv_context.hypercall_page,
+		    (u64)hypercall_msr.guest_physical_address << PAGE_SHIFT);
 
 	/* Setup the global signal event param for the signal event hypercall */
-	gHvContext.SignalEventBuffer =
+	hv_context.signal_event_buffer =
 			kmalloc(sizeof(struct hv_input_signal_event_buffer),
 				GFP_KERNEL);
-	if (!gHvContext.SignalEventBuffer)
+	if (!hv_context.signal_event_buffer)
 		goto Cleanup;
 
-	gHvContext.SignalEventParam =
+	hv_context.signal_event_param =
 		(struct hv_input_signal_event *)
-			(ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer,
+			(ALIGN_UP((unsigned long)
+				  hv_context.signal_event_buffer,
 				  HV_HYPERCALL_PARAM_ALIGN));
-	gHvContext.SignalEventParam->ConnectionId.Asu32 = 0;
-	gHvContext.SignalEventParam->ConnectionId.u.Id =
+	hv_context.signal_event_param->connectionid.asu32 = 0;
+	hv_context.signal_event_param->connectionid.u.id =
 						VMBUS_EVENT_CONNECTION_ID;
-	gHvContext.SignalEventParam->FlagNumber = 0;
-	gHvContext.SignalEventParam->RsvdZ = 0;
+	hv_context.signal_event_param->flag_number = 0;
+	hv_context.signal_event_param->rsvdz = 0;
 
 	return ret;
 
 Cleanup:
-	if (virtAddr) {
-		if (hypercallMsr.Enable) {
-			hypercallMsr.AsUINT64 = 0;
-			wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+	if (virtaddr) {
+		if (hypercall_msr.enable) {
+			hypercall_msr.as_uint64 = 0;
+			wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 		}
 
-		vfree(virtAddr);
+		vfree(virtaddr);
 	}
 	ret = -1;
 	return ret;
 }
 
 /*
- * HvCleanup - Cleanup routine.
+ * hv_cleanup - Cleanup routine.
  *
  * This routine is called normally during driver unloading or exiting.
  */
-void HvCleanup(void)
+void hv_cleanup(void)
 {
-	union hv_x64_msr_hypercall_contents hypercallMsr;
+	union hv_x64_msr_hypercall_contents hypercall_msr;
 
-	kfree(gHvContext.SignalEventBuffer);
-	gHvContext.SignalEventBuffer = NULL;
-	gHvContext.SignalEventParam = NULL;
+	kfree(hv_context.signal_event_buffer);
+	hv_context.signal_event_buffer = NULL;
+	hv_context.signal_event_param = NULL;
 
-	if (gHvContext.HypercallPage) {
-		hypercallMsr.AsUINT64 = 0;
-		wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
-		vfree(gHvContext.HypercallPage);
-		gHvContext.HypercallPage = NULL;
+	if (hv_context.hypercall_page) {
+		hypercall_msr.as_uint64 = 0;
+		wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+		vfree(hv_context.hypercall_page);
+		hv_context.hypercall_page = NULL;
 	}
 }
 
 /*
- * HvPostMessage - Post a message using the hypervisor message IPC.
+ * hv_post_message - Post a message using the hypervisor message IPC.
  *
  * This involves a hypercall.
  */
-u16 HvPostMessage(union hv_connection_id connectionId,
-		  enum hv_message_type messageType,
-		  void *payload, size_t payloadSize)
+u16 hv_post_message(union hv_connection_id connection_id,
+		  enum hv_message_type message_type,
+		  void *payload, size_t payload_size)
 {
-	struct alignedInput {
+	struct aligned_input {
 		u64 alignment8;
 		struct hv_input_post_message msg;
 	};
 
-	struct hv_input_post_message *alignedMsg;
+	struct hv_input_post_message *aligned_msg;
 	u16 status;
 	unsigned long addr;
 
-	if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
+	if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
 		return -1;
 
-	addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC);
+	addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC);
 	if (!addr)
 		return -1;
 
-	alignedMsg = (struct hv_input_post_message *)
+	aligned_msg = (struct hv_input_post_message *)
 			(ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN));
 
-	alignedMsg->ConnectionId = connectionId;
-	alignedMsg->MessageType = messageType;
-	alignedMsg->PayloadSize = payloadSize;
-	memcpy((void *)alignedMsg->Payload, payload, payloadSize);
+	aligned_msg->connectionid = connection_id;
+	aligned_msg->message_type = message_type;
+	aligned_msg->payload_size = payload_size;
+	memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-	status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF;
+	status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
+		& 0xFFFF;
 
 	kfree((void *)addr);
 
@@ -351,38 +355,40 @@
 
 
 /*
- * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC.
+ * hv_signal_event -
+ * Signal an event on the specified connection using the hypervisor event IPC.
  *
  * This involves a hypercall.
  */
-u16 HvSignalEvent(void)
+u16 hv_signal_event(void)
 {
 	u16 status;
 
-	status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam,
+	status = do_hypercall(HVCALL_SIGNAL_EVENT,
+			       hv_context.signal_event_param,
 			       NULL) & 0xFFFF;
 	return status;
 }
 
 /*
- * HvSynicInit - Initialize the Synthethic Interrupt Controller.
+ * hv_synic_init - Initialize the Synthethic Interrupt Controller.
  *
  * If it is already initialized by another entity (ie x2v shim), we need to
  * retrieve the initialized message and event pages.  Otherwise, we create and
  * initialize the message and event pages.
  */
-void HvSynicInit(void *irqarg)
+void hv_synic_init(void *irqarg)
 {
 	u64 version;
 	union hv_synic_simp simp;
 	union hv_synic_siefp siefp;
-	union hv_synic_sint sharedSint;
+	union hv_synic_sint shared_sint;
 	union hv_synic_scontrol sctrl;
 
-	u32 irqVector = *((u32 *)(irqarg));
+	u32 irq_vector = *((u32 *)(irqarg));
 	int cpu = smp_processor_id();
 
-	if (!gHvContext.HypercallPage)
+	if (!hv_context.hypercall_page)
 		return;
 
 	/* Check the version */
@@ -390,110 +396,112 @@
 
 	DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
 
-	gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
+	hv_context.synic_message_page[cpu] =
+		(void *)get_zeroed_page(GFP_ATOMIC);
 
-	if (gHvContext.synICMessagePage[cpu] == NULL) {
+	if (hv_context.synic_message_page[cpu] == NULL) {
 		DPRINT_ERR(VMBUS,
 			   "unable to allocate SYNIC message page!!");
 		goto Cleanup;
 	}
 
-	gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
+	hv_context.synic_event_page[cpu] =
+		(void *)get_zeroed_page(GFP_ATOMIC);
 
-	if (gHvContext.synICEventPage[cpu] == NULL) {
+	if (hv_context.synic_event_page[cpu] == NULL) {
 		DPRINT_ERR(VMBUS,
 			   "unable to allocate SYNIC event page!!");
 		goto Cleanup;
 	}
 
 	/* Setup the Synic's message page */
-	rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
-	simp.SimpEnabled = 1;
-	simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
+	rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
+	simp.simp_enabled = 1;
+	simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu])
 		>> PAGE_SHIFT;
 
-	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64);
+	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.as_uint64);
 
-	wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
 
 	/* Setup the Synic's event page */
-	rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
-	siefp.SiefpEnabled = 1;
-	siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
+	rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
+	siefp.siefp_enabled = 1;
+	siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu])
 		>> PAGE_SHIFT;
 
-	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64);
+	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.as_uint64);
 
-	wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
 
 	/* Setup the interception SINT. */
 	/* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
-	/*	  interceptionSint.AsUINT64); */
+	/*	  interceptionSint.as_uint64); */
 
 	/* Setup the shared SINT. */
-	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
-	sharedSint.AsUINT64 = 0;
-	sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
-	sharedSint.Masked = false;
-	sharedSint.AutoEoi = true;
+	shared_sint.as_uint64 = 0;
+	shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
+	shared_sint.masked = false;
+	shared_sint.auto_eoi = true;
 
 	DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx",
-		   sharedSint.AsUINT64);
+		   shared_sint.as_uint64);
 
-	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
 	/* Enable the global synic bit */
-	rdmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
-	sctrl.Enable = 1;
+	rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
+	sctrl.enable = 1;
 
-	wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
+	wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
 
-	gHvContext.SynICInitialized = true;
+	hv_context.synic_initialized = true;
 	return;
 
 Cleanup:
-	if (gHvContext.synICEventPage[cpu])
-		osd_PageFree(gHvContext.synICEventPage[cpu], 1);
+	if (hv_context.synic_event_page[cpu])
+		osd_page_free(hv_context.synic_event_page[cpu], 1);
 
-	if (gHvContext.synICMessagePage[cpu])
-		osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
+	if (hv_context.synic_message_page[cpu])
+		osd_page_free(hv_context.synic_message_page[cpu], 1);
 	return;
 }
 
 /*
- * HvSynicCleanup - Cleanup routine for HvSynicInit().
+ * hv_synic_cleanup - Cleanup routine for hv_synic_init().
  */
-void HvSynicCleanup(void *arg)
+void hv_synic_cleanup(void *arg)
 {
-	union hv_synic_sint sharedSint;
+	union hv_synic_sint shared_sint;
 	union hv_synic_simp simp;
 	union hv_synic_siefp siefp;
 	int cpu = smp_processor_id();
 
-	if (!gHvContext.SynICInitialized)
+	if (!hv_context.synic_initialized)
 		return;
 
-	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
-	sharedSint.Masked = 1;
+	shared_sint.masked = 1;
 
 	/* Need to correctly cleanup in the case of SMP!!! */
 	/* Disable the interrupt */
-	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
-	rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
-	simp.SimpEnabled = 0;
-	simp.BaseSimpGpa = 0;
+	rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
+	simp.simp_enabled = 0;
+	simp.base_simp_gpa = 0;
 
-	wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
 
-	rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
-	siefp.SiefpEnabled = 0;
-	siefp.BaseSiefpGpa = 0;
+	rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
+	siefp.siefp_enabled = 0;
+	siefp.base_siefp_gpa = 0;
 
-	wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
 
-	osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
-	osd_PageFree(gHvContext.synICEventPage[cpu], 1);
+	osd_page_free(hv_context.synic_message_page[cpu], 1);
+	osd_page_free(hv_context.synic_event_page[cpu], 1);
 }
diff --git a/drivers/staging/hv/hv.h b/drivers/staging/hv/hv.h
index 41f5ebb..829aff81 100644
--- a/drivers/staging/hv/hv.h
+++ b/drivers/staging/hv/hv.h
@@ -92,49 +92,49 @@
 
 
 struct hv_input_signal_event_buffer {
-	u64 Align8;
-	struct hv_input_signal_event Event;
+	u64 align8;
+	struct hv_input_signal_event event;
 };
 
 struct hv_context {
 	/* We only support running on top of Hyper-V
 	* So at this point this really can only contain the Hyper-V ID
 	*/
-	u64 GuestId;
+	u64 guestid;
 
-	void *HypercallPage;
+	void *hypercall_page;
 
-	bool SynICInitialized;
+	bool synic_initialized;
 
 	/*
 	 * This is used as an input param to HvCallSignalEvent hypercall. The
 	 * input param is immutable in our usage and must be dynamic mem (vs
 	 * stack or global). */
-	struct hv_input_signal_event_buffer *SignalEventBuffer;
+	struct hv_input_signal_event_buffer *signal_event_buffer;
 	/* 8-bytes aligned of the buffer above */
-	struct hv_input_signal_event *SignalEventParam;
+	struct hv_input_signal_event *signal_event_param;
 
-	void *synICMessagePage[MAX_NUM_CPUS];
-	void *synICEventPage[MAX_NUM_CPUS];
+	void *synic_message_page[MAX_NUM_CPUS];
+	void *synic_event_page[MAX_NUM_CPUS];
 };
 
-extern struct hv_context gHvContext;
+extern struct hv_context hv_context;
 
 
 /* Hv Interface */
 
-extern int HvInit(void);
+extern int hv_init(void);
 
-extern void HvCleanup(void);
+extern void hv_cleanup(void);
 
-extern u16 HvPostMessage(union hv_connection_id connectionId,
-			 enum hv_message_type messageType,
-			 void *payload, size_t payloadSize);
+extern u16 hv_post_message(union hv_connection_id connection_id,
+			 enum hv_message_type message_type,
+			 void *payload, size_t payload_size);
 
-extern u16 HvSignalEvent(void);
+extern u16 hv_signal_event(void);
 
-extern void HvSynicInit(void *irqarg);
+extern void hv_synic_init(void *irqarg);
 
-extern void HvSynicCleanup(void *arg);
+extern void hv_synic_cleanup(void *arg);
 
 #endif /* __HV_H__ */
diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h
index 9eb818e..70e863a 100644
--- a/drivers/staging/hv/hv_api.h
+++ b/drivers/staging/hv/hv_api.h
@@ -510,21 +510,21 @@
 
 /*
  * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
- * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
+ * is set by CPUID(HVCPUID_VERSION_FEATURES).
  */
 enum hv_cpuid_function {
-	HvCpuIdFunctionVersionAndFeatures		= 0x00000001,
-	HvCpuIdFunctionHvVendorAndMaxFunction		= 0x40000000,
-	HvCpuIdFunctionHvInterface			= 0x40000001,
+	HVCPUID_VERSION_FEATURES		= 0x00000001,
+	HVCPUID_VENDOR_MAXFUNCTION		= 0x40000000,
+	HVCPUID_INTERFACE			= 0x40000001,
 
 	/*
 	 * The remaining functions depend on the value of
-	 * HvCpuIdFunctionInterface
+	 * HVCPUID_INTERFACE
 	 */
-	HvCpuIdFunctionMsHvVersion			= 0x40000002,
-	HvCpuIdFunctionMsHvFeatures			= 0x40000003,
-	HvCpuIdFunctionMsHvEnlightenmentInformation	= 0x40000004,
-	HvCpuIdFunctionMsHvImplementationLimits		= 0x40000005,
+	HVCPUID_VERSION			= 0x40000002,
+	HVCPUID_FEATURES			= 0x40000003,
+	HVCPUID_ENLIGHTENMENT_INFO	= 0x40000004,
+	HVCPUID_IMPLEMENTATION_LIMITS		= 0x40000005,
 };
 
 /* Define the virtual APIC registers */
@@ -575,30 +575,30 @@
 
 /* Define hypervisor message types. */
 enum hv_message_type {
-	HvMessageTypeNone			= 0x00000000,
+	HVMSG_NONE			= 0x00000000,
 
 	/* Memory access messages. */
-	HvMessageTypeUnmappedGpa		= 0x80000000,
-	HvMessageTypeGpaIntercept		= 0x80000001,
+	HVMSG_UNMAPPED_GPA		= 0x80000000,
+	HVMSG_GPA_INTERCEPT		= 0x80000001,
 
 	/* Timer notification messages. */
-	HvMessageTimerExpired			= 0x80000010,
+	HVMSG_TIMER_EXPIRED			= 0x80000010,
 
 	/* Error messages. */
-	HvMessageTypeInvalidVpRegisterValue	= 0x80000020,
-	HvMessageTypeUnrecoverableException	= 0x80000021,
-	HvMessageTypeUnsupportedFeature		= 0x80000022,
+	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
+	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
+	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
 
 	/* Trace buffer complete messages. */
-	HvMessageTypeEventLogBufferComplete	= 0x80000040,
+	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
 
 	/* Platform-specific processor intercept messages. */
-	HvMessageTypeX64IoPortIntercept		= 0x80010000,
-	HvMessageTypeX64MsrIntercept		= 0x80010001,
-	HvMessageTypeX64CpuidIntercept		= 0x80010002,
-	HvMessageTypeX64ExceptionIntercept	= 0x80010003,
-	HvMessageTypeX64ApicEoi			= 0x80010004,
-	HvMessageTypeX64LegacyFpError		= 0x80010005
+	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
+	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
+	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
+	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
+	HVMSG_X64_APIC_EOI			= 0x80010004,
+	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
 };
 
 /* Define the number of synthetic interrupt sources. */
@@ -610,103 +610,103 @@
 
 /* Define connection identifier type. */
 union hv_connection_id {
-	u32 Asu32;
+	u32 asu32;
 	struct {
-		u32 Id:24;
-		u32 Reserved:8;
+		u32 id:24;
+		u32 reserved:8;
 	} u;
 };
 
 /* Define port identifier type. */
 union hv_port_id {
-	u32 Asu32;
+	u32 asu32;
 	struct {
-		u32 Id:24;
-		u32 Reserved:8;
+		u32 id:24;
+		u32 reserved:8;
 	} u ;
 };
 
 /* Define port type. */
 enum hv_port_type {
-	HvPortTypeMessage	= 1,
-	HvPortTypeEvent		= 2,
-	HvPortTypeMonitor	= 3
+	HVPORT_MSG	= 1,
+	HVPORT_EVENT		= 2,
+	HVPORT_MONITOR	= 3
 };
 
 /* Define port information structure. */
 struct hv_port_info {
-	enum hv_port_type PortType;
-	u32 Padding;
+	enum hv_port_type port_type;
+	u32 padding;
 	union {
 		struct {
-			u32 TargetSint;
-			u32 TargetVp;
-			u64 RsvdZ;
-		} MessagePortInfo;
+			u32 target_sint;
+			u32 target_vp;
+			u64 rsvdz;
+		} message_port_info;
 		struct {
-			u32 TargetSint;
-			u32 TargetVp;
-			u16 BaseFlagNumber;
-			u16 FlagCount;
-			u32 RsvdZ;
-		} EventPortInfo;
+			u32 target_sint;
+			u32 target_vp;
+			u16 base_flag_bumber;
+			u16 flag_count;
+			u32 rsvdz;
+		} event_port_info;
 		struct {
-			u64 MonitorAddress;
-			u64 RsvdZ;
-		} MonitorPortInfo;
+			u64 monitor_address;
+			u64 rsvdz;
+		} monitor_port_info;
 	};
 };
 
 struct hv_connection_info {
-	enum hv_port_type PortType;
-	u32 Padding;
+	enum hv_port_type port_type;
+	u32 padding;
 	union {
 		struct {
-			u64 RsvdZ;
-		} MessageConnectionInfo;
+			u64 rsvdz;
+		} message_connection_info;
 		struct {
-			u64 RsvdZ;
-		} EventConnectionInfo;
+			u64 rsvdz;
+		} event_connection_info;
 		struct {
-			u64 MonitorAddress;
-		} MonitorConnectionInfo;
+			u64 monitor_address;
+		} monitor_connection_info;
 	};
 };
 
 /* Define synthetic interrupt controller message flags. */
 union hv_message_flags {
-	u8 Asu8;
+	u8 asu8;
 	struct {
-		u8 MessagePending:1;
-		u8 Reserved:7;
+		u8 msg_pending:1;
+		u8 reserved:7;
 	};
 };
 
 /* Define synthetic interrupt controller message header. */
 struct hv_message_header {
-	enum hv_message_type MessageType;
-	u8 PayloadSize;
-	union hv_message_flags MessageFlags;
-	u8 Reserved[2];
+	enum hv_message_type message_type;
+	u8 payload_size;
+	union hv_message_flags message_flags;
+	u8 reserved[2];
 	union {
-		u64 Sender;
-		union hv_port_id Port;
+		u64 sender;
+		union hv_port_id port;
 	};
 };
 
 /* Define timer message payload structure. */
 struct hv_timer_message_payload {
-	u32 TimerIndex;
-	u32 Reserved;
-	u64 ExpirationTime;	/* When the timer expired */
-	u64 DeliveryTime;	/* When the message was delivered */
+	u32 timer_index;
+	u32 reserved;
+	u64 expiration_time;	/* When the timer expired */
+	u64 delivery_time;	/* When the message was delivered */
 };
 
 /* Define synthetic interrupt controller message format. */
 struct hv_message {
-	struct hv_message_header Header;
+	struct hv_message_header header;
 	union {
-		u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 	} u ;
 };
 
@@ -715,82 +715,82 @@
 
 /* Define the synthetic interrupt message page layout. */
 struct hv_message_page {
-	struct hv_message SintMessage[HV_SYNIC_SINT_COUNT];
+	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
 };
 
 /* Define the synthetic interrupt controller event flags format. */
 union hv_synic_event_flags {
-	u8 Flags8[HV_EVENT_FLAGS_BYTE_COUNT];
-	u32 Flags32[HV_EVENT_FLAGS_DWORD_COUNT];
+	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
+	u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
 };
 
 /* Define the synthetic interrupt flags page layout. */
 struct hv_synic_event_flags_page {
-	union hv_synic_event_flags SintEventFlags[HV_SYNIC_SINT_COUNT];
+	union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT];
 };
 
 /* Define SynIC control register. */
 union hv_synic_scontrol {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u64 Enable:1;
-		u64 Reserved:63;
+		u64 enable:1;
+		u64 reserved:63;
 	};
 };
 
 /* Define synthetic interrupt source. */
 union hv_synic_sint {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u64 Vector:8;
-		u64 Reserved1:8;
-		u64 Masked:1;
-		u64 AutoEoi:1;
-		u64 Reserved2:46;
+		u64 vector:8;
+		u64 reserved1:8;
+		u64 masked:1;
+		u64 auto_eoi:1;
+		u64 reserved2:46;
 	};
 };
 
 /* Define the format of the SIMP register */
 union hv_synic_simp {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u64 SimpEnabled:1;
-		u64 Preserved:11;
-		u64 BaseSimpGpa:52;
+		u64 simp_enabled:1;
+		u64 preserved:11;
+		u64 base_simp_gpa:52;
 	};
 };
 
 /* Define the format of the SIEFP register */
 union hv_synic_siefp {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u64 SiefpEnabled:1;
-		u64 Preserved:11;
-		u64 BaseSiefpGpa:52;
+		u64 siefp_enabled:1;
+		u64 preserved:11;
+		u64 base_siefp_gpa:52;
 	};
 };
 
 /* Definitions for the monitored notification facility */
 union hv_monitor_trigger_group {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u32 Pending;
-		u32 Armed;
+		u32 pending;
+		u32 armed;
 	};
 };
 
 struct hv_monitor_parameter {
-	union hv_connection_id ConnectionId;
-	u16 FlagNumber;
-	u16 RsvdZ;
+	union hv_connection_id connectionid;
+	u16 flagnumber;
+	u16 rsvdz;
 };
 
 union hv_monitor_trigger_state {
-	u32 Asu32;
+	u32 asu32;
 
 	struct {
-		u32 GroupEnable:4;
-		u32 RsvdZ:28;
+		u32 group_enable:4;
+		u32 rsvdz:28;
 	};
 };
 
@@ -814,42 +814,42 @@
 /* | 840 | Rsvd4[0]                                     | */
 /* ------------------------------------------------------ */
 struct hv_monitor_page {
-	union hv_monitor_trigger_state TriggerState;
-	u32 RsvdZ1;
+	union hv_monitor_trigger_state trigger_state;
+	u32 rsvdz1;
 
-	union hv_monitor_trigger_group TriggerGroup[4];
-	u64 RsvdZ2[3];
+	union hv_monitor_trigger_group trigger_group[4];
+	u64 rsvdz2[3];
 
-	s32 NextCheckTime[4][32];
+	s32 next_checktime[4][32];
 
-	u16 Latency[4][32];
-	u64 RsvdZ3[32];
+	u16 latency[4][32];
+	u64 rsvdz3[32];
 
-	struct hv_monitor_parameter Parameter[4][32];
+	struct hv_monitor_parameter parameter[4][32];
 
-	u8 RsvdZ4[1984];
+	u8 rsvdz4[1984];
 };
 
 /* Declare the various hypercall operations. */
 enum hv_call_code {
-	HvCallPostMessage	= 0x005c,
-	HvCallSignalEvent	= 0x005d,
+	HVCALL_POST_MESSAGE	= 0x005c,
+	HVCALL_SIGNAL_EVENT	= 0x005d,
 };
 
-/* Definition of the HvPostMessage hypercall input structure. */
+/* Definition of the hv_post_message hypercall input structure. */
 struct hv_input_post_message {
-	union hv_connection_id ConnectionId;
-	u32 Reserved;
-	enum hv_message_type MessageType;
-	u32 PayloadSize;
-	u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+	union hv_connection_id connectionid;
+	u32 reserved;
+	enum hv_message_type message_type;
+	u32 payload_size;
+	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
 };
 
-/* Definition of the HvSignalEvent hypercall input structure. */
+/* Definition of the hv_signal_event hypercall input structure. */
 struct hv_input_signal_event {
-	union hv_connection_id ConnectionId;
-	u16 FlagNumber;
-	u16 RsvdZ;
+	union hv_connection_id connectionid;
+	u16 flag_number;
+	u16 rsvdz;
 };
 
 /*
@@ -859,16 +859,16 @@
 
 /* Version info reported by guest OS's */
 enum hv_guest_os_vendor {
-	HvGuestOsVendorMicrosoft	= 0x0001
+	HVGUESTOS_VENDOR_MICROSOFT	= 0x0001
 };
 
 enum hv_guest_os_microsoft_ids {
-	HvGuestOsMicrosoftUndefined	= 0x00,
-	HvGuestOsMicrosoftMSDOS		= 0x01,
-	HvGuestOsMicrosoftWindows3x	= 0x02,
-	HvGuestOsMicrosoftWindows9x	= 0x03,
-	HvGuestOsMicrosoftWindowsNT	= 0x04,
-	HvGuestOsMicrosoftWindowsCE	= 0x05
+	HVGUESTOS_MICROSOFT_UNDEFINED	= 0x00,
+	HVGUESTOS_MICROSOFT_MSDOS		= 0x01,
+	HVGUESTOS_MICROSOFT_WINDOWS3X	= 0x02,
+	HVGUESTOS_MICROSOFT_WINDOWS9X	= 0x03,
+	HVGUESTOS_MICROSOFT_WINDOWSNT	= 0x04,
+	HVGUESTOS_MICROSOFT_WINDOWSCE	= 0x05
 };
 
 /*
@@ -877,14 +877,14 @@
 #define HV_X64_MSR_GUEST_OS_ID	0x40000000
 
 union hv_x64_msr_guest_os_id_contents {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u64 BuildNumber:16;
-		u64 ServiceVersion:8; /* Service Pack, etc. */
-		u64 MinorVersion:8;
-		u64 MajorVersion:8;
-		u64 OsId:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
-		u64 VendorId:16; /* enum hv_guest_os_vendor */
+		u64 build_number:16;
+		u64 service_version:8; /* Service Pack, etc. */
+		u64 minor_version:8;
+		u64 major_version:8;
+		u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
+		u64 vendor_id:16; /* enum hv_guest_os_vendor */
 	};
 };
 
@@ -894,11 +894,11 @@
 #define HV_X64_MSR_HYPERCALL	0x40000001
 
 union hv_x64_msr_hypercall_contents {
-	u64 AsUINT64;
+	u64 as_uint64;
 	struct {
-		u64 Enable:1;
-		u64 Reserved:11;
-		u64 GuestPhysicalAddress:52;
+		u64 enable:1;
+		u64 reserved:11;
+		u64 guest_physical_address:52;
 	};
 };
 
diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c
index a99e900..53e1e29 100644
--- a/drivers/staging/hv/hv_utils.c
+++ b/drivers/staging/hv/hv_utils.c
@@ -268,15 +268,15 @@
 	if (!dmi_check_system(hv_utils_dmi_table))
 		return -ENODEV;
 
-	hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
+	hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
 		&shutdown_onchannelcallback;
 	hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
 
-	hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback =
+	hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
 		&timesync_onchannelcallback;
 	hv_cb_utils[HV_TIMESYNC_MSG].callback = &timesync_onchannelcallback;
 
-	hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback =
+	hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
 		&heartbeat_onchannelcallback;
 	hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
 
@@ -287,15 +287,15 @@
 {
 	printk(KERN_INFO "De-Registered HyperV Utility Driver\n");
 
-	hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
+	hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
 		&chn_cb_negotiate;
 	hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate;
 
-	hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback =
+	hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
 		&chn_cb_negotiate;
 	hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate;
 
-	hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback =
+	hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
 		&chn_cb_negotiate;
 	hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate;
 }
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 4c2632c..8022781 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -221,7 +221,7 @@
 	/* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */
 
 	netDevice->ReceiveBuffer =
-		osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT);
+		osd_page_alloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT);
 	if (!netDevice->ReceiveBuffer) {
 		DPRINT_ERR(NETVSC,
 			   "unable to allocate receive buffer of size %d",
@@ -249,7 +249,7 @@
 		goto Cleanup;
 	}
 
-	/* osd_WaitEventWait(ext->ChannelInitEvent); */
+	/* osd_waitevent_wait(ext->ChannelInitEvent); */
 
 	/* Notify the NetVsp of the gpadl handle */
 	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer...");
@@ -274,7 +274,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(netDevice->ChannelInitEvent);
+	osd_waitevent_wait(netDevice->ChannelInitEvent);
 
 	/* Check the response */
 	if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) {
@@ -350,7 +350,7 @@
 	/* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */
 
 	netDevice->SendBuffer =
-		osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT);
+		osd_page_alloc(netDevice->SendBufferSize >> PAGE_SHIFT);
 	if (!netDevice->SendBuffer) {
 		DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d",
 			   netDevice->SendBufferSize);
@@ -375,7 +375,7 @@
 		goto Cleanup;
 	}
 
-	/* osd_WaitEventWait(ext->ChannelInitEvent); */
+	/* osd_waitevent_wait(ext->ChannelInitEvent); */
 
 	/* Notify the NetVsp of the gpadl handle */
 	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer...");
@@ -400,7 +400,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(netDevice->ChannelInitEvent);
+	osd_waitevent_wait(netDevice->ChannelInitEvent);
 
 	/* Check the response */
 	if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) {
@@ -480,7 +480,7 @@
 		DPRINT_INFO(NETVSC, "Freeing up receive buffer...");
 
 		/* Free up the receive buffer */
-		osd_PageFree(NetDevice->ReceiveBuffer,
+		osd_page_free(NetDevice->ReceiveBuffer,
 			     NetDevice->ReceiveBufferSize >> PAGE_SHIFT);
 		NetDevice->ReceiveBuffer = NULL;
 	}
@@ -553,7 +553,7 @@
 		DPRINT_INFO(NETVSC, "Freeing up send buffer...");
 
 		/* Free up the receive buffer */
-		osd_PageFree(NetDevice->SendBuffer,
+		osd_page_free(NetDevice->SendBuffer,
 			     NetDevice->SendBufferSize >> PAGE_SHIFT);
 		NetDevice->SendBuffer = NULL;
 	}
@@ -597,7 +597,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(netDevice->ChannelInitEvent);
+	osd_waitevent_wait(netDevice->ChannelInitEvent);
 
 	/* Now, check the response */
 	/* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */
@@ -651,7 +651,7 @@
 	 * packet) since our Vmbus always set the
 	 * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
 	 */
-	 /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */
+	 /* osd_waitevent_wait(NetVscChannel->ChannelInitEvent); */
 
 	/* Post the big receive buffer to NetVSP */
 	ret = NetVscInitializeReceiveBufferWithNetVsp(Device);
@@ -710,7 +710,7 @@
 		list_add_tail(&packet->ListEntry,
 			      &netDevice->ReceivePacketList);
 	}
-	netDevice->ChannelInitEvent = osd_WaitEventCreate();
+	netDevice->ChannelInitEvent = osd_waitevent_create();
 	if (!netDevice->ChannelInitEvent) {
 		ret = -ENOMEM;
 		goto Cleanup;
@@ -855,7 +855,7 @@
 		/* Copy the response back */
 		memcpy(&netDevice->ChannelInitPacket, nvspPacket,
 		       sizeof(struct nvsp_message));
-		osd_WaitEventSet(netDevice->ChannelInitEvent);
+		osd_waitevent_set(netDevice->ChannelInitEvent);
 	} else if (nvspPacket->Header.MessageType ==
 		   NvspMessage1TypeSendRNDISPacketComplete) {
 		/* Get the send context */
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c
index 8c3eb27..b699ee2 100644
--- a/drivers/staging/hv/osd.c
+++ b/drivers/staging/hv/osd.c
@@ -49,7 +49,7 @@
 	void *data;
 };
 
-void *osd_VirtualAllocExec(unsigned int size)
+void *osd_virtual_alloc_exec(unsigned int size)
 {
 #ifdef __x86_64__
 	return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC);
@@ -60,7 +60,7 @@
 }
 
 /**
- * osd_PageAlloc() - Allocate pages
+ * osd_page_alloc() - Allocate pages
  * @count:      Total number of Kernel pages you want to allocate
  *
  * Tries to allocate @count number of consecutive free kernel pages.
@@ -68,7 +68,7 @@
  * If successfull it will return pointer to the @count pages.
  * Mainly used by Hyper-V drivers.
  */
-void *osd_PageAlloc(unsigned int count)
+void *osd_page_alloc(unsigned int count)
 {
 	void *p;
 
@@ -85,26 +85,26 @@
 	/* if (p) memset(p, 0, PAGE_SIZE); */
 	/* return p; */
 }
-EXPORT_SYMBOL_GPL(osd_PageAlloc);
+EXPORT_SYMBOL_GPL(osd_page_alloc);
 
 /**
- * osd_PageFree() - Free pages
+ * osd_page_free() - Free pages
  * @page:       Pointer to the first page to be freed
  * @count:      Total number of Kernel pages you free
  *
- * Frees the pages allocated by osd_PageAlloc()
+ * Frees the pages allocated by osd_page_alloc()
  * Mainly used by Hyper-V drivers.
  */
-void osd_PageFree(void *page, unsigned int count)
+void osd_page_free(void *page, unsigned int count)
 {
 	free_pages((unsigned long)page, get_order(count * PAGE_SIZE));
 	/*struct page* p = virt_to_page(page);
 	__free_page(p);*/
 }
-EXPORT_SYMBOL_GPL(osd_PageFree);
+EXPORT_SYMBOL_GPL(osd_page_free);
 
 /**
- * osd_WaitEventCreate() - Create the event queue
+ * osd_waitevent_create() - Create the event queue
  *
  * Allocates memory for a &struct osd_waitevent. And then calls
  * init_waitqueue_head to set up the wait queue for the event.
@@ -114,7 +114,7 @@
  * Returns pointer to &struct osd_waitevent
  * Mainly used by Hyper-V drivers.
  */
-struct osd_waitevent *osd_WaitEventCreate(void)
+struct osd_waitevent *osd_waitevent_create(void)
 {
 	struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent),
 					     GFP_KERNEL);
@@ -125,14 +125,14 @@
 	init_waitqueue_head(&wait->event);
 	return wait;
 }
-EXPORT_SYMBOL_GPL(osd_WaitEventCreate);
+EXPORT_SYMBOL_GPL(osd_waitevent_create);
 
 
 /**
- * osd_WaitEventSet() - Wake up the process
- * @waitEvent: Structure to event to be woken up
+ * osd_waitevent_set() - Wake up the process
+ * @wait_event: Structure to event to be woken up
  *
- * @waitevent is of type &struct osd_waitevent
+ * @wait_event is of type &struct osd_waitevent
  *
  * Wake up the sleeping process so it can do some work.
  * And set condition indicator in &struct osd_waitevent to indicate
@@ -140,18 +140,18 @@
  *
  * Only used by Network and Storage Hyper-V drivers.
  */
-void osd_WaitEventSet(struct osd_waitevent *waitEvent)
+void osd_waitevent_set(struct osd_waitevent *wait_event)
 {
-	waitEvent->condition = 1;
-	wake_up_interruptible(&waitEvent->event);
+	wait_event->condition = 1;
+	wake_up_interruptible(&wait_event->event);
 }
-EXPORT_SYMBOL_GPL(osd_WaitEventSet);
+EXPORT_SYMBOL_GPL(osd_waitevent_set);
 
 /**
- * osd_WaitEventWait() - Wait for event till condition is true
- * @waitEvent: Structure to event to be put to sleep
+ * osd_waitevent_wait() - Wait for event till condition is true
+ * @wait_event: Structure to event to be put to sleep
  *
- * @waitevent is of type &struct osd_waitevent
+ * @wait_event is of type &struct osd_waitevent
  *
  * Set up the process to sleep until waitEvent->condition get true.
  * And set condition indicator in &struct osd_waitevent to indicate
@@ -161,25 +161,25 @@
  *
  * Mainly used by Hyper-V drivers.
  */
-int osd_WaitEventWait(struct osd_waitevent *waitEvent)
+int osd_waitevent_wait(struct osd_waitevent *wait_event)
 {
 	int ret = 0;
 
-	ret = wait_event_interruptible(waitEvent->event,
-				       waitEvent->condition);
-	waitEvent->condition = 0;
+	ret = wait_event_interruptible(wait_event->event,
+				       wait_event->condition);
+	wait_event->condition = 0;
 	return ret;
 }
-EXPORT_SYMBOL_GPL(osd_WaitEventWait);
+EXPORT_SYMBOL_GPL(osd_waitevent_wait);
 
 /**
- * osd_WaitEventWaitEx() - Wait for event or timeout for process wakeup
- * @waitEvent: Structure to event to be put to sleep
- * @TimeoutInMs:       Total number of Milliseconds to wait before waking up
+ * osd_waitevent_waitex() - Wait for event or timeout for process wakeup
+ * @wait_event: Structure to event to be put to sleep
+ * @timeout_in_ms:       Total number of Milliseconds to wait before waking up
  *
- * @waitevent is of type &struct osd_waitevent
+ * @wait_event is of type &struct osd_waitevent
  * Set up the process to sleep until @waitEvent->condition get true or
- * @TimeoutInMs (Time out in Milliseconds) has been reached.
+ * @timeout_in_ms (Time out in Milliseconds) has been reached.
  * And set condition indicator in &struct osd_waitevent to indicate
  * the process is in a sleeping state.
  *
@@ -187,17 +187,17 @@
  *
  * Mainly used by Hyper-V drivers.
  */
-int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, u32 TimeoutInMs)
+int osd_waitevent_waitex(struct osd_waitevent *wait_event, u32 timeout_in_ms)
 {
 	int ret = 0;
 
-	ret = wait_event_interruptible_timeout(waitEvent->event,
-					       waitEvent->condition,
-					       msecs_to_jiffies(TimeoutInMs));
-	waitEvent->condition = 0;
+	ret = wait_event_interruptible_timeout(wait_event->event,
+					       wait_event->condition,
+					       msecs_to_jiffies(timeout_in_ms));
+	wait_event->condition = 0;
 	return ret;
 }
-EXPORT_SYMBOL_GPL(osd_WaitEventWaitEx);
+EXPORT_SYMBOL_GPL(osd_waitevent_waitex);
 
 static void osd_callback_work(struct work_struct *work)
 {
diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h
index ce064e8..cae126f 100644
--- a/drivers/staging/hv/osd.h
+++ b/drivers/staging/hv/osd.h
@@ -50,18 +50,18 @@
 
 /* Osd routines */
 
-extern void *osd_VirtualAllocExec(unsigned int size);
+extern void *osd_virtual_alloc_exec(unsigned int size);
 
-extern void *osd_PageAlloc(unsigned int count);
-extern void osd_PageFree(void *page, unsigned int count);
+extern void *osd_page_alloc(unsigned int count);
+extern void osd_page_free(void *page, unsigned int count);
 
-extern struct osd_waitevent *osd_WaitEventCreate(void);
-extern void osd_WaitEventSet(struct osd_waitevent *waitEvent);
-extern int osd_WaitEventWait(struct osd_waitevent *waitEvent);
+extern struct osd_waitevent *osd_waitevent_create(void);
+extern void osd_waitevent_set(struct osd_waitevent *wait_event);
+extern int osd_waitevent_wait(struct osd_waitevent *wait_event);
 
-/* If >0, waitEvent got signaled. If ==0, timeout. If < 0, error */
-extern int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent,
-			       u32 TimeoutInMs);
+/* If >0, wait_event got signaled. If ==0, timeout. If < 0, error */
+extern int osd_waitevent_waitex(struct osd_waitevent *wait_event,
+			       u32 timeout_in_ms);
 
 int osd_schedule_callback(struct workqueue_struct *wq,
 			  void (*func)(void *),
diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c
index d78c569..4d53392 100644
--- a/drivers/staging/hv/ring_buffer.c
+++ b/drivers/staging/hv/ring_buffer.c
@@ -38,7 +38,7 @@
 /*++
 
 Name:
-	GetRingBufferAvailBytes()
+	get_ringbuffer_availbytes()
 
 Description:
 	Get number of bytes available to read and to write to
@@ -46,33 +46,34 @@
 
 --*/
 static inline void
-GetRingBufferAvailBytes(struct hv_ring_buffer_info *rbi, u32 *read, u32 *write)
+get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
+			  u32 *read, u32 *write)
 {
 	u32 read_loc, write_loc;
 
 	/* Capture the read/write indices before they changed */
-	read_loc = rbi->RingBuffer->ReadIndex;
-	write_loc = rbi->RingBuffer->WriteIndex;
+	read_loc = rbi->ring_buffer->read_index;
+	write_loc = rbi->ring_buffer->write_index;
 
-	*write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->RingDataSize);
-	*read = rbi->RingDataSize - *write;
+	*write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->ring_datasize);
+	*read = rbi->ring_datasize - *write;
 }
 
 /*++
 
 Name:
-	GetNextWriteLocation()
+	get_next_write_location()
 
 Description:
 	Get the next write location for the specified ring buffer
 
 --*/
 static inline u32
-GetNextWriteLocation(struct hv_ring_buffer_info *RingInfo)
+get_next_write_location(struct hv_ring_buffer_info *ring_info)
 {
-	u32 next = RingInfo->RingBuffer->WriteIndex;
+	u32 next = ring_info->ring_buffer->write_index;
 
-	/* ASSERT(next < RingInfo->RingDataSize); */
+	/* ASSERT(next < ring_info->RingDataSize); */
 
 	return next;
 }
@@ -80,34 +81,34 @@
 /*++
 
 Name:
-	SetNextWriteLocation()
+	set_next_write_location()
 
 Description:
 	Set the next write location for the specified ring buffer
 
 --*/
 static inline void
-SetNextWriteLocation(struct hv_ring_buffer_info *RingInfo,
-		     u32 NextWriteLocation)
+set_next_write_location(struct hv_ring_buffer_info *ring_info,
+		     u32 next_write_location)
 {
-	RingInfo->RingBuffer->WriteIndex = NextWriteLocation;
+	ring_info->ring_buffer->write_index = next_write_location;
 }
 
 /*++
 
 Name:
-	GetNextReadLocation()
+	get_next_read_location()
 
 Description:
 	Get the next read location for the specified ring buffer
 
 --*/
 static inline u32
-GetNextReadLocation(struct hv_ring_buffer_info *RingInfo)
+get_next_read_location(struct hv_ring_buffer_info *ring_info)
 {
-	u32 next = RingInfo->RingBuffer->ReadIndex;
+	u32 next = ring_info->ring_buffer->read_index;
 
-	/* ASSERT(next < RingInfo->RingDataSize); */
+	/* ASSERT(next < ring_info->RingDataSize); */
 
 	return next;
 }
@@ -115,7 +116,7 @@
 /*++
 
 Name:
-	GetNextReadLocationWithOffset()
+	get_next_readlocation_withoffset()
 
 Description:
 	Get the next read location + offset for the specified ring buffer.
@@ -123,13 +124,14 @@
 
 --*/
 static inline u32
-GetNextReadLocationWithOffset(struct hv_ring_buffer_info *RingInfo, u32 Offset)
+get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
+				 u32 offset)
 {
-	u32 next = RingInfo->RingBuffer->ReadIndex;
+	u32 next = ring_info->ring_buffer->read_index;
 
-	/* ASSERT(next < RingInfo->RingDataSize); */
-	next += Offset;
-	next %= RingInfo->RingDataSize;
+	/* ASSERT(next < ring_info->RingDataSize); */
+	next += offset;
+	next %= ring_info->ring_datasize;
 
 	return next;
 }
@@ -137,141 +139,145 @@
 /*++
 
 Name:
-	SetNextReadLocation()
+	set_next_read_location()
 
 Description:
 	Set the next read location for the specified ring buffer
 
 --*/
 static inline void
-SetNextReadLocation(struct hv_ring_buffer_info *RingInfo, u32 NextReadLocation)
+set_next_read_location(struct hv_ring_buffer_info *ring_info,
+		    u32 next_read_location)
 {
-	RingInfo->RingBuffer->ReadIndex = NextReadLocation;
+	ring_info->ring_buffer->read_index = next_read_location;
 }
 
 
 /*++
 
 Name:
-	GetRingBuffer()
+	get_ring_buffer()
 
 Description:
 	Get the start of the ring buffer
 
 --*/
 static inline void *
-GetRingBuffer(struct hv_ring_buffer_info *RingInfo)
+get_ring_buffer(struct hv_ring_buffer_info *ring_info)
 {
-	return (void *)RingInfo->RingBuffer->Buffer;
+	return (void *)ring_info->ring_buffer->buffer;
 }
 
 
 /*++
 
 Name:
-	GetRingBufferSize()
+	get_ring_buffersize()
 
 Description:
 	Get the size of the ring buffer
 
 --*/
 static inline u32
-GetRingBufferSize(struct hv_ring_buffer_info *RingInfo)
+get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
 {
-	return RingInfo->RingDataSize;
+	return ring_info->ring_datasize;
 }
 
 /*++
 
 Name:
-	GetRingBufferIndices()
+	get_ring_bufferindices()
 
 Description:
 	Get the read and write indices as u64 of the specified ring buffer
 
 --*/
 static inline u64
-GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo)
+get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
 {
-	return (u64)RingInfo->RingBuffer->WriteIndex << 32;
+	return (u64)ring_info->ring_buffer->write_index << 32;
 }
 
 
 /*++
 
 Name:
-	DumpRingInfo()
+	dump_ring_info()
 
 Description:
 	Dump out to console the ring buffer info
 
 --*/
-void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix)
+void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
 {
-	u32 bytesAvailToWrite;
-	u32 bytesAvailToRead;
+	u32 bytes_avail_towrite;
+	u32 bytes_avail_toread;
 
-	GetRingBufferAvailBytes(RingInfo,
-	&bytesAvailToRead,
-	&bytesAvailToWrite);
+	get_ringbuffer_availbytes(ring_info,
+	&bytes_avail_toread,
+	&bytes_avail_towrite);
 
 	DPRINT(VMBUS,
 		DEBUG_RING_LVL,
 		"%s <<ringinfo %p buffer %p avail write %u "
 		"avail read %u read idx %u write idx %u>>",
-		Prefix,
-		RingInfo,
-		RingInfo->RingBuffer->Buffer,
-		bytesAvailToWrite,
-		bytesAvailToRead,
-		RingInfo->RingBuffer->ReadIndex,
-		RingInfo->RingBuffer->WriteIndex);
+		prefix,
+		ring_info,
+		ring_info->ring_buffer->buffer,
+		bytes_avail_towrite,
+		bytes_avail_toread,
+		ring_info->ring_buffer->read_index,
+		ring_info->ring_buffer->write_index);
 }
 
 
 /* Internal routines */
 
 static u32
-CopyToRingBuffer(
-	struct hv_ring_buffer_info	*RingInfo,
-	u32				StartWriteOffset,
-	void				*Src,
-	u32				SrcLen);
+copyto_ringbuffer(
+	struct hv_ring_buffer_info	*ring_info,
+	u32				start_write_offset,
+	void				*src,
+	u32				srclen);
 
 static u32
-CopyFromRingBuffer(
-	struct hv_ring_buffer_info	*RingInfo,
-	void				*Dest,
-	u32				DestLen,
-	u32				StartReadOffset);
+copyfrom_ringbuffer(
+	struct hv_ring_buffer_info	*ring_info,
+	void				*dest,
+	u32				destlen,
+	u32				start_read_offset);
 
 
 
 /*++
 
 Name:
-	RingBufferGetDebugInfo()
+	ringbuffer_get_debuginfo()
 
 Description:
 	Get various debug metrics for the specified ring buffer
 
 --*/
-void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo,
+void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
 			    struct hv_ring_buffer_debug_info *debug_info)
 {
-	u32 bytesAvailToWrite;
-	u32 bytesAvailToRead;
+	u32 bytes_avail_towrite;
+	u32 bytes_avail_toread;
 
-	if (RingInfo->RingBuffer) {
-		GetRingBufferAvailBytes(RingInfo,
-					&bytesAvailToRead,
-					&bytesAvailToWrite);
+	if (ring_info->ring_buffer) {
+		get_ringbuffer_availbytes(ring_info,
+					&bytes_avail_toread,
+					&bytes_avail_towrite);
 
-		debug_info->BytesAvailToRead = bytesAvailToRead;
-		debug_info->BytesAvailToWrite = bytesAvailToWrite;
-		debug_info->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
-		debug_info->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
-		debug_info->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
+		debug_info->bytes_avail_toread = bytes_avail_toread;
+		debug_info->bytes_avail_towrite = bytes_avail_towrite;
+		debug_info->current_read_index =
+			ring_info->ring_buffer->read_index;
+		debug_info->current_write_index =
+			ring_info->ring_buffer->write_index;
+		debug_info->current_interrupt_mask =
+			ring_info->ring_buffer->interrupt_mask;
 	}
 }
 
@@ -279,40 +285,42 @@
 /*++
 
 Name:
-	GetRingBufferInterruptMask()
+	get_ringbuffer_interrupt_mask()
 
 Description:
 	Get the interrupt mask for the specified ring buffer
 
 --*/
-u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *rbi)
+u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
 {
-	return rbi->RingBuffer->InterruptMask;
+	return rbi->ring_buffer->interrupt_mask;
 }
 
 /*++
 
 Name:
-	RingBufferInit()
+	ringbuffer_init()
 
 Description:
 	Initialize the ring buffer
 
 --*/
-int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer, u32 BufferLen)
+int ringbuffer_init(struct hv_ring_buffer_info *ring_info,
+		   void *buffer, u32 buflen)
 {
 	if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
 		return -EINVAL;
 
-	memset(RingInfo, 0, sizeof(struct hv_ring_buffer_info));
+	memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
 
-	RingInfo->RingBuffer = (struct hv_ring_buffer *)Buffer;
-	RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0;
+	ring_info->ring_buffer = (struct hv_ring_buffer *)buffer;
+	ring_info->ring_buffer->read_index =
+		ring_info->ring_buffer->write_index = 0;
 
-	RingInfo->RingSize = BufferLen;
-	RingInfo->RingDataSize = BufferLen - sizeof(struct hv_ring_buffer);
+	ring_info->ring_size = buflen;
+	ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer);
 
-	spin_lock_init(&RingInfo->ring_lock);
+	spin_lock_init(&ring_info->ring_lock);
 
 	return 0;
 }
@@ -320,97 +328,97 @@
 /*++
 
 Name:
-	RingBufferCleanup()
+	ringbuffer_cleanup()
 
 Description:
 	Cleanup the ring buffer
 
 --*/
-void RingBufferCleanup(struct hv_ring_buffer_info *RingInfo)
+void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
 {
 }
 
 /*++
 
 Name:
-	RingBufferWrite()
+	ringbuffer_write()
 
 Description:
 	Write to the ring buffer
 
 --*/
-int RingBufferWrite(struct hv_ring_buffer_info *OutRingInfo,
+int ringbuffer_write(struct hv_ring_buffer_info *outring_info,
 		    struct scatterlist *sglist, u32 sgcount)
 {
 	int i = 0;
-	u32 byteAvailToWrite;
-	u32 byteAvailToRead;
-	u32 totalBytesToWrite = 0;
+	u32 bytes_avail_towrite;
+	u32 bytes_avail_toread;
+	u32 totalbytes_towrite = 0;
 
 	struct scatterlist *sg;
-	volatile u32 nextWriteLocation;
-	u64 prevIndices = 0;
+	volatile u32 next_write_location;
+	u64 prev_indices = 0;
 	unsigned long flags;
 
 	for_each_sg(sglist, sg, sgcount, i)
 	{
-		totalBytesToWrite += sg->length;
+		totalbytes_towrite += sg->length;
 	}
 
-	totalBytesToWrite += sizeof(u64);
+	totalbytes_towrite += sizeof(u64);
 
-	spin_lock_irqsave(&OutRingInfo->ring_lock, flags);
+	spin_lock_irqsave(&outring_info->ring_lock, flags);
 
-	GetRingBufferAvailBytes(OutRingInfo,
-				&byteAvailToRead,
-				&byteAvailToWrite);
+	get_ringbuffer_availbytes(outring_info,
+				&bytes_avail_toread,
+				&bytes_avail_towrite);
 
-	DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite);
+	DPRINT_DBG(VMBUS, "Writing %u bytes...", totalbytes_towrite);
 
-	/* DumpRingInfo(OutRingInfo, "BEFORE "); */
+	/* Dumpring_info(Outring_info, "BEFORE "); */
 
 	/* If there is only room for the packet, assume it is full. */
 	/* Otherwise, the next time around, we think the ring buffer */
 	/* is empty since the read index == write index */
-	if (byteAvailToWrite <= totalBytesToWrite) {
+	if (bytes_avail_towrite <= totalbytes_towrite) {
 		DPRINT_DBG(VMBUS,
 			"No more space left on outbound ring buffer "
 			"(needed %u, avail %u)",
-			totalBytesToWrite,
-			byteAvailToWrite);
+			totalbytes_towrite,
+			bytes_avail_towrite);
 
-		spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
+		spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 		return -1;
 	}
 
 	/* Write to the ring buffer */
-	nextWriteLocation = GetNextWriteLocation(OutRingInfo);
+	next_write_location = get_next_write_location(outring_info);
 
 	for_each_sg(sglist, sg, sgcount, i)
 	{
-		nextWriteLocation = CopyToRingBuffer(OutRingInfo,
-						     nextWriteLocation,
+		next_write_location = copyto_ringbuffer(outring_info,
+						     next_write_location,
 						     sg_virt(sg),
 						     sg->length);
 	}
 
 	/* Set previous packet start */
-	prevIndices = GetRingBufferIndices(OutRingInfo);
+	prev_indices = get_ring_bufferindices(outring_info);
 
-	nextWriteLocation = CopyToRingBuffer(OutRingInfo,
-					     nextWriteLocation,
-					     &prevIndices,
+	next_write_location = copyto_ringbuffer(outring_info,
+					     next_write_location,
+					     &prev_indices,
 					     sizeof(u64));
 
 	/* Make sure we flush all writes before updating the writeIndex */
 	mb();
 
 	/* Now, update the write location */
-	SetNextWriteLocation(OutRingInfo, nextWriteLocation);
+	set_next_write_location(outring_info, next_write_location);
 
-	/* DumpRingInfo(OutRingInfo, "AFTER "); */
+	/* Dumpring_info(Outring_info, "AFTER "); */
 
-	spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
+	spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 	return 0;
 }
 
@@ -418,47 +426,48 @@
 /*++
 
 Name:
-	RingBufferPeek()
+	ringbuffer_peek()
 
 Description:
 	Read without advancing the read index
 
 --*/
-int RingBufferPeek(struct hv_ring_buffer_info *InRingInfo, void *Buffer, u32 BufferLen)
+int ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
+		   void *Buffer, u32 buflen)
 {
-	u32 bytesAvailToWrite;
-	u32 bytesAvailToRead;
-	u32 nextReadLocation = 0;
+	u32 bytes_avail_towrite;
+	u32 bytes_avail_toread;
+	u32 next_read_location = 0;
 	unsigned long flags;
 
-	spin_lock_irqsave(&InRingInfo->ring_lock, flags);
+	spin_lock_irqsave(&Inring_info->ring_lock, flags);
 
-	GetRingBufferAvailBytes(InRingInfo,
-				&bytesAvailToRead,
-				&bytesAvailToWrite);
+	get_ringbuffer_availbytes(Inring_info,
+				&bytes_avail_toread,
+				&bytes_avail_towrite);
 
 	/* Make sure there is something to read */
-	if (bytesAvailToRead < BufferLen) {
+	if (bytes_avail_toread < buflen) {
 		/* DPRINT_DBG(VMBUS,
 			"got callback but not enough to read "
 			"<avail to read %d read size %d>!!",
-			bytesAvailToRead,
+			bytes_avail_toread,
 			BufferLen); */
 
-		spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+		spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
 
 		return -1;
 	}
 
 	/* Convert to byte offset */
-	nextReadLocation = GetNextReadLocation(InRingInfo);
+	next_read_location = get_next_read_location(Inring_info);
 
-	nextReadLocation = CopyFromRingBuffer(InRingInfo,
+	next_read_location = copyfrom_ringbuffer(Inring_info,
 						Buffer,
-						BufferLen,
-						nextReadLocation);
+						buflen,
+						next_read_location);
 
-	spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+	spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
 
 	return 0;
 }
@@ -467,58 +476,59 @@
 /*++
 
 Name:
-	RingBufferRead()
+	ringbuffer_read()
 
 Description:
 	Read and advance the read index
 
 --*/
-int RingBufferRead(struct hv_ring_buffer_info *InRingInfo, void *Buffer,
-		   u32 BufferLen, u32 Offset)
+int ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
+		   u32 buflen, u32 offset)
 {
-	u32 bytesAvailToWrite;
-	u32 bytesAvailToRead;
-	u32 nextReadLocation = 0;
-	u64 prevIndices = 0;
+	u32 bytes_avail_towrite;
+	u32 bytes_avail_toread;
+	u32 next_read_location = 0;
+	u64 prev_indices = 0;
 	unsigned long flags;
 
-	if (BufferLen <= 0)
+	if (buflen <= 0)
 		return -EINVAL;
 
-	spin_lock_irqsave(&InRingInfo->ring_lock, flags);
+	spin_lock_irqsave(&inring_info->ring_lock, flags);
 
-	GetRingBufferAvailBytes(InRingInfo,
-				&bytesAvailToRead,
-				&bytesAvailToWrite);
+	get_ringbuffer_availbytes(inring_info,
+				&bytes_avail_toread,
+				&bytes_avail_towrite);
 
-	DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen);
+	DPRINT_DBG(VMBUS, "Reading %u bytes...", buflen);
 
-	/* DumpRingInfo(InRingInfo, "BEFORE "); */
+	/* Dumpring_info(Inring_info, "BEFORE "); */
 
 	/* Make sure there is something to read */
-	if (bytesAvailToRead < BufferLen) {
+	if (bytes_avail_toread < buflen) {
 		DPRINT_DBG(VMBUS,
 			"got callback but not enough to read "
 			"<avail to read %d read size %d>!!",
-			bytesAvailToRead,
-			BufferLen);
+			bytes_avail_toread,
+			buflen);
 
-		spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+		spin_unlock_irqrestore(&inring_info->ring_lock, flags);
 
 		return -1;
 	}
 
-	nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset);
+	next_read_location =
+		get_next_readlocation_withoffset(inring_info, offset);
 
-	nextReadLocation = CopyFromRingBuffer(InRingInfo,
-						Buffer,
-						BufferLen,
-						nextReadLocation);
+	next_read_location = copyfrom_ringbuffer(inring_info,
+						buffer,
+						buflen,
+						next_read_location);
 
-	nextReadLocation = CopyFromRingBuffer(InRingInfo,
-						&prevIndices,
+	next_read_location = copyfrom_ringbuffer(inring_info,
+						&prev_indices,
 						sizeof(u64),
-						nextReadLocation);
+						next_read_location);
 
 	/* Make sure all reads are done before we update the read index since */
 	/* the writer may start writing to the read area once the read index */
@@ -526,11 +536,11 @@
 	mb();
 
 	/* Update the read index */
-	SetNextReadLocation(InRingInfo, nextReadLocation);
+	set_next_read_location(inring_info, next_read_location);
 
-	/* DumpRingInfo(InRingInfo, "AFTER "); */
+	/* Dumpring_info(Inring_info, "AFTER "); */
 
-	spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+	spin_unlock_irqrestore(&inring_info->ring_lock, flags);
 
 	return 0;
 }
@@ -539,7 +549,7 @@
 /*++
 
 Name:
-	CopyToRingBuffer()
+	copyto_ringbuffer()
 
 Description:
 	Helper routine to copy from source to ring buffer.
@@ -547,37 +557,37 @@
 
 --*/
 static u32
-CopyToRingBuffer(
-	struct hv_ring_buffer_info	*RingInfo,
-	u32				StartWriteOffset,
-	void				*Src,
-	u32				SrcLen)
+copyto_ringbuffer(
+	struct hv_ring_buffer_info	*ring_info,
+	u32				start_write_offset,
+	void				*src,
+	u32				srclen)
 {
-	void *ringBuffer = GetRingBuffer(RingInfo);
-	u32 ringBufferSize = GetRingBufferSize(RingInfo);
-	u32 fragLen;
+	void *ring_buffer = get_ring_buffer(ring_info);
+	u32 ring_buffer_size = get_ring_buffersize(ring_info);
+	u32 frag_len;
 
 	/* wrap-around detected! */
-	if (SrcLen > ringBufferSize - StartWriteOffset) {
+	if (srclen > ring_buffer_size - start_write_offset) {
 		DPRINT_DBG(VMBUS, "wrap-around detected!");
 
-		fragLen = ringBufferSize - StartWriteOffset;
-		memcpy(ringBuffer + StartWriteOffset, Src, fragLen);
-		memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen);
+		frag_len = ring_buffer_size - start_write_offset;
+		memcpy(ring_buffer + start_write_offset, src, frag_len);
+		memcpy(ring_buffer, src + frag_len, srclen - frag_len);
 	} else
-		memcpy(ringBuffer + StartWriteOffset, Src, SrcLen);
+		memcpy(ring_buffer + start_write_offset, src, srclen);
 
-	StartWriteOffset += SrcLen;
-	StartWriteOffset %= ringBufferSize;
+	start_write_offset += srclen;
+	start_write_offset %= ring_buffer_size;
 
-	return StartWriteOffset;
+	return start_write_offset;
 }
 
 
 /*++
 
 Name:
-	CopyFromRingBuffer()
+	copyfrom_ringbuffer()
 
 Description:
 	Helper routine to copy to source from ring buffer.
@@ -585,34 +595,34 @@
 
 --*/
 static u32
-CopyFromRingBuffer(
-	struct hv_ring_buffer_info	*RingInfo,
-	void				*Dest,
-	u32				DestLen,
-	u32				StartReadOffset)
+copyfrom_ringbuffer(
+	struct hv_ring_buffer_info	*ring_info,
+	void				*dest,
+	u32				destlen,
+	u32				start_read_offset)
 {
-	void *ringBuffer = GetRingBuffer(RingInfo);
-	u32 ringBufferSize = GetRingBufferSize(RingInfo);
+	void *ring_buffer = get_ring_buffer(ring_info);
+	u32 ring_buffer_size = get_ring_buffersize(ring_info);
 
-	u32 fragLen;
+	u32 frag_len;
 
 	/* wrap-around detected at the src */
-	if (DestLen > ringBufferSize - StartReadOffset) {
+	if (destlen > ring_buffer_size - start_read_offset) {
 		DPRINT_DBG(VMBUS, "src wrap-around detected!");
 
-		fragLen = ringBufferSize - StartReadOffset;
+		frag_len = ring_buffer_size - start_read_offset;
 
-		memcpy(Dest, ringBuffer + StartReadOffset, fragLen);
-		memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen);
+		memcpy(dest, ring_buffer + start_read_offset, frag_len);
+		memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
 	} else
 
-		memcpy(Dest, ringBuffer + StartReadOffset, DestLen);
+		memcpy(dest, ring_buffer + start_read_offset, destlen);
 
 
-	StartReadOffset += DestLen;
-	StartReadOffset %= ringBufferSize;
+	start_read_offset += destlen;
+	start_read_offset %= ring_buffer_size;
 
-	return StartReadOffset;
+	return start_read_offset;
 }
 
 
diff --git a/drivers/staging/hv/ring_buffer.h b/drivers/staging/hv/ring_buffer.h
index a7f1717..7bd6ecf 100644
--- a/drivers/staging/hv/ring_buffer.h
+++ b/drivers/staging/hv/ring_buffer.h
@@ -29,18 +29,18 @@
 
 struct hv_ring_buffer {
 	/* Offset in bytes from the start of ring data below */
-	volatile u32 WriteIndex;
+	volatile u32 write_index;
 
 	/* Offset in bytes from the start of ring data below */
-	volatile u32 ReadIndex;
+	volatile u32 read_index;
 
-	volatile u32 InterruptMask;
+	volatile u32 interrupt_mask;
 
 	/* Pad it to PAGE_SIZE so that data starts on page boundary */
-	u8	Reserved[4084];
+	u8	reserved[4084];
 
 	/* NOTE:
-	 * The InterruptMask field is used only for channels but since our
+	 * The interrupt_mask field is used only for channels but since our
 	 * vmbus connection also uses this data structure and its data starts
 	 * here, we commented out this field.
 	 */
@@ -50,24 +50,24 @@
 	 * Ring data starts here + RingDataStartOffset
 	 * !!! DO NOT place any fields below this !!!
 	 */
-	u8 Buffer[0];
+	u8 buffer[0];
 } __attribute__((packed));
 
 struct hv_ring_buffer_info {
-	struct hv_ring_buffer *RingBuffer;
-	u32 RingSize;			/* Include the shared header */
+	struct hv_ring_buffer *ring_buffer;
+	u32 ring_size;			/* Include the shared header */
 	spinlock_t ring_lock;
 
-	u32 RingDataSize;		/* < ringSize */
-	u32 RingDataStartOffset;
+	u32 ring_datasize;		/* < ring_size */
+	u32 ring_data_startoffset;
 };
 
 struct hv_ring_buffer_debug_info {
-	u32 CurrentInterruptMask;
-	u32 CurrentReadIndex;
-	u32 CurrentWriteIndex;
-	u32 BytesAvailToRead;
-	u32 BytesAvailToWrite;
+	u32 current_interrupt_mask;
+	u32 current_read_index;
+	u32 current_write_index;
+	u32 bytes_avail_toread;
+	u32 bytes_avail_towrite;
 };
 
 
@@ -75,28 +75,28 @@
 /* Interface */
 
 
-int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer,
-		   u32 BufferLen);
+int ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
+		   u32 buflen);
 
-void RingBufferCleanup(struct hv_ring_buffer_info *RingInfo);
+void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
 
-int RingBufferWrite(struct hv_ring_buffer_info *RingInfo,
+int ringbuffer_write(struct hv_ring_buffer_info *ring_info,
 		    struct scatterlist *sglist,
 		    u32 sgcount);
 
-int RingBufferPeek(struct hv_ring_buffer_info *RingInfo, void *Buffer,
-		   u32 BufferLen);
+int ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
+		   u32 buflen);
 
-int RingBufferRead(struct hv_ring_buffer_info *RingInfo,
-		   void *Buffer,
-		   u32 BufferLen,
-		   u32 Offset);
+int ringbuffer_read(struct hv_ring_buffer_info *ring_info,
+		   void *buffer,
+		   u32 buflen,
+		   u32 offset);
 
-u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *RingInfo);
+u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
 
-void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix);
+void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
 
-void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo,
+void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
 			    struct hv_ring_buffer_debug_info *debug_info);
 
 #endif /* _RING_BUFFER_H_ */
diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c
index fa2141f..b85c825 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/staging/hv/rndis_filter.c
@@ -129,7 +129,7 @@
 	if (!request)
 		return NULL;
 
-	request->WaitEvent = osd_WaitEventCreate();
+	request->WaitEvent = osd_waitevent_create();
 	if (!request->WaitEvent) {
 		kfree(request);
 		return NULL;
@@ -313,7 +313,7 @@
 			}
 		}
 
-		osd_WaitEventSet(request->WaitEvent);
+		osd_waitevent_set(request->WaitEvent);
 	} else {
 		DPRINT_ERR(NETVSC, "no rndis request found for this response "
 			   "(id 0x%x res type 0x%x)",
@@ -497,7 +497,7 @@
 	if (ret != 0)
 		goto Cleanup;
 
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	/* Copy the response back */
 	queryComplete = &request->ResponseMessage.Message.QueryComplete;
@@ -572,7 +572,7 @@
 	if (ret != 0)
 		goto Cleanup;
 
-	ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/);
+	ret = osd_waitevent_waitex(request->WaitEvent, 2000/*2sec*/);
 	if (!ret) {
 		ret = -1;
 		DPRINT_ERR(NETVSC, "timeout before we got a set response...");
@@ -665,7 +665,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	initComplete = &request->ResponseMessage.Message.InitializeComplete;
 	status = initComplete->Status;
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 19e87f6..525c8ee 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -198,7 +198,7 @@
 	 * channel
 	 */
 	memset(request, 0, sizeof(struct storvsc_request_extension));
-	request->WaitEvent = osd_WaitEventCreate();
+	request->WaitEvent = osd_waitevent_create();
 	if (!request->WaitEvent) {
 		ret = -ENOMEM;
 		goto nomem;
@@ -224,7 +224,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	if (vstorPacket->Operation != VStorOperationCompleteIo ||
 	    vstorPacket->Status != 0) {
@@ -255,7 +255,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	/* TODO: Check returned version */
 	if (vstorPacket->Operation != VStorOperationCompleteIo ||
@@ -287,7 +287,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	/* TODO: Check returned version */
 	if (vstorPacket->Operation != VStorOperationCompleteIo ||
@@ -323,7 +323,7 @@
 		goto Cleanup;
 	}
 
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	if (vstorPacket->Operation != VStorOperationCompleteIo ||
 	    vstorPacket->Status != 0) {
@@ -473,7 +473,7 @@
 				memcpy(&request->VStorPacket, packet,
 				       sizeof(struct vstor_packet));
 
-				osd_WaitEventSet(request->WaitEvent);
+				osd_waitevent_set(request->WaitEvent);
 			} else {
 				StorVscOnReceive(device,
 						(struct vstor_packet *)packet,
@@ -622,7 +622,7 @@
 	request = &storDevice->ResetRequest;
 	vstorPacket = &request->VStorPacket;
 
-	request->WaitEvent = osd_WaitEventCreate();
+	request->WaitEvent = osd_waitevent_create();
 	if (!request->WaitEvent) {
 		ret = -ENOMEM;
 		goto Cleanup;
@@ -644,7 +644,7 @@
 	}
 
 	/* FIXME: Add a timeout */
-	osd_WaitEventWait(request->WaitEvent);
+	osd_waitevent_wait(request->WaitEvent);
 
 	kfree(request->WaitEvent);
 	DPRINT_INFO(STORVSC, "host adapter reset completed");
diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c
index d449daf..e6462c6 100644
--- a/drivers/staging/hv/vmbus.c
+++ b/drivers/staging/hv/vmbus.c
@@ -109,7 +109,7 @@
 
 	/* strcpy(dev->name, "vmbus"); */
 	/* SynIC setup... */
-	on_each_cpu(HvSynicInit, (void *)irqvector, 1);
+	on_each_cpu(hv_synic_init, (void *)irqvector, 1);
 
 	/* Connect to VMBus in the root partition */
 	ret = VmbusConnect();
@@ -127,7 +127,7 @@
 
 	vmbus_release_unattached_channels();
 	VmbusDisconnect();
-	on_each_cpu(HvSynicCleanup, NULL, 1);
+	on_each_cpu(hv_synic_cleanup, NULL, 1);
 	return ret;
 }
 
@@ -138,7 +138,7 @@
 {
 	/* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */
 
-	HvCleanup();
+	hv_cleanup();
 }
 
 /*
@@ -147,13 +147,13 @@
 static void VmbusOnMsgDPC(struct hv_driver *drv)
 {
 	int cpu = smp_processor_id();
-	void *page_addr = gHvContext.synICMessagePage[cpu];
+	void *page_addr = hv_context.synic_message_page[cpu];
 	struct hv_message *msg = (struct hv_message *)page_addr +
 				  VMBUS_MESSAGE_SINT;
 	struct hv_message *copied;
 
 	while (1) {
-		if (msg->Header.MessageType == HvMessageTypeNone) {
+		if (msg->header.message_type == HVMSG_NONE) {
 			/* no msg */
 			break;
 		} else {
@@ -166,18 +166,18 @@
 					      (void *)copied);
 		}
 
-		msg->Header.MessageType = HvMessageTypeNone;
+		msg->header.message_type = HVMSG_NONE;
 
 		/*
 		 * Make sure the write to MessageType (ie set to
-		 * HvMessageTypeNone) happens before we read the
+		 * HVMSG_NONE) happens before we read the
 		 * MessagePending and EOMing. Otherwise, the EOMing
 		 * will not deliver any more messages since there is
 		 * no empty slot
 		 */
 		mb();
 
-		if (msg->Header.MessageFlags.MessagePending) {
+		if (msg->header.message_flags.msg_pending) {
 			/*
 			 * This will cause message queue rescan to
 			 * possibly deliver another msg from the
@@ -208,24 +208,24 @@
 	struct hv_message *msg;
 	union hv_synic_event_flags *event;
 
-	page_addr = gHvContext.synICMessagePage[cpu];
+	page_addr = hv_context.synic_message_page[cpu];
 	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Check if there are actual msgs to be process */
-	if (msg->Header.MessageType != HvMessageTypeNone) {
+	if (msg->header.message_type != HVMSG_NONE) {
 		DPRINT_DBG(VMBUS, "received msg type %d size %d",
-				msg->Header.MessageType,
-				msg->Header.PayloadSize);
+				msg->header.message_type,
+				msg->header.payload_size);
 		ret |= 0x1;
 	}
 
 	/* TODO: Check if there are events to be process */
-	page_addr = gHvContext.synICEventPage[cpu];
+	page_addr = hv_context.synic_event_page[cpu];
 	event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Since we are a child, we only need to check bit 0 */
-	if (test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) {
-		DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]);
+	if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
+		DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]);
 		ret |= 0x2;
 	}
 
@@ -264,7 +264,7 @@
 	driver->GetChannelOffers	= VmbusGetChannelOffers;
 
 	/* Hypervisor initialization...setup hypercall page..etc */
-	ret = HvInit();
+	ret = hv_init();
 	if (ret != 0)
 		DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x",
 				ret);
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 0d9f3a4..09658759 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -139,35 +139,38 @@
 
 	vmbus_get_debug_info(device->channel, &debug_info);
 
-	info->ChannelId = debug_info.RelId;
-	info->ChannelState = debug_info.State;
-	memcpy(&info->ChannelType, &debug_info.InterfaceType,
+	info->ChannelId = debug_info.relid;
+	info->ChannelState = debug_info.state;
+	memcpy(&info->ChannelType, &debug_info.interfacetype,
 	       sizeof(struct hv_guid));
-	memcpy(&info->ChannelInstance, &debug_info.InterfaceInstance,
+	memcpy(&info->ChannelInstance, &debug_info.interface_instance,
 	       sizeof(struct hv_guid));
 
-	info->MonitorId = debug_info.MonitorId;
+	info->MonitorId = debug_info.monitorid;
 
-	info->ServerMonitorPending = debug_info.ServerMonitorPending;
-	info->ServerMonitorLatency = debug_info.ServerMonitorLatency;
-	info->ServerMonitorConnectionId = debug_info.ServerMonitorConnectionId;
+	info->ServerMonitorPending = debug_info.servermonitor_pending;
+	info->ServerMonitorLatency = debug_info.servermonitor_latency;
+	info->ServerMonitorConnectionId = debug_info.servermonitor_connectionid;
 
-	info->ClientMonitorPending = debug_info.ClientMonitorPending;
-	info->ClientMonitorLatency = debug_info.ClientMonitorLatency;
-	info->ClientMonitorConnectionId = debug_info.ClientMonitorConnectionId;
+	info->ClientMonitorPending = debug_info.clientmonitor_pending;
+	info->ClientMonitorLatency = debug_info.clientmonitor_latency;
+	info->ClientMonitorConnectionId = debug_info.clientmonitor_connectionid;
 
-	info->Inbound.InterruptMask = debug_info.Inbound.CurrentInterruptMask;
-	info->Inbound.ReadIndex = debug_info.Inbound.CurrentReadIndex;
-	info->Inbound.WriteIndex = debug_info.Inbound.CurrentWriteIndex;
-	info->Inbound.BytesAvailToRead = debug_info.Inbound.BytesAvailToRead;
-	info->Inbound.BytesAvailToWrite = debug_info.Inbound.BytesAvailToWrite;
+	info->Inbound.InterruptMask = debug_info.inbound.current_interrupt_mask;
+	info->Inbound.ReadIndex = debug_info.inbound.current_read_index;
+	info->Inbound.WriteIndex = debug_info.inbound.current_write_index;
+	info->Inbound.BytesAvailToRead = debug_info.inbound.bytes_avail_toread;
+	info->Inbound.BytesAvailToWrite =
+		debug_info.inbound.bytes_avail_towrite;
 
-	info->Outbound.InterruptMask = debug_info.Outbound.CurrentInterruptMask;
-	info->Outbound.ReadIndex = debug_info.Outbound.CurrentReadIndex;
-	info->Outbound.WriteIndex = debug_info.Outbound.CurrentWriteIndex;
-	info->Outbound.BytesAvailToRead = debug_info.Outbound.BytesAvailToRead;
+	info->Outbound.InterruptMask =
+		debug_info.outbound.current_interrupt_mask;
+	info->Outbound.ReadIndex = debug_info.outbound.current_read_index;
+	info->Outbound.WriteIndex = debug_info.outbound.current_write_index;
+	info->Outbound.BytesAvailToRead =
+		debug_info.outbound.bytes_avail_toread;
 	info->Outbound.BytesAvailToWrite =
-		debug_info.Outbound.BytesAvailToWrite;
+		debug_info.outbound.bytes_avail_towrite;
 }
 
 /*
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index ed48815..e2ac07d 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -42,11 +42,15 @@
 
 source "drivers/staging/iio/accel/Kconfig"
 source "drivers/staging/iio/adc/Kconfig"
+source "drivers/staging/iio/addac/Kconfig"
+source "drivers/staging/iio/dac/Kconfig"
+source "drivers/staging/iio/dds/Kconfig"
 source "drivers/staging/iio/gyro/Kconfig"
 source "drivers/staging/iio/imu/Kconfig"
 source "drivers/staging/iio/light/Kconfig"
 source "drivers/staging/iio/magnetometer/Kconfig"
-
+source "drivers/staging/iio/meter/Kconfig"
+source "drivers/staging/iio/resolver/Kconfig"
 source "drivers/staging/iio/trigger/Kconfig"
 
 endif # IIO
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
index e909674..f9b5fb2 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -11,8 +11,13 @@
 
 obj-y += accel/
 obj-y += adc/
+obj-y += addac/
+obj-y += dac/
+obj-y += dds/
 obj-y += gyro/
 obj-y += imu/
 obj-y += light/
-obj-y += trigger/
 obj-y += magnetometer/
+obj-y += meter/
+obj-y += resolver/
+obj-y += trigger/
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
index 898cba1..d1ad35e 100644
--- a/drivers/staging/iio/TODO
+++ b/drivers/staging/iio/TODO
@@ -61,6 +61,10 @@
 files. (avoided at the moment to keep the driver set
 contained in staging).
 
+ADI Drivers:
+CC the device-drivers-devel@blackfin.uclinux.org mailing list when
+e-mailing the normal IIO list (see below).
+
 Documentation
 1) Lots of cleanup and expansion.
 2) Some device require indvidual docs.
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
index 5926c03..a34f1d3 100644
--- a/drivers/staging/iio/accel/Kconfig
+++ b/drivers/staging/iio/accel/Kconfig
@@ -3,6 +3,33 @@
 #
 comment "Accelerometers"
 
+config ADIS16201
+	tristate "Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer"
+	depends on SPI
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select IIO_SW_RING if IIO_RING_BUFFER
+	help
+	  Say yes here to build support for Analog Devices adis16201 dual-axis
+	  digital inclinometer and accelerometer.
+
+config ADIS16203
+	tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer"
+	depends on SPI
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select IIO_SW_RING if IIO_RING_BUFFER
+	help
+	  Say yes here to build support for Analog Devices adis16203 Programmable
+	  360 Degrees Inclinometer.
+
+config ADIS16204
+	tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder"
+	depends on SPI
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select IIO_SW_RING if IIO_RING_BUFFER
+	help
+	  Say yes here to build support for Analog Devices adis16204 Programmable
+	  High-g Digital Impact Sensor and Recorder.
+
 config ADIS16209
 	tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer"
 	depends on SPI
diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile
index ff84703..1b2a6d3 100644
--- a/drivers/staging/iio/accel/Makefile
+++ b/drivers/staging/iio/accel/Makefile
@@ -2,6 +2,18 @@
 # Makefile for industrial I/O accelerometer drivers
 #
 
+adis16201-y             := adis16201_core.o
+adis16201-$(CONFIG_IIO_RING_BUFFER) += adis16201_ring.o adis16201_trigger.o
+obj-$(CONFIG_ADIS16201) += adis16201.o
+
+adis16203-y             := adis16203_core.o
+adis16203-$(CONFIG_IIO_RING_BUFFER) += adis16203_ring.o adis16203_trigger.o
+obj-$(CONFIG_ADIS16203) += adis16203.o
+
+adis16204-y             := adis16204_core.o
+adis16204-$(CONFIG_IIO_RING_BUFFER) += adis16204_ring.o adis16204_trigger.o
+obj-$(CONFIG_ADIS16204) += adis16204.o
+
 adis16209-y             := adis16209_core.o
 adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o
 obj-$(CONFIG_ADIS16209) += adis16209.o
diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h
index f5f61b2..50651f8 100644
--- a/drivers/staging/iio/accel/accel.h
+++ b/drivers/staging/iio/accel/accel.h
@@ -65,3 +65,23 @@
 #define IIO_DEV_ATTR_ACCEL_Z(_show, _addr)			\
 	IIO_DEVICE_ATTR(accel_z_raw, S_IRUGO, _show, NULL, _addr)
 
+#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_xy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_PEAK(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_peak, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_XPEAK(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_xpeak, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_YPEAK(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_ypeak, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_ZPEAK(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_zpeak, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr)		\
+	IIO_DEVICE_ATTR(accel_xypeak, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_XYZPEAK(_show, _addr)		\
+	IIO_DEVICE_ATTR(accel_xyzpeak, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h
new file mode 100644
index 0000000..c9bf22c
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16201.h
@@ -0,0 +1,150 @@
+#ifndef SPI_ADIS16201_H_
+#define SPI_ADIS16201_H_
+
+#define ADIS16201_STARTUP_DELAY	220 /* ms */
+
+#define ADIS16201_READ_REG(a)    a
+#define ADIS16201_WRITE_REG(a) ((a) | 0x80)
+
+#define ADIS16201_FLASH_CNT      0x00 /* Flash memory write count */
+#define ADIS16201_SUPPLY_OUT     0x02 /* Output, power supply */
+#define ADIS16201_XACCL_OUT      0x04 /* Output, x-axis accelerometer */
+#define ADIS16201_YACCL_OUT      0x06 /* Output, y-axis accelerometer */
+#define ADIS16201_AUX_ADC        0x08 /* Output, auxiliary ADC input */
+#define ADIS16201_TEMP_OUT       0x0A /* Output, temperature */
+#define ADIS16201_XINCL_OUT      0x0C /* Output, x-axis inclination */
+#define ADIS16201_YINCL_OUT      0x0E /* Output, y-axis inclination */
+#define ADIS16201_XACCL_OFFS     0x10 /* Calibration, x-axis acceleration offset */
+#define ADIS16201_YACCL_OFFS     0x12 /* Calibration, y-axis acceleration offset */
+#define ADIS16201_XACCL_SCALE    0x14 /* x-axis acceleration scale factor */
+#define ADIS16201_YACCL_SCALE    0x16 /* y-axis acceleration scale factor */
+#define ADIS16201_XINCL_OFFS     0x18 /* Calibration, x-axis inclination offset */
+#define ADIS16201_YINCL_OFFS     0x1A /* Calibration, y-axis inclination offset */
+#define ADIS16201_XINCL_SCALE    0x1C /* x-axis inclination scale factor */
+#define ADIS16201_YINCL_SCALE    0x1E /* y-axis inclination scale factor */
+#define ADIS16201_ALM_MAG1       0x20 /* Alarm 1 amplitude threshold */
+#define ADIS16201_ALM_MAG2       0x22 /* Alarm 2 amplitude threshold */
+#define ADIS16201_ALM_SMPL1      0x24 /* Alarm 1, sample period */
+#define ADIS16201_ALM_SMPL2      0x26 /* Alarm 2, sample period */
+#define ADIS16201_ALM_CTRL       0x28 /* Alarm control */
+#define ADIS16201_AUX_DAC        0x30 /* Auxiliary DAC data */
+#define ADIS16201_GPIO_CTRL      0x32 /* General-purpose digital input/output control */
+#define ADIS16201_MSC_CTRL       0x34 /* Miscellaneous control */
+#define ADIS16201_SMPL_PRD       0x36 /* Internal sample period (rate) control */
+#define ADIS16201_AVG_CNT        0x38 /* Operation, filter configuration */
+#define ADIS16201_SLP_CNT        0x3A /* Operation, sleep mode control */
+#define ADIS16201_DIAG_STAT      0x3C /* Diagnostics, system status register */
+#define ADIS16201_GLOB_CMD       0x3E /* Operation, system command register */
+
+#define ADIS16201_OUTPUTS        7
+
+/* MSC_CTRL */
+#define ADIS16201_MSC_CTRL_SELF_TEST_EN	        (1 << 8)  /* Self-test enable */
+#define ADIS16201_MSC_CTRL_DATA_RDY_EN	        (1 << 2)  /* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16201_MSC_CTRL_ACTIVE_HIGH	        (1 << 1)  /* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16201_MSC_CTRL_DATA_RDY_DIO1	(1 << 0)  /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */
+
+/* DIAG_STAT */
+#define ADIS16201_DIAG_STAT_ALARM2        (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16201_DIAG_STAT_ALARM1        (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16201_DIAG_STAT_SPI_FAIL	  (1<<3) /* SPI communications failure */
+#define ADIS16201_DIAG_STAT_FLASH_UPT	  (1<<2) /* Flash update failure */
+#define ADIS16201_DIAG_STAT_POWER_HIGH	  (1<<1) /* Power supply above 3.625 V */
+#define ADIS16201_DIAG_STAT_POWER_LOW	  (1<<0) /* Power supply below 3.15 V */
+
+/* GLOB_CMD */
+#define ADIS16201_GLOB_CMD_SW_RESET	(1<<7)
+#define ADIS16201_GLOB_CMD_FACTORY_CAL	(1<<1)
+
+#define ADIS16201_MAX_TX 14
+#define ADIS16201_MAX_RX 14
+
+#define ADIS16201_ERROR_ACTIVE          (1<<14)
+
+/**
+ * struct adis16201_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16201_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+int adis16201_set_irq(struct device *dev, bool enable);
+
+#ifdef CONFIG_IIO_RING_BUFFER
+enum adis16201_scan {
+	ADIS16201_SCAN_SUPPLY,
+	ADIS16201_SCAN_ACC_X,
+	ADIS16201_SCAN_ACC_Y,
+	ADIS16201_SCAN_AUX_ADC,
+	ADIS16201_SCAN_TEMP,
+	ADIS16201_SCAN_INCLI_X,
+	ADIS16201_SCAN_INCLI_Y,
+};
+
+void adis16201_remove_trigger(struct iio_dev *indio_dev);
+int adis16201_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16201_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+int adis16201_configure_ring(struct iio_dev *indio_dev);
+void adis16201_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16201_initialize_ring(struct iio_ring_buffer *ring);
+void adis16201_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16201_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16201_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16201_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16201_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16201_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16201_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16201_H_ */
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
new file mode 100644
index 0000000..79b785a
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -0,0 +1,659 @@
+/*
+ * ADIS16201 Programmable Digital Vibration Sensor driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "accel.h"
+#include "inclinometer.h"
+#include "../gyro/gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16201.h"
+
+#define DRIVER_NAME		"adis16201"
+
+static int adis16201_check_status(struct device *dev);
+
+/**
+ * adis16201_spi_write_reg_8() - write single byte to a register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be written
+ * @val: the value to write
+ **/
+static int adis16201_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16201_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: value to be written
+ **/
+static int adis16201_spi_write_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.tx_buf = st->tx + 2,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16201_WRITE_REG(lower_reg_address);
+	st->tx[1] = value & 0xFF;
+	st->tx[2] = ADIS16201_WRITE_REG(lower_reg_address + 1);
+	st->tx[3] = (value >> 8) & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: somewhere to pass back the value read
+ **/
+static int adis16201_spi_read_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.delay_usecs = 20,
+		}, {
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.delay_usecs = 20,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16201_READ_REG(lower_reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				lower_reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[0] << 8) | st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t adis16201_read_12bit_unsigned(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = adis16201_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	if (val & ADIS16201_ERROR_ACTIVE) {
+		ret = adis16201_check_status(dev);
+		if (ret)
+			return ret;
+	}
+
+	return sprintf(buf, "%u\n", val & 0x0FFF);
+}
+
+static ssize_t adis16201_read_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	ssize_t ret;
+	u16 val;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16201_spi_read_reg_16(dev, ADIS16201_TEMP_OUT, (u16 *)&val);
+	if (ret)
+		goto error_ret;
+
+	if (val & ADIS16201_ERROR_ACTIVE) {
+		ret = adis16201_check_status(dev);
+		if (ret)
+			goto error_ret;
+	}
+
+	val &= 0xFFF;
+	ret = sprintf(buf, "%d\n", val);
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
+}
+
+static ssize_t adis16201_read_9bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	s16 val = 0;
+	ssize_t ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (!ret) {
+		if (val & ADIS16201_ERROR_ACTIVE) {
+			ret = adis16201_check_status(dev);
+			if (ret)
+				goto error_ret;
+		}
+		val = ((s16)(val << 7) >> 7);
+		ret = sprintf(buf, "%d\n", val);
+	}
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16201_read_12bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	s16 val = 0;
+	ssize_t ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (!ret) {
+		if (val & ADIS16201_ERROR_ACTIVE) {
+			ret = adis16201_check_status(dev);
+			if (ret)
+				goto error_ret;
+		}
+
+		val = ((s16)(val << 4) >> 4);
+		ret = sprintf(buf, "%d\n", val);
+	}
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16201_read_14bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	s16 val = 0;
+	ssize_t ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (!ret) {
+		if (val & ADIS16201_ERROR_ACTIVE) {
+			ret = adis16201_check_status(dev);
+			if (ret)
+				goto error_ret;
+		}
+
+		val = ((s16)(val << 2) >> 2);
+		ret = sprintf(buf, "%d\n", val);
+	}
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16201_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16201_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int adis16201_reset(struct device *dev)
+{
+	int ret;
+	ret = adis16201_spi_write_reg_8(dev,
+			ADIS16201_GLOB_CMD,
+			ADIS16201_GLOB_CMD_SW_RESET);
+	if (ret)
+		dev_err(dev, "problem resetting device");
+
+	return ret;
+}
+
+static ssize_t adis16201_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -EINVAL;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return adis16201_reset(dev);
+	}
+	return -EINVAL;
+}
+
+int adis16201_set_irq(struct device *dev, bool enable)
+{
+	int ret = 0;
+	u16 msc;
+
+	ret = adis16201_spi_read_reg_16(dev, ADIS16201_MSC_CTRL, &msc);
+	if (ret)
+		goto error_ret;
+
+	msc |= ADIS16201_MSC_CTRL_ACTIVE_HIGH;
+	msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_DIO1;
+	if (enable)
+		msc |= ADIS16201_MSC_CTRL_DATA_RDY_EN;
+	else
+		msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN;
+
+	ret = adis16201_spi_write_reg_16(dev, ADIS16201_MSC_CTRL, msc);
+
+error_ret:
+	return ret;
+}
+
+static int adis16201_check_status(struct device *dev)
+{
+	u16 status;
+	int ret;
+
+	ret = adis16201_spi_read_reg_16(dev, ADIS16201_DIAG_STAT, &status);
+	if (ret < 0) {
+		dev_err(dev, "Reading status failed\n");
+		goto error_ret;
+	}
+	ret = status & 0xF;
+	if (ret)
+		ret = -EFAULT;
+
+	if (status & ADIS16201_DIAG_STAT_SPI_FAIL)
+		dev_err(dev, "SPI failure\n");
+	if (status & ADIS16201_DIAG_STAT_FLASH_UPT)
+		dev_err(dev, "Flash update failed\n");
+	if (status & ADIS16201_DIAG_STAT_POWER_HIGH)
+		dev_err(dev, "Power supply above 3.625V\n");
+	if (status & ADIS16201_DIAG_STAT_POWER_LOW)
+		dev_err(dev, "Power supply below 3.15V\n");
+
+error_ret:
+	return ret;
+}
+
+static int adis16201_self_test(struct device *dev)
+{
+	int ret;
+	ret = adis16201_spi_write_reg_16(dev,
+			ADIS16201_MSC_CTRL,
+			ADIS16201_MSC_CTRL_SELF_TEST_EN);
+	if (ret) {
+		dev_err(dev, "problem starting self test");
+		goto err_ret;
+	}
+
+	ret = adis16201_check_status(dev);
+
+err_ret:
+	return ret;
+}
+
+static int adis16201_initial_setup(struct adis16201_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* Disable IRQ */
+	ret = adis16201_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	/* Do self test */
+	ret = adis16201_self_test(dev);
+	if (ret) {
+		dev_err(dev, "self test failure");
+		goto err_ret;
+	}
+
+	/* Read status register to check the result */
+	ret = adis16201_check_status(dev);
+	if (ret) {
+		adis16201_reset(dev);
+		dev_err(dev, "device not playing ball -> reset");
+		msleep(ADIS16201_STARTUP_DELAY);
+		ret = adis16201_check_status(dev);
+		if (ret) {
+			dev_err(dev, "giving up");
+			goto err_ret;
+		}
+	}
+
+	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
+			st->us->chip_select, st->us->irq);
+
+err_ret:
+	return ret;
+}
+
+static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16201_read_12bit_unsigned,
+		ADIS16201_SUPPLY_OUT);
+static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
+static IIO_DEV_ATTR_IN_RAW(1, adis16201_read_12bit_unsigned,
+		ADIS16201_AUX_ADC);
+static IIO_CONST_ATTR(in1_scale, "0.00061");
+
+static IIO_DEV_ATTR_ACCEL_X(adis16201_read_14bit_signed,
+		ADIS16201_XACCL_OUT);
+static IIO_DEV_ATTR_ACCEL_Y(adis16201_read_14bit_signed,
+		ADIS16201_YACCL_OUT);
+static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+		adis16201_read_12bit_signed,
+		adis16201_write_16bit,
+		ADIS16201_XACCL_OFFS);
+static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+		adis16201_read_12bit_signed,
+		adis16201_write_16bit,
+		ADIS16201_YACCL_OFFS);
+static IIO_CONST_ATTR(accel_scale, "0.4625");
+
+static IIO_DEV_ATTR_INCLI_X(adis16201_read_14bit_signed,
+		ADIS16201_XINCL_OUT);
+static IIO_DEV_ATTR_INCLI_Y(adis16201_read_14bit_signed,
+		ADIS16201_YINCL_OUT);
+static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
+		adis16201_read_9bit_signed,
+		adis16201_write_16bit,
+		ADIS16201_XACCL_OFFS);
+static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
+		adis16201_read_9bit_signed,
+		adis16201_write_16bit,
+		ADIS16201_YACCL_OFFS);
+static IIO_CONST_ATTR(incli_scale, "0.1");
+
+static IIO_DEV_ATTR_TEMP_RAW(adis16201_read_temp);
+static IIO_CONST_ATTR(temp_offset, "25");
+static IIO_CONST_ATTR(temp_scale, "-0.47");
+
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0);
+
+static IIO_CONST_ATTR(name, "adis16201");
+
+static struct attribute *adis16201_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16201_event_attribute_group = {
+	.attrs = adis16201_event_attributes,
+};
+
+static struct attribute *adis16201_attributes[] = {
+	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
+	&iio_const_attr_in0_supply_scale.dev_attr.attr,
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_in1_raw.dev_attr.attr,
+	&iio_const_attr_in1_scale.dev_attr.attr,
+	&iio_dev_attr_accel_x_raw.dev_attr.attr,
+	&iio_dev_attr_accel_y_raw.dev_attr.attr,
+	&iio_dev_attr_accel_x_offset.dev_attr.attr,
+	&iio_dev_attr_accel_y_offset.dev_attr.attr,
+	&iio_const_attr_accel_scale.dev_attr.attr,
+	&iio_dev_attr_incli_x_raw.dev_attr.attr,
+	&iio_dev_attr_incli_y_raw.dev_attr.attr,
+	&iio_dev_attr_incli_x_offset.dev_attr.attr,
+	&iio_dev_attr_incli_y_offset.dev_attr.attr,
+	&iio_const_attr_incli_scale.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16201_attribute_group = {
+	.attrs = adis16201_attributes,
+};
+
+static int __devinit adis16201_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16201_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16201_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16201_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16201_event_attribute_group;
+	st->indio_dev->attrs = &adis16201_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16201_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16201_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16201");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16201_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = adis16201_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	adis16201_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (spi->irq)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16201_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16201_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int adis16201_remove(struct spi_device *spi)
+{
+	struct adis16201_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	adis16201_remove_trigger(indio_dev);
+	if (spi->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16201_uninitialize_ring(indio_dev->ring);
+	iio_device_unregister(indio_dev);
+	adis16201_unconfigure_ring(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver adis16201_driver = {
+	.driver = {
+		.name = "adis16201",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16201_probe,
+	.remove = __devexit_p(adis16201_remove),
+};
+
+static __init int adis16201_init(void)
+{
+	return spi_register_driver(&adis16201_driver);
+}
+module_init(adis16201_init);
+
+static __exit void adis16201_exit(void)
+{
+	spi_unregister_driver(&adis16201_driver);
+}
+module_exit(adis16201_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16201 Programmable Digital Vibration Sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
new file mode 100644
index 0000000..e6870a2
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -0,0 +1,218 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_sw.h"
+#include "accel.h"
+#include "../trigger.h"
+#include "adis16201.h"
+
+static IIO_SCAN_EL_C(in_supply, ADIS16201_SCAN_SUPPLY, ADIS16201_SUPPLY_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
+static IIO_SCAN_EL_C(accel_x, ADIS16201_SCAN_ACC_X, ADIS16201_XACCL_OUT, NULL);
+static IIO_SCAN_EL_C(accel_y, ADIS16201_SCAN_ACC_Y, ADIS16201_YACCL_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
+static IIO_SCAN_EL_C(in0, ADIS16201_SCAN_AUX_ADC, ADIS16201_AUX_ADC, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
+static IIO_SCAN_EL_C(temp, ADIS16201_SCAN_TEMP, ADIS16201_TEMP_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
+static IIO_SCAN_EL_C(incli_x, ADIS16201_SCAN_INCLI_X,
+		     ADIS16201_XINCL_OUT, NULL);
+static IIO_SCAN_EL_C(incli_y, ADIS16201_SCAN_INCLI_Y,
+		     ADIS16201_YINCL_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
+static IIO_SCAN_EL_TIMESTAMP(7);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
+
+static struct attribute *adis16201_scan_el_attrs[] = {
+	&iio_scan_el_in_supply.dev_attr.attr,
+	&iio_const_attr_in_supply_index.dev_attr.attr,
+	&iio_const_attr_in_supply_type.dev_attr.attr,
+	&iio_scan_el_accel_x.dev_attr.attr,
+	&iio_const_attr_accel_x_index.dev_attr.attr,
+	&iio_scan_el_accel_y.dev_attr.attr,
+	&iio_const_attr_accel_y_index.dev_attr.attr,
+	&iio_const_attr_accel_type.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
+	&iio_const_attr_in0_index.dev_attr.attr,
+	&iio_const_attr_in0_type.dev_attr.attr,
+	&iio_scan_el_temp.dev_attr.attr,
+	&iio_const_attr_temp_index.dev_attr.attr,
+	&iio_const_attr_temp_type.dev_attr.attr,
+	&iio_scan_el_incli_x.dev_attr.attr,
+	&iio_const_attr_incli_x_index.dev_attr.attr,
+	&iio_scan_el_incli_y.dev_attr.attr,
+	&iio_const_attr_incli_y_index.dev_attr.attr,
+	&iio_const_attr_incli_type.dev_attr.attr,
+	&iio_scan_el_timestamp.dev_attr.attr,
+	&iio_const_attr_timestamp_index.dev_attr.attr,
+	&iio_const_attr_timestamp_type.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adis16201_scan_el_group = {
+	.attrs = adis16201_scan_el_attrs,
+	.name = "scan_elements",
+};
+
+/**
+ * adis16201_poll_func_th() top half interrupt handler called by trigger
+ * @private_data:	iio_dev
+ **/
+static void adis16201_poll_func_th(struct iio_dev *indio_dev, s64 time)
+{
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+	st->last_timestamp = time;
+	schedule_work(&st->work_trigger_to_ring);
+}
+
+/**
+ * adis16201_read_ring_data() read data registers which will be placed into ring
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read
+ **/
+static int adis16201_read_ring_data(struct device *dev, u8 *rx)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[ADIS16201_OUTPUTS + 1];
+	int ret;
+	int i;
+
+	mutex_lock(&st->buf_lock);
+
+	spi_message_init(&msg);
+
+	memset(xfers, 0, sizeof(xfers));
+	for (i = 0; i <= ADIS16201_OUTPUTS; i++) {
+		xfers[i].bits_per_word = 8;
+		xfers[i].cs_change = 1;
+		xfers[i].len = 2;
+		xfers[i].delay_usecs = 20;
+		xfers[i].tx_buf = st->tx + 2 * i;
+		st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + 2 * i);
+		st->tx[2 * i + 1] = 0;
+		if (i >= 1)
+			xfers[i].rx_buf = rx + 2 * (i - 1);
+		spi_message_add_tail(&xfers[i], &msg);
+	}
+
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when burst reading");
+
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+ * specific to be rolled into the core.
+ */
+static void adis16201_trigger_bh_to_ring(struct work_struct *work_s)
+{
+	struct adis16201_state *st
+		= container_of(work_s, struct adis16201_state,
+			       work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
+
+	int i = 0;
+	s16 *data;
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
+
+	data = kmalloc(datasize, GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed in ring bh");
+		return;
+	}
+
+	if (ring->scan_count)
+		if (adis16201_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+			for (; i < ring->scan_count; i++)
+				data[i] = be16_to_cpup(
+					(__be16 *)&(st->rx[i*2]));
+
+	/* Guaranteed to be aligned with 8 byte boundary */
+	if (ring->scan_timestamp)
+		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+
+	ring->access.store_to(ring,
+			      (u8 *)data,
+			      st->last_timestamp);
+
+	iio_trigger_notify_done(st->indio_dev->trig);
+	kfree(data);
+
+	return;
+}
+
+void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
+{
+	kfree(indio_dev->pollfunc);
+	iio_sw_rb_free(indio_dev->ring);
+}
+
+int adis16201_configure_ring(struct iio_dev *indio_dev)
+{
+	int ret = 0;
+	struct adis16201_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring;
+	INIT_WORK(&st->work_trigger_to_ring, adis16201_trigger_bh_to_ring);
+
+	ring = iio_sw_rb_allocate(indio_dev);
+	if (!ring) {
+		ret = -ENOMEM;
+		return ret;
+	}
+	indio_dev->ring = ring;
+	/* Effectively select the ring buffer implementation */
+	iio_ring_sw_register_funcs(&ring->access);
+	ring->bpe = 2;
+	ring->scan_el_attrs = &adis16201_scan_el_group;
+	ring->scan_timestamp = true;
+	ring->preenable = &iio_sw_ring_preenable;
+	ring->postenable = &iio_triggered_ring_postenable;
+	ring->predisable = &iio_triggered_ring_predisable;
+	ring->owner = THIS_MODULE;
+
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+	iio_scan_mask_set(ring, iio_scan_el_temp.number);
+	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
+	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+
+	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16201_poll_func_th);
+	if (ret)
+		goto error_iio_sw_rb_free;
+
+	indio_dev->modes |= INDIO_RING_TRIGGERED;
+	return 0;
+
+error_iio_sw_rb_free:
+	iio_sw_rb_free(indio_dev->ring);
+	return ret;
+}
+
+int adis16201_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return iio_ring_buffer_register(ring, 0);
+}
+
+void adis16201_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+	iio_ring_buffer_unregister(ring);
+}
diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c
new file mode 100644
index 0000000..8a9cea19
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16201_trigger.c
@@ -0,0 +1,122 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../trigger.h"
+#include "adis16201.h"
+
+/**
+ * adis16201_data_rdy_trig_poll() the event handler for the data rdy trig
+ **/
+static int adis16201_data_rdy_trig_poll(struct iio_dev *dev_info,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
+{
+	struct adis16201_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_trigger *trig = st->trig;
+
+	iio_trigger_poll(trig, timestamp);
+
+	return IRQ_HANDLED;
+}
+
+IIO_EVENT_SH(data_rdy_trig, &adis16201_data_rdy_trig_poll);
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static struct attribute *adis16201_trigger_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group adis16201_trigger_attr_group = {
+	.attrs = adis16201_trigger_attrs,
+};
+
+/**
+ * adis16201_data_rdy_trigger_set_state() set datardy interrupt state
+ **/
+static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig,
+						bool state)
+{
+	struct adis16201_state *st = trig->private_data;
+	struct iio_dev *indio_dev = st->indio_dev;
+	int ret = 0;
+
+	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
+	ret = adis16201_set_irq(&st->indio_dev->dev, state);
+	if (state == false) {
+		iio_remove_event_from_list(&iio_event_data_rdy_trig,
+					   &indio_dev->interrupts[0]
+					   ->ev_list);
+		flush_scheduled_work();
+	} else {
+		iio_add_event_to_list(&iio_event_data_rdy_trig,
+				      &indio_dev->interrupts[0]->ev_list);
+	}
+	return ret;
+}
+
+/**
+ * adis16201_trig_try_reen() try renabling irq for data rdy trigger
+ * @trig:	the datardy trigger
+ **/
+static int adis16201_trig_try_reen(struct iio_trigger *trig)
+{
+	struct adis16201_state *st = trig->private_data;
+	enable_irq(st->us->irq);
+	return 0;
+}
+
+int adis16201_probe_trigger(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct adis16201_state *st = indio_dev->dev_data;
+
+	st->trig = iio_allocate_trigger();
+	st->trig->name = kasprintf(GFP_KERNEL,
+				"adis16201-dev%d",
+				indio_dev->id);
+	if (!st->trig->name) {
+		ret = -ENOMEM;
+		goto error_free_trig;
+	}
+	st->trig->dev.parent = &st->us->dev;
+	st->trig->owner = THIS_MODULE;
+	st->trig->private_data = st;
+	st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state;
+	st->trig->try_reenable = &adis16201_trig_try_reen;
+	st->trig->control_attrs = &adis16201_trigger_attr_group;
+	ret = iio_trigger_register(st->trig);
+
+	/* select default trigger */
+	indio_dev->trig = st->trig;
+	if (ret)
+		goto error_free_trig_name;
+
+	return 0;
+
+error_free_trig_name:
+	kfree(st->trig->name);
+error_free_trig:
+	iio_free_trigger(st->trig);
+
+	return ret;
+}
+
+void adis16201_remove_trigger(struct iio_dev *indio_dev)
+{
+	struct adis16201_state *state = indio_dev->dev_data;
+
+	iio_trigger_unregister(state->trig);
+	kfree(state->trig->name);
+	iio_free_trigger(state->trig);
+}
diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h
new file mode 100644
index 0000000..b39323e
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16203.h
@@ -0,0 +1,143 @@
+#ifndef SPI_ADIS16203_H_
+#define SPI_ADIS16203_H_
+
+#define ADIS16203_STARTUP_DELAY	220 /* ms */
+
+#define ADIS16203_READ_REG(a)    a
+#define ADIS16203_WRITE_REG(a) ((a) | 0x80)
+
+#define ADIS16203_FLASH_CNT      0x00 /* Flash memory write count */
+#define ADIS16203_SUPPLY_OUT     0x02 /* Output, power supply */
+#define ADIS16203_AUX_ADC        0x08 /* Output, auxiliary ADC input */
+#define ADIS16203_TEMP_OUT       0x0A /* Output, temperature */
+#define ADIS16203_XINCL_OUT      0x0C /* Output, x-axis inclination */
+#define ADIS16203_YINCL_OUT      0x0E /* Output, y-axis inclination */
+#define ADIS16203_INCL_NULL      0x18 /* Incline null calibration */
+#define ADIS16203_ALM_MAG1       0x20 /* Alarm 1 amplitude threshold */
+#define ADIS16203_ALM_MAG2       0x22 /* Alarm 2 amplitude threshold */
+#define ADIS16203_ALM_SMPL1      0x24 /* Alarm 1, sample period */
+#define ADIS16203_ALM_SMPL2      0x26 /* Alarm 2, sample period */
+#define ADIS16203_ALM_CTRL       0x28 /* Alarm control */
+#define ADIS16203_AUX_DAC        0x30 /* Auxiliary DAC data */
+#define ADIS16203_GPIO_CTRL      0x32 /* General-purpose digital input/output control */
+#define ADIS16203_MSC_CTRL       0x34 /* Miscellaneous control */
+#define ADIS16203_SMPL_PRD       0x36 /* Internal sample period (rate) control */
+#define ADIS16203_AVG_CNT        0x38 /* Operation, filter configuration */
+#define ADIS16203_SLP_CNT        0x3A /* Operation, sleep mode control */
+#define ADIS16203_DIAG_STAT      0x3C /* Diagnostics, system status register */
+#define ADIS16203_GLOB_CMD       0x3E /* Operation, system command register */
+
+#define ADIS16203_OUTPUTS        5
+
+/* MSC_CTRL */
+#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST	(1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */
+#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN	(1 << 9)  /* Reverses rotation of both inclination outputs */
+#define ADIS16203_MSC_CTRL_SELF_TEST_EN	        (1 << 8)  /* Self-test enable */
+#define ADIS16203_MSC_CTRL_DATA_RDY_EN	        (1 << 2)  /* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16203_MSC_CTRL_ACTIVE_HIGH	        (1 << 1)  /* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16203_MSC_CTRL_DATA_RDY_DIO1	(1 << 0)  /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */
+
+/* DIAG_STAT */
+#define ADIS16203_DIAG_STAT_ALARM2        (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16203_DIAG_STAT_ALARM1        (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16203_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag */
+#define ADIS16203_DIAG_STAT_SPI_FAIL	  (1<<3) /* SPI communications failure */
+#define ADIS16203_DIAG_STAT_FLASH_UPT	  (1<<2) /* Flash update failure */
+#define ADIS16203_DIAG_STAT_POWER_HIGH	  (1<<1) /* Power supply above 3.625 V */
+#define ADIS16203_DIAG_STAT_POWER_LOW	  (1<<0) /* Power supply below 3.15 V */
+
+/* GLOB_CMD */
+#define ADIS16203_GLOB_CMD_SW_RESET	(1<<7)
+#define ADIS16203_GLOB_CMD_CLEAR_STAT	(1<<4)
+#define ADIS16203_GLOB_CMD_FACTORY_CAL	(1<<1)
+
+#define ADIS16203_MAX_TX 12
+#define ADIS16203_MAX_RX 10
+
+#define ADIS16203_ERROR_ACTIVE          (1<<14)
+
+/**
+ * struct adis16203_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16203_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+int adis16203_set_irq(struct device *dev, bool enable);
+
+#ifdef CONFIG_IIO_RING_BUFFER
+enum adis16203_scan {
+	ADIS16203_SCAN_SUPPLY,
+	ADIS16203_SCAN_AUX_ADC,
+	ADIS16203_SCAN_TEMP,
+	ADIS16203_SCAN_INCLI_X,
+	ADIS16203_SCAN_INCLI_Y,
+};
+
+void adis16203_remove_trigger(struct iio_dev *indio_dev);
+int adis16203_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16203_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+int adis16203_configure_ring(struct iio_dev *indio_dev);
+void adis16203_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16203_initialize_ring(struct iio_ring_buffer *ring);
+void adis16203_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16203_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16203_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16203_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16203_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16203_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16203_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16203_H_ */
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
new file mode 100644
index 0000000..b57f190
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -0,0 +1,568 @@
+/*
+ * ADIS16203 Programmable Digital Vibration Sensor driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "accel.h"
+#include "inclinometer.h"
+#include "../gyro/gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16203.h"
+
+#define DRIVER_NAME		"adis16203"
+
+static int adis16203_check_status(struct device *dev);
+
+/**
+ * adis16203_spi_write_reg_8() - write single byte to a register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be written
+ * @val: the value to write
+ **/
+static int adis16203_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16203_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: value to be written
+ **/
+static int adis16203_spi_write_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.tx_buf = st->tx + 2,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16203_WRITE_REG(lower_reg_address);
+	st->tx[1] = value & 0xFF;
+	st->tx[2] = ADIS16203_WRITE_REG(lower_reg_address + 1);
+	st->tx[3] = (value >> 8) & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: somewhere to pass back the value read
+ **/
+static int adis16203_spi_read_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.delay_usecs = 20,
+		}, {
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.delay_usecs = 20,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16203_READ_REG(lower_reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				lower_reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[0] << 8) | st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t adis16203_read_12bit_unsigned(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = adis16203_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	if (val & ADIS16203_ERROR_ACTIVE)
+		adis16203_check_status(dev);
+
+	return sprintf(buf, "%u\n", val & 0x0FFF);
+}
+
+static ssize_t adis16203_read_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	ssize_t ret;
+	u16 val;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16203_spi_read_reg_16(dev, ADIS16203_TEMP_OUT, (u16 *)&val);
+	if (ret)
+		goto error_ret;
+
+	if (val & ADIS16203_ERROR_ACTIVE)
+		adis16203_check_status(dev);
+
+	val &= 0xFFF;
+	ret = sprintf(buf, "%d\n", val);
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
+}
+
+static ssize_t adis16203_read_14bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	s16 val = 0;
+	ssize_t ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16203_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (!ret) {
+		if (val & ADIS16203_ERROR_ACTIVE)
+			adis16203_check_status(dev);
+
+		val = ((s16)(val << 2) >> 2);
+		ret = sprintf(buf, "%d\n", val);
+	}
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16203_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16203_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int adis16203_reset(struct device *dev)
+{
+	int ret;
+	ret = adis16203_spi_write_reg_8(dev,
+			ADIS16203_GLOB_CMD,
+			ADIS16203_GLOB_CMD_SW_RESET);
+	if (ret)
+		dev_err(dev, "problem resetting device");
+
+	return ret;
+}
+
+static ssize_t adis16203_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -EINVAL;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return adis16203_reset(dev);
+	}
+	return -EINVAL;
+}
+
+int adis16203_set_irq(struct device *dev, bool enable)
+{
+	int ret = 0;
+	u16 msc;
+
+	ret = adis16203_spi_read_reg_16(dev, ADIS16203_MSC_CTRL, &msc);
+	if (ret)
+		goto error_ret;
+
+	msc |= ADIS16203_MSC_CTRL_ACTIVE_HIGH;
+	msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_DIO1;
+	if (enable)
+		msc |= ADIS16203_MSC_CTRL_DATA_RDY_EN;
+	else
+		msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN;
+
+	ret = adis16203_spi_write_reg_16(dev, ADIS16203_MSC_CTRL, msc);
+
+error_ret:
+	return ret;
+}
+
+static int adis16203_check_status(struct device *dev)
+{
+	u16 status;
+	int ret;
+
+	ret = adis16203_spi_read_reg_16(dev, ADIS16203_DIAG_STAT, &status);
+	if (ret < 0) {
+		dev_err(dev, "Reading status failed\n");
+		goto error_ret;
+	}
+	ret = status & 0x1F;
+
+	if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL)
+		dev_err(dev, "Self test failure\n");
+	if (status & ADIS16203_DIAG_STAT_SPI_FAIL)
+		dev_err(dev, "SPI failure\n");
+	if (status & ADIS16203_DIAG_STAT_FLASH_UPT)
+		dev_err(dev, "Flash update failed\n");
+	if (status & ADIS16203_DIAG_STAT_POWER_HIGH)
+		dev_err(dev, "Power supply above 3.625V\n");
+	if (status & ADIS16203_DIAG_STAT_POWER_LOW)
+		dev_err(dev, "Power supply below 3.15V\n");
+
+error_ret:
+	return ret;
+}
+
+static int adis16203_self_test(struct device *dev)
+{
+	int ret;
+	ret = adis16203_spi_write_reg_16(dev,
+			ADIS16203_MSC_CTRL,
+			ADIS16203_MSC_CTRL_SELF_TEST_EN);
+	if (ret) {
+		dev_err(dev, "problem starting self test");
+		goto err_ret;
+	}
+
+	adis16203_check_status(dev);
+
+err_ret:
+	return ret;
+}
+
+static int adis16203_initial_setup(struct adis16203_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* Disable IRQ */
+	ret = adis16203_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	/* Do self test */
+	ret = adis16203_self_test(dev);
+	if (ret) {
+		dev_err(dev, "self test failure");
+		goto err_ret;
+	}
+
+	/* Read status register to check the result */
+	ret = adis16203_check_status(dev);
+	if (ret) {
+		adis16203_reset(dev);
+		dev_err(dev, "device not playing ball -> reset");
+		msleep(ADIS16203_STARTUP_DELAY);
+		ret = adis16203_check_status(dev);
+		if (ret) {
+			dev_err(dev, "giving up");
+			goto err_ret;
+		}
+	}
+
+	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
+			st->us->chip_select, st->us->irq);
+
+err_ret:
+	return ret;
+}
+
+static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16203_read_12bit_unsigned,
+		ADIS16203_SUPPLY_OUT);
+static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
+static IIO_DEV_ATTR_IN_RAW(1, adis16203_read_12bit_unsigned,
+		ADIS16203_AUX_ADC);
+static IIO_CONST_ATTR(in1_scale, "0.00061");
+
+static IIO_DEV_ATTR_INCLI_X(adis16203_read_14bit_signed,
+		ADIS16203_XINCL_OUT);
+static IIO_DEV_ATTR_INCLI_Y(adis16203_read_14bit_signed,
+		ADIS16203_YINCL_OUT);
+static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
+		adis16203_read_14bit_signed,
+		adis16203_write_16bit,
+		ADIS16203_INCL_NULL);
+static IIO_CONST_ATTR(incli_scale, "0.025");
+
+static IIO_DEV_ATTR_TEMP_RAW(adis16203_read_temp);
+static IIO_CONST_ATTR(temp_offset, "25");
+static IIO_CONST_ATTR(temp_scale, "-0.47");
+
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0);
+
+static IIO_CONST_ATTR(name, "adis16203");
+
+static struct attribute *adis16203_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16203_event_attribute_group = {
+	.attrs = adis16203_event_attributes,
+};
+
+static struct attribute *adis16203_attributes[] = {
+	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
+	&iio_const_attr_in0_supply_scale.dev_attr.attr,
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_in1_raw.dev_attr.attr,
+	&iio_const_attr_in1_scale.dev_attr.attr,
+	&iio_dev_attr_incli_x_raw.dev_attr.attr,
+	&iio_dev_attr_incli_y_raw.dev_attr.attr,
+	&iio_dev_attr_incli_x_offset.dev_attr.attr,
+	&iio_const_attr_incli_scale.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16203_attribute_group = {
+	.attrs = adis16203_attributes,
+};
+
+static int __devinit adis16203_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16203_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16203_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16203_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16203_event_attribute_group;
+	st->indio_dev->attrs = &adis16203_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16203_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16203_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16203");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16203_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = adis16203_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	adis16203_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (spi->irq)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16203_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16203_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int adis16203_remove(struct spi_device *spi)
+{
+	struct adis16203_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	adis16203_remove_trigger(indio_dev);
+	if (spi->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16203_uninitialize_ring(indio_dev->ring);
+	iio_device_unregister(indio_dev);
+	adis16203_unconfigure_ring(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver adis16203_driver = {
+	.driver = {
+		.name = "adis16203",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16203_probe,
+	.remove = __devexit_p(adis16203_remove),
+};
+
+static __init int adis16203_init(void)
+{
+	return spi_register_driver(&adis16203_driver);
+}
+module_init(adis16203_init);
+
+static __exit void adis16203_exit(void)
+{
+	spi_unregister_driver(&adis16203_driver);
+}
+module_exit(adis16203_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable Digital Vibration Sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
new file mode 100644
index 0000000..3d774f7
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -0,0 +1,211 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_sw.h"
+#include "accel.h"
+#include "../trigger.h"
+#include "adis16203.h"
+
+static IIO_SCAN_EL_C(in_supply, ADIS16203_SCAN_SUPPLY, ADIS16203_SUPPLY_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
+static IIO_SCAN_EL_C(in0, ADIS16203_SCAN_AUX_ADC, ADIS16203_AUX_ADC, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
+static IIO_SCAN_EL_C(temp, ADIS16203_SCAN_TEMP, ADIS16203_TEMP_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
+static IIO_SCAN_EL_C(incli_x, ADIS16203_SCAN_INCLI_X,
+		     ADIS16203_XINCL_OUT, NULL);
+static IIO_SCAN_EL_C(incli_y, ADIS16203_SCAN_INCLI_Y,
+		     ADIS16203_YINCL_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
+static IIO_SCAN_EL_TIMESTAMP(5);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
+
+static struct attribute *adis16203_scan_el_attrs[] = {
+	&iio_scan_el_in_supply.dev_attr.attr,
+	&iio_const_attr_in_supply_index.dev_attr.attr,
+	&iio_const_attr_in_supply_type.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
+	&iio_const_attr_in0_index.dev_attr.attr,
+	&iio_const_attr_in0_type.dev_attr.attr,
+	&iio_scan_el_temp.dev_attr.attr,
+	&iio_const_attr_temp_index.dev_attr.attr,
+	&iio_const_attr_temp_type.dev_attr.attr,
+	&iio_scan_el_incli_x.dev_attr.attr,
+	&iio_const_attr_incli_x_index.dev_attr.attr,
+	&iio_scan_el_incli_y.dev_attr.attr,
+	&iio_const_attr_incli_y_index.dev_attr.attr,
+	&iio_const_attr_incli_type.dev_attr.attr,
+	&iio_scan_el_timestamp.dev_attr.attr,
+	&iio_const_attr_timestamp_index.dev_attr.attr,
+	&iio_const_attr_timestamp_type.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adis16203_scan_el_group = {
+	.attrs = adis16203_scan_el_attrs,
+	.name = "scan_elements",
+};
+
+/**
+ * adis16203_poll_func_th() top half interrupt handler called by trigger
+ * @private_data:	iio_dev
+ **/
+static void adis16203_poll_func_th(struct iio_dev *indio_dev, s64 timestamp)
+{
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+	st->last_timestamp = timestamp;
+	schedule_work(&st->work_trigger_to_ring);
+}
+
+/**
+ * adis16203_read_ring_data() read data registers which will be placed into ring
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read
+ **/
+static int adis16203_read_ring_data(struct device *dev, u8 *rx)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[ADIS16203_OUTPUTS + 1];
+	int ret;
+	int i;
+
+	mutex_lock(&st->buf_lock);
+
+	spi_message_init(&msg);
+
+	memset(xfers, 0, sizeof(xfers));
+	for (i = 0; i <= ADIS16203_OUTPUTS; i++) {
+		xfers[i].bits_per_word = 8;
+		xfers[i].cs_change = 1;
+		xfers[i].len = 2;
+		xfers[i].delay_usecs = 20;
+		xfers[i].tx_buf = st->tx + 2 * i;
+		if (i < 1) /* SUPPLY_OUT: 0x02, AUX_ADC: 0x08 */
+			st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i);
+		else
+			st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i + 6);
+		st->tx[2 * i + 1] = 0;
+		if (i >= 1)
+			xfers[i].rx_buf = rx + 2 * (i - 1);
+		spi_message_add_tail(&xfers[i], &msg);
+	}
+
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when burst reading");
+
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+ * specific to be rolled into the core.
+ */
+static void adis16203_trigger_bh_to_ring(struct work_struct *work_s)
+{
+	struct adis16203_state *st
+		= container_of(work_s, struct adis16203_state,
+			       work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
+
+	int i = 0;
+	s16 *data;
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
+
+	data = kmalloc(datasize, GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed in ring bh");
+		return;
+	}
+
+	if (ring->scan_count)
+		if (adis16203_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+			for (; i < ring->scan_count; i++)
+				data[i] = be16_to_cpup(
+					(__be16 *)&(st->rx[i*2]));
+
+	/* Guaranteed to be aligned with 8 byte boundary */
+	if (ring->scan_timestamp)
+		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+
+	ring->access.store_to(ring,
+			      (u8 *)data,
+			      st->last_timestamp);
+
+	iio_trigger_notify_done(st->indio_dev->trig);
+	kfree(data);
+
+	return;
+}
+
+void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
+{
+	kfree(indio_dev->pollfunc);
+	iio_sw_rb_free(indio_dev->ring);
+}
+
+int adis16203_configure_ring(struct iio_dev *indio_dev)
+{
+	int ret = 0;
+	struct adis16203_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring;
+	INIT_WORK(&st->work_trigger_to_ring, adis16203_trigger_bh_to_ring);
+
+	ring = iio_sw_rb_allocate(indio_dev);
+	if (!ring) {
+		ret = -ENOMEM;
+		return ret;
+	}
+	indio_dev->ring = ring;
+	/* Effectively select the ring buffer implementation */
+	iio_ring_sw_register_funcs(&ring->access);
+	ring->bpe = 2;
+	ring->scan_el_attrs = &adis16203_scan_el_group;
+	ring->scan_timestamp = true;
+	ring->preenable = &iio_sw_ring_preenable;
+	ring->postenable = &iio_triggered_ring_postenable;
+	ring->predisable = &iio_triggered_ring_predisable;
+	ring->owner = THIS_MODULE;
+
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_temp.number);
+	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
+	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+
+	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16203_poll_func_th);
+	if (ret)
+		goto error_iio_sw_rb_free;
+
+	indio_dev->modes |= INDIO_RING_TRIGGERED;
+	return 0;
+
+error_iio_sw_rb_free:
+	iio_sw_rb_free(indio_dev->ring);
+	return ret;
+}
+
+int adis16203_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return iio_ring_buffer_register(ring, 0);
+}
+
+void adis16203_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+	iio_ring_buffer_unregister(ring);
+}
diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c
new file mode 100644
index 0000000..50be51c2
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16203_trigger.c
@@ -0,0 +1,122 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../trigger.h"
+#include "adis16203.h"
+
+/**
+ * adis16203_data_rdy_trig_poll() the event handler for the data rdy trig
+ **/
+static int adis16203_data_rdy_trig_poll(struct iio_dev *dev_info,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
+{
+	struct adis16203_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_trigger *trig = st->trig;
+
+	iio_trigger_poll(trig, timestamp);
+
+	return IRQ_HANDLED;
+}
+
+IIO_EVENT_SH(data_rdy_trig, &adis16203_data_rdy_trig_poll);
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static struct attribute *adis16203_trigger_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group adis16203_trigger_attr_group = {
+	.attrs = adis16203_trigger_attrs,
+};
+
+/**
+ * adis16203_data_rdy_trigger_set_state() set datardy interrupt state
+ **/
+static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig,
+						bool state)
+{
+	struct adis16203_state *st = trig->private_data;
+	struct iio_dev *indio_dev = st->indio_dev;
+	int ret = 0;
+
+	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
+	ret = adis16203_set_irq(&st->indio_dev->dev, state);
+	if (state == false) {
+		iio_remove_event_from_list(&iio_event_data_rdy_trig,
+					   &indio_dev->interrupts[0]
+					   ->ev_list);
+		flush_scheduled_work();
+	} else {
+		iio_add_event_to_list(&iio_event_data_rdy_trig,
+				      &indio_dev->interrupts[0]->ev_list);
+	}
+	return ret;
+}
+
+/**
+ * adis16203_trig_try_reen() try renabling irq for data rdy trigger
+ * @trig:	the datardy trigger
+ **/
+static int adis16203_trig_try_reen(struct iio_trigger *trig)
+{
+	struct adis16203_state *st = trig->private_data;
+	enable_irq(st->us->irq);
+	return 0;
+}
+
+int adis16203_probe_trigger(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct adis16203_state *st = indio_dev->dev_data;
+
+	st->trig = iio_allocate_trigger();
+	st->trig->name = kasprintf(GFP_KERNEL,
+				"adis16203-dev%d",
+				indio_dev->id);
+	if (!st->trig->name) {
+		ret = -ENOMEM;
+		goto error_free_trig;
+	}
+	st->trig->dev.parent = &st->us->dev;
+	st->trig->owner = THIS_MODULE;
+	st->trig->private_data = st;
+	st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state;
+	st->trig->try_reenable = &adis16203_trig_try_reen;
+	st->trig->control_attrs = &adis16203_trigger_attr_group;
+	ret = iio_trigger_register(st->trig);
+
+	/* select default trigger */
+	indio_dev->trig = st->trig;
+	if (ret)
+		goto error_free_trig_name;
+
+	return 0;
+
+error_free_trig_name:
+	kfree(st->trig->name);
+error_free_trig:
+	iio_free_trigger(st->trig);
+
+	return ret;
+}
+
+void adis16203_remove_trigger(struct iio_dev *indio_dev)
+{
+	struct adis16203_state *state = indio_dev->dev_data;
+
+	iio_trigger_unregister(state->trig);
+	kfree(state->trig->name);
+	iio_free_trigger(state->trig);
+}
diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h
new file mode 100644
index 0000000..e9ed7cb
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16204.h
@@ -0,0 +1,151 @@
+#ifndef SPI_ADIS16204_H_
+#define SPI_ADIS16204_H_
+
+#define ADIS16204_STARTUP_DELAY	220 /* ms */
+
+#define ADIS16204_READ_REG(a)    a
+#define ADIS16204_WRITE_REG(a) ((a) | 0x80)
+
+#define ADIS16204_FLASH_CNT      0x00 /* Flash memory write count */
+#define ADIS16204_SUPPLY_OUT     0x02 /* Output, power supply */
+#define ADIS16204_XACCL_OUT      0x04 /* Output, x-axis accelerometer */
+#define ADIS16204_YACCL_OUT      0x06 /* Output, y-axis accelerometer */
+#define ADIS16204_AUX_ADC        0x08 /* Output, auxiliary ADC input */
+#define ADIS16204_TEMP_OUT       0x0A /* Output, temperature */
+#define ADIS16204_X_PEAK_OUT     0x0C /* Twos complement */
+#define ADIS16204_Y_PEAK_OUT     0x0E /* Twos complement */
+#define ADIS16204_XACCL_NULL     0x10 /* Calibration, x-axis acceleration offset null */
+#define ADIS16204_YACCL_NULL     0x12 /* Calibration, y-axis acceleration offset null */
+#define ADIS16204_XACCL_SCALE    0x14 /* X-axis scale factor calibration register */
+#define ADIS16204_YACCL_SCALE    0x16 /* Y-axis scale factor calibration register */
+#define ADIS16204_XY_RSS_OUT     0x18 /* XY combined acceleration (RSS) */
+#define ADIS16204_XY_PEAK_OUT    0x1A /* Peak, XY combined output (RSS) */
+#define ADIS16204_CAP_BUF_1      0x1C /* Capture buffer output register 1 */
+#define ADIS16204_CAP_BUF_2      0x1E /* Capture buffer output register 2 */
+#define ADIS16204_ALM_MAG1       0x20 /* Alarm 1 amplitude threshold */
+#define ADIS16204_ALM_MAG2       0x22 /* Alarm 2 amplitude threshold */
+#define ADIS16204_ALM_CTRL       0x28 /* Alarm control */
+#define ADIS16204_CAPT_PNTR      0x2A /* Capture register address pointer */
+#define ADIS16204_AUX_DAC        0x30 /* Auxiliary DAC data */
+#define ADIS16204_GPIO_CTRL      0x32 /* General-purpose digital input/output control */
+#define ADIS16204_MSC_CTRL       0x34 /* Miscellaneous control */
+#define ADIS16204_SMPL_PRD       0x36 /* Internal sample period (rate) control */
+#define ADIS16204_AVG_CNT        0x38 /* Operation, filter configuration */
+#define ADIS16204_SLP_CNT        0x3A /* Operation, sleep mode control */
+#define ADIS16204_DIAG_STAT      0x3C /* Diagnostics, system status register */
+#define ADIS16204_GLOB_CMD       0x3E /* Operation, system command register */
+
+#define ADIS16204_OUTPUTS        5
+
+/* MSC_CTRL */
+#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST	(1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */
+#define ADIS16204_MSC_CTRL_SELF_TEST_EN	        (1 << 8)  /* Self-test enable */
+#define ADIS16204_MSC_CTRL_DATA_RDY_EN	        (1 << 2)  /* Data-ready enable: 1 = enabled, 0 = disabled */
+#define ADIS16204_MSC_CTRL_ACTIVE_HIGH	        (1 << 1)  /* Data-ready polarity: 1 = active high, 0 = active low */
+#define ADIS16204_MSC_CTRL_DATA_RDY_DIO2	(1 << 0)  /* Data-ready line selection: 1 = DIO2, 0 = DIO1 */
+
+/* DIAG_STAT */
+#define ADIS16204_DIAG_STAT_ALARM2        (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16204_DIAG_STAT_ALARM1        (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */
+#define ADIS16204_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag: 1 = error condition,
+						0 = normal operation */
+#define ADIS16204_DIAG_STAT_SPI_FAIL	  (1<<3) /* SPI communications failure */
+#define ADIS16204_DIAG_STAT_FLASH_UPT	  (1<<2) /* Flash update failure */
+#define ADIS16204_DIAG_STAT_POWER_HIGH	  (1<<1) /* Power supply above 3.625 V */
+#define ADIS16204_DIAG_STAT_POWER_LOW	  (1<<0) /* Power supply below 2.975 V */
+
+/* GLOB_CMD */
+#define ADIS16204_GLOB_CMD_SW_RESET	(1<<7)
+#define ADIS16204_GLOB_CMD_CLEAR_STAT	(1<<4)
+#define ADIS16204_GLOB_CMD_FACTORY_CAL	(1<<1)
+
+#define ADIS16204_MAX_TX 24
+#define ADIS16204_MAX_RX 24
+
+#define ADIS16204_ERROR_ACTIVE          (1<<14)
+
+/**
+ * struct adis16204_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16204_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+int adis16204_set_irq(struct device *dev, bool enable);
+
+#ifdef CONFIG_IIO_RING_BUFFER
+enum adis16204_scan {
+	ADIS16204_SCAN_SUPPLY,
+	ADIS16204_SCAN_ACC_X,
+	ADIS16204_SCAN_ACC_Y,
+	ADIS16204_SCAN_AUX_ADC,
+	ADIS16204_SCAN_TEMP,
+};
+
+void adis16204_remove_trigger(struct iio_dev *indio_dev);
+int adis16204_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16204_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+int adis16204_configure_ring(struct iio_dev *indio_dev);
+void adis16204_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16204_initialize_ring(struct iio_ring_buffer *ring);
+void adis16204_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16204_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16204_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16204_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16204_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16204_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16204_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16204_H_ */
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
new file mode 100644
index 0000000..cc15e40
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -0,0 +1,613 @@
+/*
+ * ADIS16204 Programmable High-g Digital Impact Sensor and Recorder
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "accel.h"
+#include "../gyro/gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16204.h"
+
+#define DRIVER_NAME		"adis16204"
+
+static int adis16204_check_status(struct device *dev);
+
+/**
+ * adis16204_spi_write_reg_8() - write single byte to a register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be written
+ * @val: the value to write
+ **/
+static int adis16204_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16204_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: value to be written
+ **/
+static int adis16204_spi_write_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.tx_buf = st->tx + 2,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address);
+	st->tx[1] = value & 0xFF;
+	st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1);
+	st->tx[3] = (value >> 8) & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: somewhere to pass back the value read
+ **/
+static int adis16204_spi_read_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.delay_usecs = 20,
+		}, {
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.delay_usecs = 20,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16204_READ_REG(lower_reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				lower_reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[0] << 8) | st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t adis16204_read_12bit_unsigned(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = adis16204_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	if (val & ADIS16204_ERROR_ACTIVE)
+		adis16204_check_status(dev);
+
+	return sprintf(buf, "%u\n", val & 0x0FFF);
+}
+
+static ssize_t adis16204_read_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	ssize_t ret;
+	u16 val;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16204_spi_read_reg_16(dev, ADIS16204_TEMP_OUT, (u16 *)&val);
+	if (ret)
+		goto error_ret;
+
+	if (val & ADIS16204_ERROR_ACTIVE)
+		adis16204_check_status(dev);
+
+	val &= 0xFFF;
+	ret = sprintf(buf, "%d\n", val);
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
+}
+
+static ssize_t adis16204_read_12bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	s16 val = 0;
+	ssize_t ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (!ret) {
+		if (val & ADIS16204_ERROR_ACTIVE)
+			adis16204_check_status(dev);
+
+		val = ((s16)(val << 4) >> 4);
+		ret = sprintf(buf, "%d\n", val);
+	}
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16204_read_14bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	s16 val = 0;
+	ssize_t ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (!ret) {
+		if (val & ADIS16204_ERROR_ACTIVE)
+			adis16204_check_status(dev);
+
+		val = ((s16)(val << 2) >> 2);
+		ret = sprintf(buf, "%d\n", val);
+	}
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16204_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16204_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int adis16204_reset(struct device *dev)
+{
+	int ret;
+	ret = adis16204_spi_write_reg_8(dev,
+			ADIS16204_GLOB_CMD,
+			ADIS16204_GLOB_CMD_SW_RESET);
+	if (ret)
+		dev_err(dev, "problem resetting device");
+
+	return ret;
+}
+
+static ssize_t adis16204_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -EINVAL;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return adis16204_reset(dev);
+	}
+	return -EINVAL;
+}
+
+int adis16204_set_irq(struct device *dev, bool enable)
+{
+	int ret = 0;
+	u16 msc;
+
+	ret = adis16204_spi_read_reg_16(dev, ADIS16204_MSC_CTRL, &msc);
+	if (ret)
+		goto error_ret;
+
+	msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH;
+	msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2;
+	if (enable)
+		msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN;
+	else
+		msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN;
+
+	ret = adis16204_spi_write_reg_16(dev, ADIS16204_MSC_CTRL, msc);
+
+error_ret:
+	return ret;
+}
+
+static int adis16204_check_status(struct device *dev)
+{
+	u16 status;
+	int ret;
+
+	ret = adis16204_spi_read_reg_16(dev, ADIS16204_DIAG_STAT, &status);
+	if (ret < 0) {
+		dev_err(dev, "Reading status failed\n");
+		goto error_ret;
+	}
+	ret = status & 0x1F;
+
+	if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
+		dev_err(dev, "Self test failure\n");
+	if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
+		dev_err(dev, "SPI failure\n");
+	if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
+		dev_err(dev, "Flash update failed\n");
+	if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
+		dev_err(dev, "Power supply above 3.625V\n");
+	if (status & ADIS16204_DIAG_STAT_POWER_LOW)
+		dev_err(dev, "Power supply below 2.975V\n");
+
+error_ret:
+	return ret;
+}
+
+static int adis16204_self_test(struct device *dev)
+{
+	int ret;
+	ret = adis16204_spi_write_reg_16(dev,
+			ADIS16204_MSC_CTRL,
+			ADIS16204_MSC_CTRL_SELF_TEST_EN);
+	if (ret) {
+		dev_err(dev, "problem starting self test");
+		goto err_ret;
+	}
+
+	adis16204_check_status(dev);
+
+err_ret:
+	return ret;
+}
+
+static int adis16204_initial_setup(struct adis16204_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* Disable IRQ */
+	ret = adis16204_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	/* Do self test */
+	ret = adis16204_self_test(dev);
+	if (ret) {
+		dev_err(dev, "self test failure");
+		goto err_ret;
+	}
+
+	/* Read status register to check the result */
+	ret = adis16204_check_status(dev);
+	if (ret) {
+		adis16204_reset(dev);
+		dev_err(dev, "device not playing ball -> reset");
+		msleep(ADIS16204_STARTUP_DELAY);
+		ret = adis16204_check_status(dev);
+		if (ret) {
+			dev_err(dev, "giving up");
+			goto err_ret;
+		}
+	}
+
+	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
+			st->us->chip_select, st->us->irq);
+
+err_ret:
+	return ret;
+}
+
+static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16204_read_12bit_unsigned,
+		ADIS16204_SUPPLY_OUT);
+static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
+static IIO_DEV_ATTR_IN_RAW(1, adis16204_read_12bit_unsigned,
+		ADIS16204_AUX_ADC);
+static IIO_CONST_ATTR(in1_scale, "0.00061");
+
+static IIO_DEV_ATTR_ACCEL_X(adis16204_read_14bit_signed,
+		ADIS16204_XACCL_OUT);
+static IIO_DEV_ATTR_ACCEL_Y(adis16204_read_14bit_signed,
+		ADIS16204_YACCL_OUT);
+static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed,
+		ADIS16204_XY_RSS_OUT);
+static IIO_DEV_ATTR_ACCEL_XPEAK(adis16204_read_14bit_signed,
+		ADIS16204_X_PEAK_OUT);
+static IIO_DEV_ATTR_ACCEL_YPEAK(adis16204_read_14bit_signed,
+		ADIS16204_Y_PEAK_OUT);
+static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed,
+		ADIS16204_XY_PEAK_OUT);
+static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+		adis16204_read_12bit_signed,
+		adis16204_write_16bit,
+		ADIS16204_XACCL_NULL);
+static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+		adis16204_read_12bit_signed,
+		adis16204_write_16bit,
+		ADIS16204_YACCL_NULL);
+static IIO_CONST_ATTR(accel_x_scale, "0.017125");
+static IIO_CONST_ATTR(accel_y_scale, "0.008407");
+static IIO_CONST_ATTR(accel_xy_scale, "0.017125");
+
+static IIO_DEV_ATTR_TEMP_RAW(adis16204_read_temp);
+static IIO_CONST_ATTR(temp_offset, "25");
+static IIO_CONST_ATTR(temp_scale, "-0.47");
+
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0);
+
+static IIO_CONST_ATTR(name, "adis16204");
+
+static struct attribute *adis16204_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16204_event_attribute_group = {
+	.attrs = adis16204_event_attributes,
+};
+
+static struct attribute *adis16204_attributes[] = {
+	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
+	&iio_const_attr_in0_supply_scale.dev_attr.attr,
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_in1_raw.dev_attr.attr,
+	&iio_const_attr_in1_scale.dev_attr.attr,
+	&iio_dev_attr_accel_x_raw.dev_attr.attr,
+	&iio_dev_attr_accel_y_raw.dev_attr.attr,
+	&iio_dev_attr_accel_xy.dev_attr.attr,
+	&iio_dev_attr_accel_xpeak.dev_attr.attr,
+	&iio_dev_attr_accel_ypeak.dev_attr.attr,
+	&iio_dev_attr_accel_xypeak.dev_attr.attr,
+	&iio_dev_attr_accel_x_offset.dev_attr.attr,
+	&iio_dev_attr_accel_y_offset.dev_attr.attr,
+	&iio_const_attr_accel_x_scale.dev_attr.attr,
+	&iio_const_attr_accel_y_scale.dev_attr.attr,
+	&iio_const_attr_accel_xy_scale.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16204_attribute_group = {
+	.attrs = adis16204_attributes,
+};
+
+static int __devinit adis16204_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16204_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16204_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16204_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16204_event_attribute_group;
+	st->indio_dev->attrs = &adis16204_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16204_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16204_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16204");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16204_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = adis16204_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	adis16204_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (spi->irq)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16204_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16204_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int adis16204_remove(struct spi_device *spi)
+{
+	struct adis16204_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	adis16204_remove_trigger(indio_dev);
+	if (spi->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16204_uninitialize_ring(indio_dev->ring);
+	iio_device_unregister(indio_dev);
+	adis16204_unconfigure_ring(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver adis16204_driver = {
+	.driver = {
+		.name = "adis16204",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16204_probe,
+	.remove = __devexit_p(adis16204_remove),
+};
+
+static __init int adis16204_init(void)
+{
+	return spi_register_driver(&adis16204_driver);
+}
+module_init(adis16204_init);
+
+static __exit void adis16204_exit(void)
+{
+	spi_unregister_driver(&adis16204_driver);
+}
+module_exit(adis16204_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
new file mode 100644
index 0000000..420b160f
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -0,0 +1,206 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_sw.h"
+#include "accel.h"
+#include "../trigger.h"
+#include "adis16204.h"
+
+static IIO_SCAN_EL_C(in_supply, ADIS16204_SCAN_SUPPLY, ADIS16204_SUPPLY_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
+static IIO_SCAN_EL_C(accel_x, ADIS16204_SCAN_ACC_X, ADIS16204_XACCL_OUT, NULL);
+static IIO_SCAN_EL_C(accel_y, ADIS16204_SCAN_ACC_Y, ADIS16204_YACCL_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
+static IIO_SCAN_EL_C(in0, ADIS16204_SCAN_AUX_ADC, ADIS16204_AUX_ADC, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
+static IIO_SCAN_EL_C(temp, ADIS16204_SCAN_TEMP, ADIS16204_TEMP_OUT, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
+static IIO_SCAN_EL_TIMESTAMP(5);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
+
+static struct attribute *adis16204_scan_el_attrs[] = {
+	&iio_scan_el_in_supply.dev_attr.attr,
+	&iio_const_attr_in_supply_index.dev_attr.attr,
+	&iio_const_attr_in_supply_type.dev_attr.attr,
+	&iio_scan_el_accel_x.dev_attr.attr,
+	&iio_const_attr_accel_x_index.dev_attr.attr,
+	&iio_scan_el_accel_y.dev_attr.attr,
+	&iio_const_attr_accel_y_index.dev_attr.attr,
+	&iio_const_attr_accel_type.dev_attr.attr,
+	&iio_scan_el_in0.dev_attr.attr,
+	&iio_const_attr_in0_index.dev_attr.attr,
+	&iio_const_attr_in0_type.dev_attr.attr,
+	&iio_scan_el_temp.dev_attr.attr,
+	&iio_const_attr_temp_index.dev_attr.attr,
+	&iio_const_attr_temp_type.dev_attr.attr,
+	&iio_scan_el_timestamp.dev_attr.attr,
+	&iio_const_attr_timestamp_index.dev_attr.attr,
+	&iio_const_attr_timestamp_type.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adis16204_scan_el_group = {
+	.attrs = adis16204_scan_el_attrs,
+	.name = "scan_elements",
+};
+
+/**
+ * adis16204_poll_func_th() top half interrupt handler called by trigger
+ * @private_data:	iio_dev
+ **/
+static void adis16204_poll_func_th(struct iio_dev *indio_dev, s64 timestamp)
+{
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+	st->last_timestamp = timestamp;
+	schedule_work(&st->work_trigger_to_ring);
+}
+
+/**
+ * adis16204_read_ring_data() read data registers which will be placed into ring
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read
+ **/
+static int adis16204_read_ring_data(struct device *dev, u8 *rx)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[ADIS16204_OUTPUTS + 1];
+	int ret;
+	int i;
+
+	mutex_lock(&st->buf_lock);
+
+	spi_message_init(&msg);
+
+	memset(xfers, 0, sizeof(xfers));
+	for (i = 0; i <= ADIS16204_OUTPUTS; i++) {
+		xfers[i].bits_per_word = 8;
+		xfers[i].cs_change = 1;
+		xfers[i].len = 2;
+		xfers[i].delay_usecs = 20;
+		xfers[i].tx_buf = st->tx + 2 * i;
+		st->tx[2 * i] = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
+		st->tx[2 * i + 1] = 0;
+		if (i >= 1)
+			xfers[i].rx_buf = rx + 2 * (i - 1);
+		spi_message_add_tail(&xfers[i], &msg);
+	}
+
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when burst reading");
+
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+ * specific to be rolled into the core.
+ */
+static void adis16204_trigger_bh_to_ring(struct work_struct *work_s)
+{
+	struct adis16204_state *st
+		= container_of(work_s, struct adis16204_state,
+			       work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
+
+	int i = 0;
+	s16 *data;
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
+
+	data = kmalloc(datasize, GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed in ring bh");
+		return;
+	}
+
+	if (ring->scan_count)
+		if (adis16204_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+			for (; i < ring->scan_count; i++)
+				data[i] = be16_to_cpup(
+					(__be16 *)&(st->rx[i*2]));
+
+	/* Guaranteed to be aligned with 8 byte boundary */
+	if (ring->scan_timestamp)
+		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+
+	ring->access.store_to(ring,
+			      (u8 *)data,
+			      st->last_timestamp);
+
+	iio_trigger_notify_done(st->indio_dev->trig);
+	kfree(data);
+
+	return;
+}
+
+void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
+{
+	kfree(indio_dev->pollfunc);
+	iio_sw_rb_free(indio_dev->ring);
+}
+
+int adis16204_configure_ring(struct iio_dev *indio_dev)
+{
+	int ret = 0;
+	struct adis16204_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring;
+	INIT_WORK(&st->work_trigger_to_ring, adis16204_trigger_bh_to_ring);
+
+	ring = iio_sw_rb_allocate(indio_dev);
+	if (!ring) {
+		ret = -ENOMEM;
+		return ret;
+	}
+	indio_dev->ring = ring;
+	/* Effectively select the ring buffer implementation */
+	iio_ring_sw_register_funcs(&ring->access);
+	ring->bpe = 2;
+	ring->scan_el_attrs = &adis16204_scan_el_group;
+	ring->scan_timestamp = true;
+	ring->preenable = &iio_sw_ring_preenable;
+	ring->postenable = &iio_triggered_ring_postenable;
+	ring->predisable = &iio_triggered_ring_predisable;
+	ring->owner = THIS_MODULE;
+
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
+	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
+	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
+	iio_scan_mask_set(ring, iio_scan_el_temp.number);
+	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+
+	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16204_poll_func_th);
+	if (ret)
+		goto error_iio_sw_rb_free;
+
+	indio_dev->modes |= INDIO_RING_TRIGGERED;
+	return 0;
+
+error_iio_sw_rb_free:
+	iio_sw_rb_free(indio_dev->ring);
+	return ret;
+}
+
+int adis16204_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return iio_ring_buffer_register(ring, 0);
+}
+
+void adis16204_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+	iio_ring_buffer_unregister(ring);
+}
diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c
new file mode 100644
index 0000000..8e9db90
--- /dev/null
+++ b/drivers/staging/iio/accel/adis16204_trigger.c
@@ -0,0 +1,122 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../trigger.h"
+#include "adis16204.h"
+
+/**
+ * adis16204_data_rdy_trig_poll() the event handler for the data rdy trig
+ **/
+static int adis16204_data_rdy_trig_poll(struct iio_dev *dev_info,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
+{
+	struct adis16204_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_trigger *trig = st->trig;
+
+	iio_trigger_poll(trig, timestamp);
+
+	return IRQ_HANDLED;
+}
+
+IIO_EVENT_SH(data_rdy_trig, &adis16204_data_rdy_trig_poll);
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static struct attribute *adis16204_trigger_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group adis16204_trigger_attr_group = {
+	.attrs = adis16204_trigger_attrs,
+};
+
+/**
+ * adis16204_data_rdy_trigger_set_state() set datardy interrupt state
+ **/
+static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig,
+						bool state)
+{
+	struct adis16204_state *st = trig->private_data;
+	struct iio_dev *indio_dev = st->indio_dev;
+	int ret = 0;
+
+	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
+	ret = adis16204_set_irq(&st->indio_dev->dev, state);
+	if (state == false) {
+		iio_remove_event_from_list(&iio_event_data_rdy_trig,
+					   &indio_dev->interrupts[0]
+					   ->ev_list);
+		flush_scheduled_work();
+	} else {
+		iio_add_event_to_list(&iio_event_data_rdy_trig,
+				      &indio_dev->interrupts[0]->ev_list);
+	}
+	return ret;
+}
+
+/**
+ * adis16204_trig_try_reen() try renabling irq for data rdy trigger
+ * @trig:	the datardy trigger
+ **/
+static int adis16204_trig_try_reen(struct iio_trigger *trig)
+{
+	struct adis16204_state *st = trig->private_data;
+	enable_irq(st->us->irq);
+	return 0;
+}
+
+int adis16204_probe_trigger(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct adis16204_state *st = indio_dev->dev_data;
+
+	st->trig = iio_allocate_trigger();
+	st->trig->name = kasprintf(GFP_KERNEL,
+				"adis16204-dev%d",
+				indio_dev->id);
+	if (!st->trig->name) {
+		ret = -ENOMEM;
+		goto error_free_trig;
+	}
+	st->trig->dev.parent = &st->us->dev;
+	st->trig->owner = THIS_MODULE;
+	st->trig->private_data = st;
+	st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state;
+	st->trig->try_reenable = &adis16204_trig_try_reen;
+	st->trig->control_attrs = &adis16204_trigger_attr_group;
+	ret = iio_trigger_register(st->trig);
+
+	/* select default trigger */
+	indio_dev->trig = st->trig;
+	if (ret)
+		goto error_free_trig_name;
+
+	return 0;
+
+error_free_trig_name:
+	kfree(st->trig->name);
+error_free_trig:
+	iio_free_trigger(st->trig);
+
+	return ret;
+}
+
+void adis16204_remove_trigger(struct iio_dev *indio_dev)
+{
+	struct adis16204_state *state = indio_dev->dev_data;
+
+	iio_trigger_unregister(state->trig);
+	kfree(state->trig->name);
+	iio_free_trigger(state->trig);
+}
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 033135c..8eba0af 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -105,7 +105,7 @@
 		xfers[i].bits_per_word = 8;
 		xfers[i].cs_change = 1;
 		xfers[i].len = 2;
-		xfers[i].delay_usecs = 20;
+		xfers[i].delay_usecs = 30;
 		xfers[i].tx_buf = st->tx + 2 * i;
 		st->tx[2 * i]
 			= ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i);
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index acb6767..9ca6565 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -27,6 +27,41 @@
 	  Say yes here to include ring buffer support in the MAX1363
 	  ADC driver.
 
+config AD7150
+	tristate "Analog Devices ad7150/1/6 capacitive sensor driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Analog Devices capacitive sensors.
+	  (ad7150, ad7151, ad7156) Provides direct access via sysfs.
+
+config AD7152
+	tristate "Analog Devices ad7152/3 capacitive sensor driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Analog Devices capacitive sensors.
+	  (ad7152, ad7153) Provides direct access via sysfs.
+
+config AD7291
+	tristate "Analog Devices AD7291 temperature sensor driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Analog Devices AD7291
+	  temperature sensors.
+
+config AD7298
+	tristate "Analog Devices AD7298 temperature sensor and ADC driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD7298
+	  temperature sensors and ADC.
+
+config AD7314
+	tristate "Analog Devices AD7314 temperature sensor driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD7314
+	  temperature sensors.
+
 config AD799X
 	tristate "Analog Devices AD799x ADC driver"
 	depends on I2C
@@ -50,9 +85,9 @@
 config AD7476
 	tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver"
 	depends on SPI
-	select IIO_RING_BUFFER	
+	select IIO_RING_BUFFER
 	select IIO_SW_RING
-	select IIO_TRIGGER 	
+	select IIO_TRIGGER
 	help
 	  Say yes here to build support for Analog Devices
 	  AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495
@@ -61,3 +96,41 @@
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad7476.
+
+config AD7745
+	tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Analog Devices capacitive sensors.
+	  (AD7745, AD7746, AD7747) Provides direct access via sysfs.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7745.
+
+config AD7816
+	tristate "Analog Devices AD7816/7/8 temperature sensor and ADC driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD7816/7/8
+	  temperature sensors and ADC.
+
+config ADT75
+	tristate "Analog Devices ADT75 temperature sensor driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Analog Devices ADT75
+	  temperature sensors.
+
+config ADT7310
+	tristate "Analog Devices ADT7310 temperature sensor driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADT7310
+	  temperature sensors.
+
+config ADT7410
+	tristate "Analog Devices ADT7410 temperature sensor driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Analog Devices ADT7410
+	  temperature sensors.
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index b62c319b..a7dce6b 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -14,3 +14,14 @@
 ad7476-y := ad7476_core.o
 ad7476-$(CONFIG_IIO_RING_BUFFER) += ad7476_ring.o
 obj-$(CONFIG_AD7476) += ad7476.o
+
+obj-$(CONFIG_AD7150) += ad7150.o
+obj-$(CONFIG_AD7152) += ad7152.o
+obj-$(CONFIG_AD7291) += ad7291.o
+obj-$(CONFIG_AD7298) += ad7298.o
+obj-$(CONFIG_AD7314) += ad7314.o
+obj-$(CONFIG_AD7745) += ad7745.o
+obj-$(CONFIG_AD7816) += ad7816.o
+obj-$(CONFIG_ADT75) += adt75.o
+obj-$(CONFIG_ADT7310) += adt7310.o
+obj-$(CONFIG_ADT7410) += adt7410.o
diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c
new file mode 100644
index 0000000..8555766
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7150.c
@@ -0,0 +1,877 @@
+/*
+ * AD7150 capacitive sensor driver supporting AD7150/1/6
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD7150 registers definition
+ */
+
+#define AD7150_STATUS              0
+#define AD7150_STATUS_OUT1         (1 << 3)
+#define AD7150_STATUS_OUT2         (1 << 5)
+#define AD7150_CH1_DATA_HIGH       1
+#define AD7150_CH1_DATA_LOW        2
+#define AD7150_CH2_DATA_HIGH       3
+#define AD7150_CH2_DATA_LOW        4
+#define AD7150_CH1_AVG_HIGH        5
+#define AD7150_CH1_AVG_LOW         6
+#define AD7150_CH2_AVG_HIGH        7
+#define AD7150_CH2_AVG_LOW         8
+#define AD7150_CH1_SENSITIVITY     9
+#define AD7150_CH1_THR_HOLD_H      9
+#define AD7150_CH1_TIMEOUT         10
+#define AD7150_CH1_THR_HOLD_L      10
+#define AD7150_CH1_SETUP           11
+#define AD7150_CH2_SENSITIVITY     12
+#define AD7150_CH2_THR_HOLD_H      12
+#define AD7150_CH2_TIMEOUT         13
+#define AD7150_CH2_THR_HOLD_L      13
+#define AD7150_CH2_SETUP           14
+#define AD7150_CFG                 15
+#define AD7150_CFG_FIX             (1 << 7)
+#define AD7150_PD_TIMER            16
+#define AD7150_CH1_CAPDAC          17
+#define AD7150_CH2_CAPDAC          18
+#define AD7150_SN3                 19
+#define AD7150_SN2                 20
+#define AD7150_SN1                 21
+#define AD7150_SN0                 22
+#define AD7150_ID                  23
+
+#define AD7150_MAX_CONV_MODE       4
+
+/*
+ * struct ad7150_chip_info - chip specifc information
+ */
+
+struct ad7150_chip_info {
+	const char *name;
+	struct i2c_client *client;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	bool inter;
+	s64 last_timestamp;
+	u16 ch1_threshold;     /* Ch1 Threshold (in fixed threshold mode) */
+	u8  ch1_sensitivity;   /* Ch1 Sensitivity (in adaptive threshold mode) */
+	u8  ch1_timeout;       /* Ch1 Timeout (in adaptive threshold mode) */
+	u8  ch1_setup;
+	u16 ch2_threshold;     /* Ch2 Threshold (in fixed threshold mode) */
+	u8  ch2_sensitivity;   /* Ch1 Sensitivity (in adaptive threshold mode) */
+	u8  ch2_timeout;       /* Ch1 Timeout (in adaptive threshold mode) */
+	u8  ch2_setup;
+	u8  powerdown_timer;
+	char threshold_mode[10]; /* adaptive/fixed threshold mode */
+	int old_state;
+	char *conversion_mode;
+};
+
+struct ad7150_conversion_mode {
+	char *name;
+	u8 reg_cfg;
+};
+
+struct ad7150_conversion_mode ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
+	{ "idle", 0 },
+	{ "continuous-conversion", 1 },
+	{ "single-conversion", 2 },
+	{ "power-down", 3 },
+};
+
+/*
+ * ad7150 register access by I2C
+ */
+
+static int ad7150_i2c_read(struct ad7150_chip_info *chip, u8 reg, u8 *data, int len)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_master_send(client, &reg, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C write error\n");
+		return ret;
+	}
+
+	ret = i2c_master_recv(client, data, len);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int ad7150_i2c_write(struct ad7150_chip_info *chip, u8 reg, u8 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	u8 tx[2] = {
+		reg,
+		data,
+	};
+
+	ret = i2c_master_send(client, tx, 2);
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+/*
+ * sysfs nodes
+ */
+
+#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)				\
+	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(_show)				\
+	IIO_DEVICE_ATTR(available_threshold_modes, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_THRESHOLD_MODE(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(threshold_mode, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_THRESHOLD(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(ch1_threshold, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_THRESHOLD(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(ch2_threshold, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_SENSITIVITY(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch1_sensitivity, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_SENSITIVITY(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch2_sensitivity, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_TIMEOUT(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch1_timeout, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_TIMEOUT(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch2_timeout, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_VALUE(_show)		\
+	IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CH2_VALUE(_show)		\
+	IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_POWERDOWN_TIMER(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(powerdown_timer, _mode, _show, _store, 0)
+
+static ssize_t ad7150_show_conversion_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int i;
+	int len = 0;
+
+	for (i = 0; i < AD7150_MAX_CONV_MODE; i++)
+		len += sprintf(buf + len, "%s\n", ad7150_conv_mode_table[i].name);
+
+	return len;
+}
+
+static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7150_show_conversion_modes);
+
+static ssize_t ad7150_show_conversion_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%s\n", chip->conversion_mode);
+}
+
+static ssize_t ad7150_store_conversion_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	u8 cfg;
+	int i;
+
+	ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1);
+
+	for (i = 0; i < AD7150_MAX_CONV_MODE; i++) {
+		if (strncmp(buf, ad7150_conv_mode_table[i].name,
+				strlen(ad7150_conv_mode_table[i].name) - 1) == 0) {
+			chip->conversion_mode = ad7150_conv_mode_table[i].name;
+			cfg |= 0x18 | ad7150_conv_mode_table[i].reg_cfg;
+			ad7150_i2c_write(chip, AD7150_CFG, cfg);
+			return len;
+		}
+	}
+
+	dev_err(dev, "not supported conversion mode\n");
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
+		ad7150_show_conversion_mode,
+		ad7150_store_conversion_mode);
+
+static ssize_t ad7150_show_threshold_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "adaptive\nfixed\n");
+}
+
+static IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(ad7150_show_threshold_modes);
+
+static ssize_t ad7150_show_ch1_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	u8 data[2];
+
+	ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2);
+	return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]);
+}
+
+static IIO_DEV_ATTR_CH1_VALUE(ad7150_show_ch1_value);
+
+static ssize_t ad7150_show_ch2_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	u8 data[2];
+
+	ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2);
+	return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]);
+}
+
+static IIO_DEV_ATTR_CH2_VALUE(ad7150_show_ch2_value);
+
+static ssize_t ad7150_show_threshold_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%s\n", chip->threshold_mode);
+}
+
+static ssize_t ad7150_store_threshold_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	u8 cfg;
+
+	ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1);
+
+	if (strncmp(buf, "fixed", 5) == 0) {
+		strcpy(chip->threshold_mode, "fixed");
+		cfg |= AD7150_CFG_FIX;
+		ad7150_i2c_write(chip, AD7150_CFG, cfg);
+
+		return len;
+	} else if (strncmp(buf, "adaptive", 8) == 0) {
+		strcpy(chip->threshold_mode, "adaptive");
+		cfg &= ~AD7150_CFG_FIX;
+		ad7150_i2c_write(chip, AD7150_CFG, cfg);
+
+		return len;
+	}
+
+	dev_err(dev, "not supported threshold mode\n");
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_THRESHOLD_MODE(S_IRUGO | S_IWUSR,
+		ad7150_show_threshold_mode,
+		ad7150_store_threshold_mode);
+
+static ssize_t ad7150_show_ch1_threshold(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch1_threshold);
+}
+
+static ssize_t ad7150_store_ch1_threshold(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_H, data >> 8);
+		ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_L, data);
+		chip->ch1_threshold = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_THRESHOLD(S_IRUGO | S_IWUSR,
+		ad7150_show_ch1_threshold,
+		ad7150_store_ch1_threshold);
+
+static ssize_t ad7150_show_ch2_threshold(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch2_threshold);
+}
+
+static ssize_t ad7150_store_ch2_threshold(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_H, data >> 8);
+		ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_L, data);
+		chip->ch2_threshold = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_THRESHOLD(S_IRUGO | S_IWUSR,
+		ad7150_show_ch2_threshold,
+		ad7150_store_ch2_threshold);
+
+static ssize_t ad7150_show_ch1_sensitivity(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch1_sensitivity);
+}
+
+static ssize_t ad7150_store_ch1_sensitivity(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7150_i2c_write(chip, AD7150_CH1_SENSITIVITY, data);
+		chip->ch1_sensitivity = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_SENSITIVITY(S_IRUGO | S_IWUSR,
+		ad7150_show_ch1_sensitivity,
+		ad7150_store_ch1_sensitivity);
+
+static ssize_t ad7150_show_ch2_sensitivity(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch2_sensitivity);
+}
+
+static ssize_t ad7150_store_ch2_sensitivity(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7150_i2c_write(chip, AD7150_CH2_SENSITIVITY, data);
+		chip->ch2_sensitivity = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_SENSITIVITY(S_IRUGO | S_IWUSR,
+		ad7150_show_ch2_sensitivity,
+		ad7150_store_ch2_sensitivity);
+
+static ssize_t ad7150_show_ch1_timeout(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch1_timeout);
+}
+
+static ssize_t ad7150_store_ch1_timeout(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7150_i2c_write(chip, AD7150_CH1_TIMEOUT, data);
+		chip->ch1_timeout = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR,
+		ad7150_show_ch1_timeout,
+		ad7150_store_ch1_timeout);
+
+static ssize_t ad7150_show_ch2_timeout(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch2_timeout);
+}
+
+static ssize_t ad7150_store_ch2_timeout(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7150_i2c_write(chip, AD7150_CH2_TIMEOUT, data);
+		chip->ch2_timeout = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR,
+		ad7150_show_ch2_timeout,
+		ad7150_store_ch2_timeout);
+
+static ssize_t ad7150_show_ch1_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->ch1_setup);
+}
+
+static ssize_t ad7150_store_ch1_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7150_i2c_write(chip, AD7150_CH1_SETUP, data);
+		chip->ch1_setup = data;
+		return len;
+	}
+
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
+		ad7150_show_ch1_setup,
+		ad7150_store_ch1_setup);
+
+static ssize_t ad7150_show_ch2_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->ch2_setup);
+}
+
+static ssize_t ad7150_store_ch2_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7150_i2c_write(chip, AD7150_CH2_SETUP, data);
+		chip->ch2_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
+		ad7150_show_ch2_setup,
+		ad7150_store_ch2_setup);
+
+static ssize_t ad7150_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad7150_show_name, NULL, 0);
+
+static ssize_t ad7150_show_powerdown_timer(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->powerdown_timer);
+}
+
+static ssize_t ad7150_store_powerdown_timer(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x40)) {
+		chip->powerdown_timer = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR,
+		ad7150_show_powerdown_timer,
+		ad7150_store_powerdown_timer);
+
+static struct attribute *ad7150_attributes[] = {
+	&iio_dev_attr_available_threshold_modes.dev_attr.attr,
+	&iio_dev_attr_threshold_mode.dev_attr.attr,
+	&iio_dev_attr_ch1_threshold.dev_attr.attr,
+	&iio_dev_attr_ch2_threshold.dev_attr.attr,
+	&iio_dev_attr_ch1_timeout.dev_attr.attr,
+	&iio_dev_attr_ch2_timeout.dev_attr.attr,
+	&iio_dev_attr_ch1_setup.dev_attr.attr,
+	&iio_dev_attr_ch2_setup.dev_attr.attr,
+	&iio_dev_attr_ch1_sensitivity.dev_attr.attr,
+	&iio_dev_attr_ch2_sensitivity.dev_attr.attr,
+	&iio_dev_attr_powerdown_timer.dev_attr.attr,
+	&iio_dev_attr_ch1_value.dev_attr.attr,
+	&iio_dev_attr_ch2_value.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7150_attribute_group = {
+	.attrs = ad7150_attributes,
+};
+
+/*
+ * threshold events
+ */
+
+#define IIO_EVENT_CODE_CH1_HIGH    IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_CH1_LOW     IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_CH2_HIGH    IIO_BUFFER_EVENT_CODE(2)
+#define IIO_EVENT_CODE_CH2_LOW     IIO_BUFFER_EVENT_CODE(3)
+
+#define IIO_EVENT_ATTR_CH1_HIGH_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(ch1_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_ATTR_CH2_HIGH_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(ch2_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_ATTR_CH1_LOW_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(ch1_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_ATTR_CH2_LOW_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(ch2_low, _evlist, _show, _store, _mask)
+
+static void ad7150_interrupt_handler_bh(struct work_struct *work_s)
+{
+	struct ad7150_chip_info *chip =
+		container_of(work_s, struct ad7150_chip_info, thresh_work);
+	u8 int_status;
+
+	enable_irq(chip->client->irq);
+
+	ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1);
+
+	if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1))
+		iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_CH1_HIGH,
+				chip->last_timestamp);
+	else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1))
+		iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_CH1_LOW,
+				chip->last_timestamp);
+
+	if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2))
+		iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_CH2_HIGH,
+				chip->last_timestamp);
+	else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2))
+		iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_CH2_LOW,
+				chip->last_timestamp);
+}
+
+static int ad7150_interrupt_handler_th(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct ad7150_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(threshold, &ad7150_interrupt_handler_th);
+
+static ssize_t ad7150_query_out_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	/*
+	 * AD7150 provides two logic output channels, which can be used as interrupt
+	 * but the pins are not configurable
+	 */
+	return sprintf(buf, "1\n");
+}
+
+static ssize_t ad7150_set_out_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return len;
+}
+
+IIO_EVENT_ATTR_CH1_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
+IIO_EVENT_ATTR_CH2_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
+IIO_EVENT_ATTR_CH1_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
+IIO_EVENT_ATTR_CH2_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
+
+static struct attribute *ad7150_event_attributes[] = {
+	&iio_event_attr_ch1_high.dev_attr.attr,
+	&iio_event_attr_ch2_high.dev_attr.attr,
+	&iio_event_attr_ch1_low.dev_attr.attr,
+	&iio_event_attr_ch2_low.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ad7150_event_attribute_group = {
+	.attrs = ad7150_event_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit ad7150_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int ret = 0, regdone = 0;
+	struct ad7150_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, chip);
+
+	chip->client = client;
+	chip->name = id->name;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	/* Echipabilish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->attrs = &ad7150_attribute_group;
+	chip->indio_dev->event_attrs = &ad7150_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)(chip);
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = 1;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+	regdone = 1;
+
+	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0) {
+		ret = iio_register_interrupt_line(client->irq,
+				chip->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"ad7150");
+		if (ret)
+			goto error_free_dev;
+
+		iio_add_event_to_list(iio_event_attr_ch2_low.listel,
+				&chip->indio_dev->interrupts[0]->ev_list);
+
+		INIT_WORK(&chip->thresh_work, ad7150_interrupt_handler_bh);
+	}
+
+	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
+
+	return 0;
+
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(chip->indio_dev);
+	else
+		iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad7150_remove(struct i2c_client *client)
+{
+	struct ad7150_chip_info *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad7150_id[] = {
+	{ "ad7150", 0 },
+	{ "ad7151", 0 },
+	{ "ad7156", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, ad7150_id);
+
+static struct i2c_driver ad7150_driver = {
+	.driver = {
+		.name = "ad7150",
+	},
+	.probe = ad7150_probe,
+	.remove = __devexit_p(ad7150_remove),
+	.id_table = ad7150_id,
+};
+
+static __init int ad7150_init(void)
+{
+	return i2c_add_driver(&ad7150_driver);
+}
+
+static __exit void ad7150_exit(void)
+{
+	i2c_del_driver(&ad7150_driver);
+}
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ad7150/1/6 capacitive sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad7150_init);
+module_exit(ad7150_exit);
diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c
new file mode 100644
index 0000000..fa7f8406
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7152.c
@@ -0,0 +1,610 @@
+/*
+ * AD7152 capacitive sensor driver supporting AD7152/3
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD7152 registers definition
+ */
+
+#define AD7152_STATUS              0
+#define AD7152_STATUS_RDY1         (1 << 0)
+#define AD7152_STATUS_RDY2         (1 << 1)
+#define AD7152_CH1_DATA_HIGH       1
+#define AD7152_CH1_DATA_LOW        2
+#define AD7152_CH2_DATA_HIGH       3
+#define AD7152_CH2_DATA_LOW        4
+#define AD7152_CH1_OFFS_HIGH       5
+#define AD7152_CH1_OFFS_LOW        6
+#define AD7152_CH2_OFFS_HIGH       7
+#define AD7152_CH2_OFFS_LOW        8
+#define AD7152_CH1_GAIN_HIGH       9
+#define AD7152_CH1_GAIN_LOW        10
+#define AD7152_CH1_SETUP           11
+#define AD7152_CH2_GAIN_HIGH       12
+#define AD7152_CH2_GAIN_LOW        13
+#define AD7152_CH2_SETUP           14
+#define AD7152_CFG                 15
+#define AD7152_RESEVERD            16
+#define AD7152_CAPDAC_POS          17
+#define AD7152_CAPDAC_NEG          18
+#define AD7152_CFG2                26
+
+#define AD7152_MAX_CONV_MODE       6
+
+/*
+ * struct ad7152_chip_info - chip specifc information
+ */
+
+struct ad7152_chip_info {
+	const char *name;
+	struct i2c_client *client;
+	struct iio_dev *indio_dev;
+	u16 ch1_offset;     /* Channel 1 offset calibration coefficient */
+	u16 ch1_gain;       /* Channel 1 gain coefficient */
+	u8  ch1_setup;
+	u16 ch2_offset;     /* Channel 2 offset calibration coefficient */
+	u16 ch2_gain;       /* Channel 1 gain coefficient */
+	u8  ch2_setup;
+	u8  filter_rate_setup; /* Capacitive channel digital filter setup; conversion time/update rate setup per channel */
+	char *conversion_mode;
+};
+
+struct ad7152_conversion_mode {
+	char *name;
+	u8 reg_cfg;
+};
+
+struct ad7152_conversion_mode ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
+	{ "idle", 0 },
+	{ "continuous-conversion", 1 },
+	{ "single-conversion", 2 },
+	{ "power-down", 3 },
+	{ "offset-calibration", 5 },
+	{ "gain-calibration", 6 },
+};
+
+/*
+ * ad7152 register access by I2C
+ */
+
+static int ad7152_i2c_read(struct ad7152_chip_info *chip, u8 reg, u8 *data, int len)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = i2c_master_send(client, &reg, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C write error\n");
+		return ret;
+	}
+
+	ret = i2c_master_recv(client, data, len);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+	}
+
+	return ret;
+}
+
+static int ad7152_i2c_write(struct ad7152_chip_info *chip, u8 reg, u8 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	u8 tx[2] = {
+		reg,
+		data,
+	};
+
+	ret = i2c_master_send(client, tx, 2);
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+/*
+ * sysfs nodes
+ */
+
+#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)				\
+	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_OFFSET(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch1_offset, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_OFFSET(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch2_offset, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_GAIN(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch1_gain, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_GAIN(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch2_gain, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH1_VALUE(_show)		\
+	IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CH2_VALUE(_show)		\
+	IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_FILTER_RATE_SETUP(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(filter_rate_setup, _mode, _show, _store, 0)
+
+static ssize_t ad7152_show_conversion_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int i;
+	int len = 0;
+
+	for (i = 0; i < AD7152_MAX_CONV_MODE; i++)
+		len += sprintf(buf + len, "%s ", ad7152_conv_mode_table[i].name);
+
+	len += sprintf(buf + len, "\n");
+
+	return len;
+}
+
+static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7152_show_conversion_modes);
+
+static ssize_t ad7152_show_ch1_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	u8 data[2];
+
+	ad7152_i2c_read(chip, AD7152_CH1_DATA_HIGH, data, 2);
+	return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]);
+}
+
+static IIO_DEV_ATTR_CH1_VALUE(ad7152_show_ch1_value);
+
+static ssize_t ad7152_show_ch2_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	u8 data[2];
+
+	ad7152_i2c_read(chip, AD7152_CH2_DATA_HIGH, data, 2);
+	return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]);
+}
+
+static IIO_DEV_ATTR_CH2_VALUE(ad7152_show_ch2_value);
+
+static ssize_t ad7152_show_conversion_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%s\n", chip->conversion_mode);
+}
+
+static ssize_t ad7152_store_conversion_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	u8 cfg;
+	int i;
+
+	ad7152_i2c_read(chip, AD7152_CFG, &cfg, 1);
+
+	for (i = 0; i < AD7152_MAX_CONV_MODE; i++)
+		if (strncmp(buf, ad7152_conv_mode_table[i].name,
+				strlen(ad7152_conv_mode_table[i].name) - 1) == 0) {
+			chip->conversion_mode = ad7152_conv_mode_table[i].name;
+			cfg |= 0x18 | ad7152_conv_mode_table[i].reg_cfg;
+			ad7152_i2c_write(chip, AD7152_CFG, cfg);
+			return len;
+		}
+
+	dev_err(dev, "not supported conversion mode\n");
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
+		ad7152_show_conversion_mode,
+		ad7152_store_conversion_mode);
+
+static ssize_t ad7152_show_ch1_offset(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch1_offset);
+}
+
+static ssize_t ad7152_store_ch1_offset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad7152_i2c_write(chip, AD7152_CH1_OFFS_HIGH, data >> 8);
+		ad7152_i2c_write(chip, AD7152_CH1_OFFS_LOW, data);
+		chip->ch1_offset = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_OFFSET(S_IRUGO | S_IWUSR,
+		ad7152_show_ch1_offset,
+		ad7152_store_ch1_offset);
+
+static ssize_t ad7152_show_ch2_offset(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch2_offset);
+}
+
+static ssize_t ad7152_store_ch2_offset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad7152_i2c_write(chip, AD7152_CH2_OFFS_HIGH, data >> 8);
+		ad7152_i2c_write(chip, AD7152_CH2_OFFS_LOW, data);
+		chip->ch2_offset = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_OFFSET(S_IRUGO | S_IWUSR,
+		ad7152_show_ch2_offset,
+		ad7152_store_ch2_offset);
+
+static ssize_t ad7152_show_ch1_gain(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch1_gain);
+}
+
+static ssize_t ad7152_store_ch1_gain(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad7152_i2c_write(chip, AD7152_CH1_GAIN_HIGH, data >> 8);
+		ad7152_i2c_write(chip, AD7152_CH1_GAIN_LOW, data);
+		chip->ch1_gain = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_GAIN(S_IRUGO | S_IWUSR,
+		ad7152_show_ch1_gain,
+		ad7152_store_ch1_gain);
+
+static ssize_t ad7152_show_ch2_gain(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->ch2_gain);
+}
+
+static ssize_t ad7152_store_ch2_gain(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad7152_i2c_write(chip, AD7152_CH2_GAIN_HIGH, data >> 8);
+		ad7152_i2c_write(chip, AD7152_CH2_GAIN_LOW, data);
+		chip->ch2_gain = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_GAIN(S_IRUGO | S_IWUSR,
+		ad7152_show_ch2_gain,
+		ad7152_store_ch2_gain);
+
+static ssize_t ad7152_show_ch1_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->ch1_setup);
+}
+
+static ssize_t ad7152_store_ch1_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7152_i2c_write(chip, AD7152_CH1_SETUP, data);
+		chip->ch1_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR,
+		ad7152_show_ch1_setup,
+		ad7152_store_ch1_setup);
+
+static ssize_t ad7152_show_ch2_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->ch2_setup);
+}
+
+static ssize_t ad7152_store_ch2_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7152_i2c_write(chip, AD7152_CH2_SETUP, data);
+		chip->ch2_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR,
+		ad7152_show_ch2_setup,
+		ad7152_store_ch2_setup);
+
+static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->filter_rate_setup);
+}
+
+static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad7152_i2c_write(chip, AD7152_CFG2, data);
+		chip->filter_rate_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR,
+		ad7152_show_filter_rate_setup,
+		ad7152_store_filter_rate_setup);
+
+static ssize_t ad7152_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7152_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad7152_show_name, NULL, 0);
+
+static struct attribute *ad7152_attributes[] = {
+	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
+	&iio_dev_attr_conversion_mode.dev_attr.attr,
+	&iio_dev_attr_ch1_gain.dev_attr.attr,
+	&iio_dev_attr_ch2_gain.dev_attr.attr,
+	&iio_dev_attr_ch1_offset.dev_attr.attr,
+	&iio_dev_attr_ch2_offset.dev_attr.attr,
+	&iio_dev_attr_ch1_value.dev_attr.attr,
+	&iio_dev_attr_ch2_value.dev_attr.attr,
+	&iio_dev_attr_ch1_setup.dev_attr.attr,
+	&iio_dev_attr_ch2_setup.dev_attr.attr,
+	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7152_attribute_group = {
+	.attrs = ad7152_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit ad7152_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int ret = 0;
+	struct ad7152_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, chip);
+
+	chip->client = client;
+	chip->name = id->name;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	/* Echipabilish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->attrs = &ad7152_attribute_group;
+	chip->indio_dev->dev_data = (void *)(chip);
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	dev_err(&client->dev, "%s capacitive sensor registered\n", id->name);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad7152_remove(struct i2c_client *client)
+{
+	struct ad7152_chip_info *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad7152_id[] = {
+	{ "ad7152", 0 },
+	{ "ad7153", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, ad7152_id);
+
+static struct i2c_driver ad7152_driver = {
+	.driver = {
+		.name = "ad7152",
+	},
+	.probe = ad7152_probe,
+	.remove = __devexit_p(ad7152_remove),
+	.id_table = ad7152_id,
+};
+
+static __init int ad7152_init(void)
+{
+	return i2c_add_driver(&ad7152_driver);
+}
+
+static __exit void ad7152_exit(void)
+{
+	i2c_del_driver(&ad7152_driver);
+}
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ad7152/3 capacitive sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad7152_init);
+module_exit(ad7152_exit);
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
new file mode 100644
index 0000000..34041a7
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -0,0 +1,1039 @@
+/*
+ * AD7291 digital temperature sensor driver supporting AD7291
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD7291 registers definition
+ */
+#define AD7291_COMMAND			0
+#define AD7291_VOLTAGE			1
+#define AD7291_T_SENSE			2
+#define AD7291_T_AVERAGE		3
+#define AD7291_VOLTAGE_LIMIT_BASE	4
+#define AD7291_VOLTAGE_LIMIT_COUNT	8
+#define AD7291_T_SENSE_HIGH		0x1c
+#define AD7291_T_SENSE_LOW		0x1d
+#define AD7291_T_SENSE_HYST		0x1e
+#define AD7291_VOLTAGE_ALERT_STATUS	0x1f
+#define AD7291_T_ALERT_STATUS		0x20
+
+/*
+ * AD7291 command
+ */
+#define AD7291_AUTOCYCLE		0x1
+#define AD7291_RESET			0x2
+#define AD7291_ALART_CLEAR		0x4
+#define AD7291_ALART_POLARITY		0x8
+#define AD7291_EXT_REF			0x10
+#define AD7291_NOISE_DELAY		0x20
+#define AD7291_T_SENSE_MASK		0x40
+#define AD7291_VOLTAGE_MASK		0xff00
+#define AD7291_VOLTAGE_OFFSET		0x8
+
+/*
+ * AD7291 value masks
+ */
+#define AD7291_CHANNEL_MASK		0xf000
+#define AD7291_VALUE_MASK		0xfff
+#define AD7291_T_VALUE_SIGN		0x400
+#define AD7291_T_VALUE_FLOAT_OFFSET	2
+#define AD7291_T_VALUE_FLOAT_MASK	0x2
+
+/*
+ * struct ad7291_chip_info - chip specifc information
+ */
+
+struct ad7291_chip_info {
+	const char *name;
+	struct i2c_client *client;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	s64 last_timestamp;
+	u16 command;
+	u8  channels;	/* Active voltage channels */
+};
+
+/*
+ * struct ad7291_chip_info - chip specifc information
+ */
+
+struct ad7291_limit_regs {
+	u16	data_high;
+	u16	data_low;
+	u16	hysteresis;
+};
+
+/*
+ * ad7291 register access by I2C
+ */
+static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+		return ret;
+	}
+
+	*data = swab16((u16)ret);
+
+	return 0;
+}
+
+static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_smbus_write_word_data(client, reg, swab16(data));
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+/* Returns negative errno, or else the number of words read. */
+static int ad7291_i2c_read_data(struct ad7291_chip_info *chip, u8 reg, u16 *data)
+{
+	struct i2c_client *client = chip->client;
+	u8 commands[4];
+	int ret = 0;
+	int i, count;
+
+	if (reg == AD7291_T_SENSE || reg == AD7291_T_AVERAGE)
+		count = 2;
+	else if (reg == AD7291_VOLTAGE) {
+		if (!chip->channels) {
+			dev_err(&client->dev, "No voltage channel is selected.\n");
+			return -EINVAL;
+		}
+		count = 2 + chip->channels * 2;
+	} else {
+		dev_err(&client->dev, "I2C wrong data register\n");
+		return -EINVAL;
+	}
+
+	commands[0] = 0;
+	commands[1] = (chip->command >> 8) & 0xff;
+	commands[2] = chip->command & 0xff;
+	commands[3] = reg;
+
+	ret = i2c_master_send(client, commands, 4);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C master send error\n");
+		return ret;
+	}
+
+	ret = i2c_master_recv(client, (u8 *)data, count);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C master receive error\n");
+		return ret;
+	}
+	ret >>= 2;
+
+	for (i = 0; i < ret; i++)
+		data[i] = swab16(data[i]);
+
+	return ret;
+}
+
+static ssize_t ad7291_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+
+	if (chip->command & AD7291_AUTOCYCLE)
+		return sprintf(buf, "autocycle\n");
+	else
+		return sprintf(buf, "command\n");
+}
+
+static ssize_t ad7291_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	int ret;
+
+	command = chip->command & (~AD7291_AUTOCYCLE);
+	if (strcmp(buf, "autocycle"))
+		command |= AD7291_AUTOCYCLE;
+
+	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
+	if (ret)
+		return -EIO;
+
+	chip->command = command;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		ad7291_show_mode,
+		ad7291_store_mode,
+		0);
+
+static ssize_t ad7291_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "command\nautocycle\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7291_show_available_modes, NULL, 0);
+
+static ssize_t ad7291_store_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	int ret;
+
+	command = chip->command | AD7291_RESET;
+
+	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
+	if (ret)
+		return -EIO;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(reset, S_IWUSR,
+		NULL,
+		ad7291_store_reset,
+		0);
+
+static ssize_t ad7291_show_ext_ref(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->command & AD7291_EXT_REF));
+}
+
+static ssize_t ad7291_store_ext_ref(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	int ret;
+
+	command = chip->command & (~AD7291_EXT_REF);
+	if (strcmp(buf, "1"))
+		command |= AD7291_EXT_REF;
+
+	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
+	if (ret)
+		return -EIO;
+
+	chip->command = command;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR,
+		ad7291_show_ext_ref,
+		ad7291_store_ext_ref,
+		0);
+
+static ssize_t ad7291_show_noise_delay(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->command & AD7291_NOISE_DELAY));
+}
+
+static ssize_t ad7291_store_noise_delay(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	int ret;
+
+	command = chip->command & (~AD7291_NOISE_DELAY);
+	if (strcmp(buf, "1"))
+		command |= AD7291_NOISE_DELAY;
+
+	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
+	if (ret)
+		return -EIO;
+
+	chip->command = command;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(noise_delay, S_IRUGO | S_IWUSR,
+		ad7291_show_noise_delay,
+		ad7291_store_noise_delay,
+		0);
+
+static ssize_t ad7291_show_t_sense(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	ret = ad7291_i2c_read_data(chip, AD7291_T_SENSE, &data);
+	if (ret)
+		return -EIO;
+
+	if (data & AD7291_T_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (AD7291_T_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.2d\n", sign,
+		(data >> AD7291_T_VALUE_FLOAT_OFFSET),
+		(data & AD7291_T_VALUE_FLOAT_MASK) * 25);
+}
+
+static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7291_show_t_sense, NULL, 0);
+
+static ssize_t ad7291_show_t_average(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	ret = ad7291_i2c_read_data(chip, AD7291_T_AVERAGE, &data);
+	if (ret)
+		return -EIO;
+
+	if (data & AD7291_T_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (AD7291_T_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.2d\n", sign,
+		(data >> AD7291_T_VALUE_FLOAT_OFFSET),
+		(data & AD7291_T_VALUE_FLOAT_MASK) * 25);
+}
+
+static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7291_show_t_average, NULL, 0);
+
+static ssize_t ad7291_show_voltage(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 data[AD7291_VOLTAGE_LIMIT_COUNT];
+	int i, size, ret;
+
+	ret = ad7291_i2c_read_data(chip, AD7291_VOLTAGE, data);
+	if (ret)
+		return -EIO;
+
+	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) {
+		if (chip->command & (AD7291_T_SENSE_MASK << i)) {
+			ret = sprintf(buf, "channel[%d]=%d\n", i,
+					data[i] & AD7291_VALUE_MASK);
+			if (ret < 0)
+				break;
+			buf += ret;
+			size += ret;
+		}
+	}
+
+	return size;
+}
+
+static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7291_show_voltage, NULL, 0);
+
+static ssize_t ad7291_show_channel_mask(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%x\n", (chip->command & AD7291_VOLTAGE_MASK) >>
+			AD7291_VOLTAGE_OFFSET);
+}
+
+static ssize_t ad7291_store_channel_mask(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	unsigned long data;
+	int i, ret;
+
+	ret = strict_strtoul(buf, 16, &data);
+	if (ret || data > 0xff)
+		return -EINVAL;
+
+	command = chip->command & (~AD7291_VOLTAGE_MASK);
+	command |= data << AD7291_VOLTAGE_OFFSET;
+
+	ret = ad7291_i2c_write(chip, AD7291_COMMAND, command);
+	if (ret)
+		return -EIO;
+
+	chip->command = command;
+
+	for (i = 0, chip->channels = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) {
+		if (chip->command & (AD7291_T_SENSE_MASK << i))
+			chip->channels++;
+	}
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR,
+		ad7291_show_channel_mask,
+		ad7291_store_channel_mask,
+		0);
+
+static ssize_t ad7291_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad7291_show_name, NULL, 0);
+
+static struct attribute *ad7291_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_dev_attr_ext_ref.dev_attr.attr,
+	&iio_dev_attr_noise_delay.dev_attr.attr,
+	&iio_dev_attr_t_sense.dev_attr.attr,
+	&iio_dev_attr_t_average.dev_attr.attr,
+	&iio_dev_attr_voltage.dev_attr.attr,
+	&iio_dev_attr_channel_mask.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7291_attribute_group = {
+	.attrs = ad7291_attributes,
+};
+
+/*
+ * temperature bound events
+ */
+
+#define IIO_EVENT_CODE_AD7291_T_SENSE_HIGH  IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_AD7291_T_SENSE_LOW   IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_AD7291_T_AVG_HIGH    IIO_BUFFER_EVENT_CODE(2)
+#define IIO_EVENT_CODE_AD7291_T_AVG_LOW     IIO_BUFFER_EVENT_CODE(3)
+#define IIO_EVENT_CODE_AD7291_VOLTAGE_BASE  IIO_BUFFER_EVENT_CODE(4)
+
+static void ad7291_interrupt_bh(struct work_struct *work_s)
+{
+	struct ad7291_chip_info *chip =
+		container_of(work_s, struct ad7291_chip_info, thresh_work);
+	u16 t_status, v_status;
+	u16 command;
+	int i;
+
+	if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
+		return;
+
+	if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
+		return;
+
+	if (!(t_status || v_status))
+		return;
+
+	command = chip->command | AD7291_ALART_CLEAR;
+	ad7291_i2c_write(chip, AD7291_COMMAND, command);
+
+	command = chip->command & ~AD7291_ALART_CLEAR;
+	ad7291_i2c_write(chip, AD7291_COMMAND, command);
+
+	enable_irq(chip->client->irq);
+
+	for (i = 0; i < 4; i++) {
+		if (t_status & (1 << i))
+			iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_AD7291_T_SENSE_HIGH + i,
+				chip->last_timestamp);
+	}
+
+	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i++) {
+		if (v_status & (1 << i))
+			iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_AD7291_VOLTAGE_BASE + i,
+				chip->last_timestamp);
+	}
+}
+
+static int ad7291_interrupt(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(ad7291, &ad7291_interrupt);
+
+static inline ssize_t ad7291_show_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	ret = ad7291_i2c_read(chip, bound_reg, &data);
+	if (ret)
+		return -EIO;
+
+	data &= AD7291_VALUE_MASK;
+	if (data & AD7291_T_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (AD7291_T_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.2d\n", sign,
+			data >> AD7291_T_VALUE_FLOAT_OFFSET,
+			(data & AD7291_T_VALUE_FLOAT_MASK) * 25);
+}
+
+static inline ssize_t ad7291_set_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	long tmp1, tmp2;
+	u16 data;
+	char *pos;
+	int ret;
+
+	pos = strchr(buf, '.');
+
+	ret = strict_strtol(buf, 10, &tmp1);
+
+	if (ret || tmp1 > 127 || tmp1 < -128)
+		return -EINVAL;
+
+	if (pos) {
+		len = strlen(pos);
+		if (len > AD7291_T_VALUE_FLOAT_OFFSET)
+			len = AD7291_T_VALUE_FLOAT_OFFSET;
+		pos[len] = 0;
+		ret = strict_strtol(pos, 10, &tmp2);
+
+		if (!ret)
+			tmp2 = (tmp2 / 25) * 25;
+	}
+
+	if (tmp1 < 0)
+		data = (u16)(-tmp1);
+	else
+		data = (u16)tmp1;
+	data = (data << AD7291_T_VALUE_FLOAT_OFFSET) |
+		(tmp2 & AD7291_T_VALUE_FLOAT_MASK);
+	if (tmp1 < 0)
+		/* convert positive value to supplyment */
+		data = (AD7291_T_VALUE_SIGN << 1) - data;
+
+	ret = ad7291_i2c_write(chip, bound_reg, data);
+	if (ret)
+		return -EIO;
+
+	return ret;
+}
+
+static ssize_t ad7291_show_t_sense_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return ad7291_show_t_bound(dev, attr,
+			AD7291_T_SENSE_HIGH, buf);
+}
+
+static inline ssize_t ad7291_set_t_sense_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return ad7291_set_t_bound(dev, attr,
+			AD7291_T_SENSE_HIGH, buf, len);
+}
+
+static ssize_t ad7291_show_t_sense_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return ad7291_show_t_bound(dev, attr,
+			AD7291_T_SENSE_LOW, buf);
+}
+
+static inline ssize_t ad7291_set_t_sense_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return ad7291_set_t_bound(dev, attr,
+			AD7291_T_SENSE_LOW, buf, len);
+}
+
+static ssize_t ad7291_show_t_sense_hyst(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return ad7291_show_t_bound(dev, attr,
+			AD7291_T_SENSE_HYST, buf);
+}
+
+static inline ssize_t ad7291_set_t_sense_hyst(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return ad7291_set_t_bound(dev, attr,
+			AD7291_T_SENSE_HYST, buf, len);
+}
+
+static inline ssize_t ad7291_show_v_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	int ret;
+
+	if (bound_reg < AD7291_VOLTAGE_LIMIT_BASE ||
+		bound_reg >= AD7291_VOLTAGE_LIMIT_BASE +
+		AD7291_VOLTAGE_LIMIT_COUNT)
+		return -EINVAL;
+
+	ret = ad7291_i2c_read(chip, bound_reg, &data);
+	if (ret)
+		return -EIO;
+
+	data &= AD7291_VALUE_MASK;
+
+	return sprintf(buf, "%d\n", data);
+}
+
+static inline ssize_t ad7291_set_v_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7291_chip_info *chip = dev_info->dev_data;
+	unsigned long value;
+	u16 data;
+	int ret;
+
+	if (bound_reg < AD7291_VOLTAGE_LIMIT_BASE ||
+		bound_reg >= AD7291_VOLTAGE_LIMIT_BASE +
+		AD7291_VOLTAGE_LIMIT_COUNT)
+		return -EINVAL;
+
+	ret = strict_strtoul(buf, 10, &value);
+
+	if (ret || value >= 4096)
+		return -EINVAL;
+
+	data = (u16)value;
+	ret = ad7291_i2c_write(chip, bound_reg, data);
+	if (ret)
+		return -EIO;
+
+	return ret;
+}
+
+static int ad7291_get_voltage_limit_regs(const char *channel)
+{
+	int index;
+
+	if (strlen(channel) < 3 && channel[0] != 'v')
+		return -EINVAL;
+
+	index = channel[1] - '0';
+	if (index >= AD7291_VOLTAGE_LIMIT_COUNT)
+		return -EINVAL;
+
+	return index;
+}
+
+static ssize_t ad7291_show_voltage_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int regs;
+
+	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
+
+	if (regs < 0)
+		return regs;
+
+	return ad7291_show_t_bound(dev, attr, regs, buf);
+}
+
+static inline ssize_t ad7291_set_voltage_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int regs;
+
+	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
+
+	if (regs < 0)
+		return regs;
+
+	return ad7291_set_t_bound(dev, attr, regs, buf, len);
+}
+
+static ssize_t ad7291_show_voltage_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int regs;
+
+	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
+
+	if (regs < 0)
+		return regs;
+
+	return ad7291_show_t_bound(dev, attr, regs+1, buf);
+}
+
+static inline ssize_t ad7291_set_voltage_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int regs;
+
+	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
+
+	if (regs < 0)
+		return regs;
+
+	return ad7291_set_t_bound(dev, attr, regs+1, buf, len);
+}
+
+static ssize_t ad7291_show_voltage_hyst(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int regs;
+
+	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
+
+	if (regs < 0)
+		return regs;
+
+	return ad7291_show_t_bound(dev, attr, regs+2, buf);
+}
+
+static inline ssize_t ad7291_set_voltage_hyst(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int regs;
+
+	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
+
+	if (regs < 0)
+		return regs;
+
+	return ad7291_set_t_bound(dev, attr, regs+2, buf, len);
+}
+
+IIO_EVENT_ATTR_SH(t_sense_high, iio_event_ad7291,
+		ad7291_show_t_sense_high, ad7291_set_t_sense_high, 0);
+IIO_EVENT_ATTR_SH(t_sense_low, iio_event_ad7291,
+		ad7291_show_t_sense_low, ad7291_set_t_sense_low, 0);
+IIO_EVENT_ATTR_SH(t_sense_hyst, iio_event_ad7291,
+		ad7291_show_t_sense_hyst, ad7291_set_t_sense_hyst, 0);
+
+IIO_EVENT_ATTR_SH(v0_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v0_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v0_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v1_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v1_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v1_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v2_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v2_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v2_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v3_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v3_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v3_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v4_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v4_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v4_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v5_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v5_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v5_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v6_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v6_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v6_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+IIO_EVENT_ATTR_SH(v7_high, iio_event_ad7291,
+		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
+IIO_EVENT_ATTR_SH(v7_low, iio_event_ad7291,
+		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
+IIO_EVENT_ATTR_SH(v7_hyst, iio_event_ad7291,
+		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+
+static struct attribute *ad7291_event_attributes[] = {
+	&iio_event_attr_t_sense_high.dev_attr.attr,
+	&iio_event_attr_t_sense_low.dev_attr.attr,
+	&iio_event_attr_t_sense_hyst.dev_attr.attr,
+	&iio_event_attr_v0_high.dev_attr.attr,
+	&iio_event_attr_v0_low.dev_attr.attr,
+	&iio_event_attr_v0_hyst.dev_attr.attr,
+	&iio_event_attr_v1_high.dev_attr.attr,
+	&iio_event_attr_v1_low.dev_attr.attr,
+	&iio_event_attr_v1_hyst.dev_attr.attr,
+	&iio_event_attr_v2_high.dev_attr.attr,
+	&iio_event_attr_v2_low.dev_attr.attr,
+	&iio_event_attr_v2_hyst.dev_attr.attr,
+	&iio_event_attr_v3_high.dev_attr.attr,
+	&iio_event_attr_v3_low.dev_attr.attr,
+	&iio_event_attr_v3_hyst.dev_attr.attr,
+	&iio_event_attr_v4_high.dev_attr.attr,
+	&iio_event_attr_v4_low.dev_attr.attr,
+	&iio_event_attr_v4_hyst.dev_attr.attr,
+	&iio_event_attr_v5_high.dev_attr.attr,
+	&iio_event_attr_v5_low.dev_attr.attr,
+	&iio_event_attr_v5_hyst.dev_attr.attr,
+	&iio_event_attr_v6_high.dev_attr.attr,
+	&iio_event_attr_v6_low.dev_attr.attr,
+	&iio_event_attr_v6_hyst.dev_attr.attr,
+	&iio_event_attr_v7_high.dev_attr.attr,
+	&iio_event_attr_v7_low.dev_attr.attr,
+	&iio_event_attr_v7_hyst.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ad7291_event_attribute_group = {
+	.attrs = ad7291_event_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit ad7291_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct ad7291_chip_info *chip;
+	int ret = 0;
+
+	chip = kzalloc(sizeof(struct ad7291_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, chip);
+
+	chip->client = client;
+	chip->name = id->name;
+	chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->attrs = &ad7291_attribute_group;
+	chip->indio_dev->event_attrs = &ad7291_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = 1;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	if (client->irq > 0) {
+		ret = iio_register_interrupt_line(client->irq,
+				chip->indio_dev,
+				0,
+				IRQF_TRIGGER_LOW,
+				chip->name);
+		if (ret)
+			goto error_unreg_dev;
+
+		/*
+		 * The event handler list element refer to iio_event_ad7291.
+		 * All event attributes bind to the same event handler.
+		 * So, only register event handler once.
+		 */
+		iio_add_event_to_list(&iio_event_ad7291,
+				&chip->indio_dev->interrupts[0]->ev_list);
+
+		INIT_WORK(&chip->thresh_work, ad7291_interrupt_bh);
+
+		/* set irq polarity low level */
+		chip->command |= AD7291_ALART_POLARITY;
+	}
+
+	ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command);
+	if (ret) {
+		ret = -EIO;
+		goto error_unreg_irq;
+	}
+
+	dev_info(&client->dev, "%s temperature sensor registered.\n",
+			 id->name);
+
+	return 0;
+
+error_unreg_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 0);
+error_unreg_dev:
+	iio_device_unregister(chip->indio_dev);
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit ad7291_remove(struct i2c_client *client)
+{
+	struct ad7291_chip_info *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	if (client->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad7291_id[] = {
+	{ "ad7291", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, ad7291_id);
+
+static struct i2c_driver ad7291_driver = {
+	.driver = {
+		.name = "ad7291",
+	},
+	.probe = ad7291_probe,
+	.remove = __devexit_p(ad7291_remove),
+	.id_table = ad7291_id,
+};
+
+static __init int ad7291_init(void)
+{
+	return i2c_add_driver(&ad7291_driver);
+}
+
+static __exit void ad7291_exit(void)
+{
+	i2c_del_driver(&ad7291_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD7291 digital"
+			" temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad7291_init);
+module_exit(ad7291_exit);
diff --git a/drivers/staging/iio/adc/ad7298.c b/drivers/staging/iio/adc/ad7298.c
new file mode 100644
index 0000000..1a080c9
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7298.c
@@ -0,0 +1,501 @@
+/*
+ * AD7298 digital temperature sensor driver supporting AD7298
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD7298 command
+ */
+#define AD7298_PD			0x1
+#define AD7298_T_AVG_MASK		0x2
+#define AD7298_EXT_REF			0x4
+#define AD7298_T_SENSE_MASK		0x20
+#define AD7298_VOLTAGE_MASK		0x3fc0
+#define AD7298_VOLTAGE_OFFSET		0x6
+#define AD7298_VOLTAGE_LIMIT_COUNT	8
+#define AD7298_REPEAT			0x40
+#define AD7298_WRITE			0x80
+
+/*
+ * AD7298 value masks
+ */
+#define AD7298_CHANNEL_MASK		0xf000
+#define AD7298_VALUE_MASK		0xfff
+#define AD7298_T_VALUE_SIGN		0x400
+#define AD7298_T_VALUE_FLOAT_OFFSET	2
+#define AD7298_T_VALUE_FLOAT_MASK	0x2
+
+/*
+ * struct ad7298_chip_info - chip specifc information
+ */
+
+struct ad7298_chip_info {
+	const char *name;
+	struct spi_device *spi_dev;
+	struct iio_dev *indio_dev;
+	u16 command;
+	u16 busy_pin;
+	u8  channels;	/* Active voltage channels */
+};
+
+/*
+ * ad7298 register access by SPI
+ */
+static int ad7298_spi_write(struct ad7298_chip_info *chip, u16 data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	int ret = 0;
+
+	data |= AD7298_WRITE;
+	data = cpu_to_be16(data);
+	ret = spi_write(spi_dev, (u8 *)&data, sizeof(data));
+	if (ret < 0)
+		dev_err(&spi_dev->dev, "SPI write error\n");
+
+	return ret;
+}
+
+static int ad7298_spi_read(struct ad7298_chip_info *chip, u16 mask, u16 *data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	int ret = 0;
+	u8 count = chip->channels;
+	u16 command;
+	int i;
+
+	if (mask & AD7298_T_SENSE_MASK) {
+		command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_VOLTAGE_MASK);
+		command |= AD7298_T_SENSE_MASK;
+		count = 1;
+	} else if (mask & AD7298_T_AVG_MASK) {
+		command = chip->command & ~AD7298_VOLTAGE_MASK;
+		command |= AD7298_T_SENSE_MASK | AD7298_T_AVG_MASK;
+		count = 2;
+	} else if (mask & AD7298_VOLTAGE_MASK) {
+		command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_T_SENSE_MASK);
+		count = chip->channels;
+	}
+
+	ret = ad7298_spi_write(chip, chip->command);
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI write command error\n");
+		return ret;
+	}
+
+	ret = spi_read(spi_dev, (u8 *)&command, sizeof(command));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI read error\n");
+		return ret;
+	}
+
+	i = 10000;
+	while (i && gpio_get_value(chip->busy_pin)) {
+		cpu_relax();
+		i--;
+	}
+	if (!i) {
+		dev_err(&spi_dev->dev, "Always in busy convertion.\n");
+		return -EBUSY;
+	}
+
+	for (i = 0; i < count; i++) {
+		ret = spi_read(spi_dev, (u8 *)&data[i], sizeof(data[i]));
+		if (ret < 0) {
+			dev_err(&spi_dev->dev, "SPI read error\n");
+			return ret;
+		}
+		*data = be16_to_cpu(data[i]);
+	}
+
+	return 0;
+}
+
+static ssize_t ad7298_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+
+	if (chip->command & AD7298_REPEAT)
+		return sprintf(buf, "repeat\n");
+	else
+		return sprintf(buf, "normal\n");
+}
+
+static ssize_t ad7298_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+
+	if (strcmp(buf, "repeat"))
+		chip->command |= AD7298_REPEAT;
+	else
+		chip->command &= (~AD7298_REPEAT);
+
+	return 1;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		ad7298_show_mode,
+		ad7298_store_mode,
+		0);
+
+static ssize_t ad7298_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "normal\nrepeat\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7298_show_available_modes, NULL, 0);
+
+static ssize_t ad7298_store_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	int ret;
+
+	command = chip->command & ~AD7298_PD;
+
+	ret = ad7298_spi_write(chip, command);
+	if (ret)
+		return -EIO;
+
+	command = chip->command | AD7298_PD;
+
+	ret = ad7298_spi_write(chip, command);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(reset, S_IWUSR,
+		NULL,
+		ad7298_store_reset,
+		0);
+
+static ssize_t ad7298_show_ext_ref(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->command & AD7298_EXT_REF));
+}
+
+static ssize_t ad7298_store_ext_ref(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	u16 command;
+	int ret;
+
+	command = chip->command & (~AD7298_EXT_REF);
+	if (strcmp(buf, "1"))
+		command |= AD7298_EXT_REF;
+
+	ret = ad7298_spi_write(chip, command);
+	if (ret)
+		return -EIO;
+
+	chip->command = command;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR,
+		ad7298_show_ext_ref,
+		ad7298_store_ext_ref,
+		0);
+
+static ssize_t ad7298_show_t_sense(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	ret = ad7298_spi_read(chip, AD7298_T_SENSE_MASK, &data);
+	if (ret)
+		return -EIO;
+
+	if (data & AD7298_T_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (AD7298_T_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.2d\n", sign,
+		(data >> AD7298_T_VALUE_FLOAT_OFFSET),
+		(data & AD7298_T_VALUE_FLOAT_MASK) * 25);
+}
+
+static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7298_show_t_sense, NULL, 0);
+
+static ssize_t ad7298_show_t_average(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	u16 data[2];
+	char sign = ' ';
+	int ret;
+
+	ret = ad7298_spi_read(chip, AD7298_T_AVG_MASK, data);
+	if (ret)
+		return -EIO;
+
+	if (data[1] & AD7298_T_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data[1] = (AD7298_T_VALUE_SIGN << 1) - data[1];
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.2d\n", sign,
+		(data[1] >> AD7298_T_VALUE_FLOAT_OFFSET),
+		(data[1] & AD7298_T_VALUE_FLOAT_MASK) * 25);
+}
+
+static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7298_show_t_average, NULL, 0);
+
+static ssize_t ad7298_show_voltage(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	u16 data[AD7298_VOLTAGE_LIMIT_COUNT];
+	int i, size, ret;
+
+	ret = ad7298_spi_read(chip, AD7298_VOLTAGE_MASK, data);
+	if (ret)
+		return -EIO;
+
+	for (i = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) {
+		if (chip->command & (AD7298_T_SENSE_MASK << i)) {
+			ret = sprintf(buf, "channel[%d]=%d\n", i,
+					data[i] & AD7298_VALUE_MASK);
+			if (ret < 0)
+				break;
+			buf += ret;
+			size += ret;
+		}
+	}
+
+	return size;
+}
+
+static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7298_show_voltage, NULL, 0);
+
+static ssize_t ad7298_show_channel_mask(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%x\n", (chip->command & AD7298_VOLTAGE_MASK) >>
+			AD7298_VOLTAGE_OFFSET);
+}
+
+static ssize_t ad7298_store_channel_mask(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int i, ret;
+
+	ret = strict_strtoul(buf, 16, &data);
+	if (ret || data > 0xff)
+		return -EINVAL;
+
+	chip->command &= (~AD7298_VOLTAGE_MASK);
+	chip->command |= data << AD7298_VOLTAGE_OFFSET;
+
+	for (i = 0, chip->channels = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) {
+		if (chip->command & (AD7298_T_SENSE_MASK << i))
+			chip->channels++;
+	}
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR,
+		ad7298_show_channel_mask,
+		ad7298_store_channel_mask,
+		0);
+
+static ssize_t ad7298_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7298_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0);
+
+static struct attribute *ad7298_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_dev_attr_ext_ref.dev_attr.attr,
+	&iio_dev_attr_t_sense.dev_attr.attr,
+	&iio_dev_attr_t_average.dev_attr.attr,
+	&iio_dev_attr_voltage.dev_attr.attr,
+	&iio_dev_attr_channel_mask.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7298_attribute_group = {
+	.attrs = ad7298_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+static int __devinit ad7298_probe(struct spi_device *spi_dev)
+{
+	struct ad7298_chip_info *chip;
+	unsigned short *pins = spi_dev->dev.platform_data;
+	int ret = 0;
+
+	chip = kzalloc(sizeof(struct ad7298_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	dev_set_drvdata(&spi_dev->dev, chip);
+
+	chip->spi_dev = spi_dev;
+	chip->name = spi_dev->modalias;
+	chip->busy_pin = pins[0];
+
+	ret = gpio_request(chip->busy_pin, chip->name);
+	if (ret) {
+		dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
+			chip->busy_pin);
+		goto error_free_chip;
+	}
+	gpio_direction_input(chip->busy_pin);
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_gpio;
+	}
+
+	chip->indio_dev->dev.parent = &spi_dev->dev;
+	chip->indio_dev->attrs = &ad7298_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
+			 chip->name);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_gpio:
+	gpio_free(chip->busy_pin);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit ad7298_remove(struct spi_device *spi_dev)
+{
+	struct ad7298_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	dev_set_drvdata(&spi_dev->dev, NULL);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	gpio_free(chip->busy_pin);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct spi_device_id ad7298_id[] = {
+	{ "ad7298", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(spi, ad7298_id);
+
+static struct spi_driver ad7298_driver = {
+	.driver = {
+		.name = "ad7298",
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad7298_probe,
+	.remove = __devexit_p(ad7298_remove),
+	.id_table = ad7298_id,
+};
+
+static __init int ad7298_init(void)
+{
+	return spi_register_driver(&ad7298_driver);
+}
+
+static __exit void ad7298_exit(void)
+{
+	spi_unregister_driver(&ad7298_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD7298 digital"
+			" temperature sensor and ADC driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad7298_init);
+module_exit(ad7298_exit);
diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c
new file mode 100644
index 0000000..8c17b1f
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7314.c
@@ -0,0 +1,308 @@
+/*
+ * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD7314 power mode
+ */
+#define AD7314_PD		0x2000
+
+/*
+ * AD7314 temperature masks
+ */
+#define AD7314_TEMP_SIGN		0x200
+#define AD7314_TEMP_MASK		0x7FE0
+#define AD7314_TEMP_OFFSET		5
+#define AD7314_TEMP_FLOAT_OFFSET	2
+#define AD7314_TEMP_FLOAT_MASK		0x3
+
+/*
+ * ADT7301 and ADT7302 temperature masks
+ */
+#define ADT7301_TEMP_SIGN		0x2000
+#define ADT7301_TEMP_MASK		0x2FFF
+#define ADT7301_TEMP_FLOAT_OFFSET	5
+#define ADT7301_TEMP_FLOAT_MASK		0x1F
+
+/*
+ * struct ad7314_chip_info - chip specifc information
+ */
+
+struct ad7314_chip_info {
+	const char *name;
+	struct spi_device *spi_dev;
+	struct iio_dev *indio_dev;
+	s64 last_timestamp;
+	u8  mode;
+};
+
+/*
+ * ad7314 register access by SPI
+ */
+
+static int ad7314_spi_read(struct ad7314_chip_info *chip, u16 *data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	int ret = 0;
+	u16 value;
+
+	ret = spi_read(spi_dev, (u8 *)&value, sizeof(value));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI read error\n");
+		return ret;
+	}
+
+	*data = be16_to_cpu((u16)value);
+
+	return ret;
+}
+
+static int ad7314_spi_write(struct ad7314_chip_info *chip, u16 data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	int ret = 0;
+	u16 value = cpu_to_be16(data);
+
+	ret = spi_write(spi_dev, (u8 *)&value, sizeof(value));
+	if (ret < 0)
+		dev_err(&spi_dev->dev, "SPI write error\n");
+
+	return ret;
+}
+
+static ssize_t ad7314_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7314_chip_info *chip = dev_info->dev_data;
+
+	if (chip->mode)
+		return sprintf(buf, "power-save\n");
+	else
+		return sprintf(buf, "full\n");
+}
+
+static ssize_t ad7314_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7314_chip_info *chip = dev_info->dev_data;
+	u16 mode = 0;
+	int ret;
+
+	if (!strcmp(buf, "full"))
+		mode = AD7314_PD;
+
+	ret = ad7314_spi_write(chip, mode);
+	if (ret)
+		return -EIO;
+
+	chip->mode = mode;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		ad7314_show_mode,
+		ad7314_store_mode,
+		0);
+
+static ssize_t ad7314_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "full\npower-save\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7314_show_available_modes, NULL, 0);
+
+static ssize_t ad7314_show_temperature(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7314_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	if (chip->mode) {
+		ret = ad7314_spi_write(chip, 0);
+		if (ret)
+			return -EIO;
+	}
+
+	ret = ad7314_spi_read(chip, &data);
+	if (ret)
+		return -EIO;
+
+	if (chip->mode)
+		ad7314_spi_write(chip, chip->mode);
+
+	if (strcmp(chip->name, "ad7314")) {
+		data = (data & AD7314_TEMP_MASK) >>
+			AD7314_TEMP_OFFSET;
+		if (data & AD7314_TEMP_SIGN) {
+			data = (AD7314_TEMP_SIGN << 1) - data;
+			sign = '-';
+		}
+
+		return sprintf(buf, "%c%d.%.2d\n", sign,
+				data >> AD7314_TEMP_FLOAT_OFFSET,
+				(data & AD7314_TEMP_FLOAT_MASK) * 25);
+	} else {
+		data &= ADT7301_TEMP_MASK;
+		if (data & ADT7301_TEMP_SIGN) {
+			data = (ADT7301_TEMP_SIGN << 1) - data;
+			sign = '-';
+		}
+
+		return sprintf(buf, "%c%d.%.5d\n", sign,
+				data >> ADT7301_TEMP_FLOAT_OFFSET,
+				(data & ADT7301_TEMP_FLOAT_MASK) * 3125);
+	}
+}
+
+static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0);
+
+static ssize_t ad7314_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7314_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL, 0);
+
+static struct attribute *ad7314_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_temperature.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7314_attribute_group = {
+	.attrs = ad7314_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit ad7314_probe(struct spi_device *spi_dev)
+{
+	struct ad7314_chip_info *chip;
+	int ret = 0;
+
+	chip = kzalloc(sizeof(struct ad7314_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	dev_set_drvdata(&spi_dev->dev, chip);
+
+	chip->spi_dev = spi_dev;
+	chip->name = spi_dev->modalias;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	chip->indio_dev->dev.parent = &spi_dev->dev;
+	chip->indio_dev->attrs = &ad7314_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
+			 chip->name);
+
+	return 0;
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit ad7314_remove(struct spi_device *spi_dev)
+{
+	struct ad7314_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	dev_set_drvdata(&spi_dev->dev, NULL);
+	if (spi_dev->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct spi_device_id ad7314_id[] = {
+	{ "adt7301", 0 },
+	{ "adt7302", 0 },
+	{ "ad7314", 0 },
+	{}
+};
+
+static struct spi_driver ad7314_driver = {
+	.driver = {
+		.name = "ad7314",
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad7314_probe,
+	.remove = __devexit_p(ad7314_remove),
+	.id_table = ad7314_id,
+};
+
+static __init int ad7314_init(void)
+{
+	return spi_register_driver(&ad7314_driver);
+}
+
+static __exit void ad7314_exit(void)
+{
+	spi_unregister_driver(&ad7314_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital"
+			" temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad7314_init);
+module_exit(ad7314_exit);
diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c
new file mode 100644
index 0000000..ab7ef84
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7745.c
@@ -0,0 +1,734 @@
+/*
+ * AD774X capacitive sensor driver supporting AD7745/6/7
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD774X registers definition
+ */
+
+#define AD774X_STATUS		0
+#define AD774X_STATUS_RDY	(1 << 2)
+#define AD774X_STATUS_RDYVT	(1 << 1)
+#define AD774X_STATUS_RDYCAP	(1 << 0)
+#define AD774X_CAP_DATA_HIGH	1
+#define AD774X_CAP_DATA_MID	2
+#define AD774X_CAP_DATA_LOW	3
+#define AD774X_VT_DATA_HIGH	4
+#define AD774X_VT_DATA_MID	5
+#define AD774X_VT_DATA_LOW	6
+#define AD774X_CAP_SETUP	7
+#define AD774X_VT_SETUP		8
+#define AD774X_EXEC_SETUP	9
+#define AD774X_CFG		10
+#define AD774X_CAPDACA		11
+#define AD774X_CAPDACB		12
+#define AD774X_CAPDAC_EN	(1 << 7)
+#define AD774X_CAP_OFFH		13
+#define AD774X_CAP_OFFL		14
+#define AD774X_CAP_GAINH	15
+#define AD774X_CAP_GAINL	16
+#define AD774X_VOLT_GAINH	17
+#define AD774X_VOLT_GAINL	18
+
+#define AD774X_MAX_CONV_MODE	6
+
+/*
+ * struct ad774x_chip_info - chip specifc information
+ */
+
+struct ad774x_chip_info {
+	const char *name;
+	struct i2c_client *client;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	bool inter;
+	s64 last_timestamp;
+	u16 cap_offs;                   /* Capacitive offset */
+	u16 cap_gain;                   /* Capacitive gain calibration */
+	u16 volt_gain;                  /* Voltage gain calibration */
+	u8  cap_setup;
+	u8  vt_setup;
+	u8  exec_setup;
+
+	char *conversion_mode;
+};
+
+struct ad774x_conversion_mode {
+	char *name;
+	u8 reg_cfg;
+};
+
+struct ad774x_conversion_mode ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = {
+	{ "idle", 0 },
+	{ "continuous-conversion", 1 },
+	{ "single-conversion", 2 },
+	{ "power-down", 3 },
+	{ "offset-calibration", 5 },
+	{ "gain-calibration", 6 },
+};
+
+/*
+ * ad774x register access by I2C
+ */
+
+static int ad774x_i2c_read(struct ad774x_chip_info *chip, u8 reg, u8 *data, int len)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = i2c_master_send(client, &reg, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C write error\n");
+		return ret;
+	}
+
+	ret = i2c_master_recv(client, data, len);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int ad774x_i2c_write(struct ad774x_chip_info *chip, u8 reg, u8 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	u8 tx[2] = {
+		reg,
+		data,
+	};
+
+	ret = i2c_master_send(client, tx, 2);
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+/*
+ * sysfs nodes
+ */
+
+#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show)				\
+	IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CAP_SETUP(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(cap_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_VT_SETUP(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(in0_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_EXEC_SETUP(_mode, _show, _store)              \
+	IIO_DEVICE_ATTR(exec_setup, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_VOLT_GAIN(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(in0_gain, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CAP_OFFS(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(cap_offs, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CAP_GAIN(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(cap_gain, _mode, _show, _store, 0)
+#define IIO_DEV_ATTR_CAP_DATA(_show)		\
+	IIO_DEVICE_ATTR(cap0_raw, S_IRUGO, _show, NULL, 0)
+#define IIO_DEV_ATTR_VT_DATA(_show)		\
+	IIO_DEVICE_ATTR(in0_raw, S_IRUGO, _show, NULL, 0)
+
+static ssize_t ad774x_show_conversion_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int i;
+	int len = 0;
+
+	for (i = 0; i < AD774X_MAX_CONV_MODE; i++)
+		len += sprintf(buf + len, "%s ", ad774x_conv_mode_table[i].name);
+
+	len += sprintf(buf + len, "\n");
+
+	return len;
+}
+
+static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad774x_show_conversion_modes);
+
+static ssize_t ad774x_show_conversion_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%s\n", chip->conversion_mode);
+}
+
+static ssize_t ad774x_store_conversion_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	u8 cfg;
+	int i;
+
+	ad774x_i2c_read(chip, AD774X_CFG, &cfg, 1);
+
+	for (i = 0; i < AD774X_MAX_CONV_MODE; i++) {
+		if (strncmp(buf, ad774x_conv_mode_table[i].name,
+				strlen(ad774x_conv_mode_table[i].name) - 1) == 0) {
+			chip->conversion_mode = ad774x_conv_mode_table[i].name;
+			cfg |= 0x18 | ad774x_conv_mode_table[i].reg_cfg;
+			ad774x_i2c_write(chip, AD774X_CFG, cfg);
+			return len;
+		}
+	}
+
+	dev_err(dev, "not supported conversion mode\n");
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR,
+		ad774x_show_conversion_mode,
+		ad774x_store_conversion_mode);
+
+static ssize_t ad774x_show_dac_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	u8 data;
+
+	ad774x_i2c_read(chip, this_attr->address, &data, 1);
+
+	return sprintf(buf, "%02x\n", data & 0x7F);
+}
+
+static ssize_t ad774x_store_dac_value(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if (!ret) {
+		ad774x_i2c_write(chip, this_attr->address,
+			(data ? AD774X_CAPDAC_EN : 0) | (data & 0x7F));
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEVICE_ATTR(capdac0_raw, S_IRUGO | S_IWUSR,
+			ad774x_show_dac_value,
+			ad774x_store_dac_value,
+			AD774X_CAPDACA);
+
+static IIO_DEVICE_ATTR(capdac1_raw, S_IRUGO | S_IWUSR,
+			ad774x_show_dac_value,
+			ad774x_store_dac_value,
+			AD774X_CAPDACB);
+
+static ssize_t ad774x_show_cap_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->cap_setup);
+}
+
+static ssize_t ad774x_store_cap_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad774x_i2c_write(chip, AD774X_CAP_SETUP, data);
+		chip->cap_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CAP_SETUP(S_IRUGO | S_IWUSR,
+		ad774x_show_cap_setup,
+		ad774x_store_cap_setup);
+
+static ssize_t ad774x_show_vt_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->vt_setup);
+}
+
+static ssize_t ad774x_store_vt_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad774x_i2c_write(chip, AD774X_VT_SETUP, data);
+		chip->vt_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_VT_SETUP(S_IRUGO | S_IWUSR,
+		ad774x_show_vt_setup,
+		ad774x_store_vt_setup);
+
+static ssize_t ad774x_show_exec_setup(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%02x\n", chip->exec_setup);
+}
+
+static ssize_t ad774x_store_exec_setup(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x100)) {
+		ad774x_i2c_write(chip, AD774X_EXEC_SETUP, data);
+		chip->exec_setup = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_EXEC_SETUP(S_IRUGO | S_IWUSR,
+		ad774x_show_exec_setup,
+		ad774x_store_exec_setup);
+
+static ssize_t ad774x_show_volt_gain(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->volt_gain);
+}
+
+static ssize_t ad774x_store_volt_gain(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad774x_i2c_write(chip, AD774X_VOLT_GAINH, data >> 8);
+		ad774x_i2c_write(chip, AD774X_VOLT_GAINL, data);
+		chip->volt_gain = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_VOLT_GAIN(S_IRUGO | S_IWUSR,
+		ad774x_show_volt_gain,
+		ad774x_store_volt_gain);
+
+static ssize_t ad774x_show_cap_data(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	char tmp[3];
+
+	ad774x_i2c_read(chip, AD774X_CAP_DATA_HIGH, tmp, 3);
+	data = ((int)tmp[0] << 16) | ((int)tmp[1] << 8) | (int)tmp[2];
+
+	return sprintf(buf, "%ld\n", data);
+}
+
+static IIO_DEV_ATTR_CAP_DATA(ad774x_show_cap_data);
+
+static ssize_t ad774x_show_vt_data(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	char tmp[3];
+
+	ad774x_i2c_read(chip, AD774X_VT_DATA_HIGH, tmp, 3);
+	data = ((int)tmp[0] << 16) | ((int)tmp[1] << 8) | (int)tmp[2];
+
+	return sprintf(buf, "%ld\n", data);
+}
+
+static IIO_DEV_ATTR_VT_DATA(ad774x_show_vt_data);
+
+static ssize_t ad774x_show_cap_offs(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->cap_offs);
+}
+
+static ssize_t ad774x_store_cap_offs(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad774x_i2c_write(chip, AD774X_CAP_OFFH, data >> 8);
+		ad774x_i2c_write(chip, AD774X_CAP_OFFL, data);
+		chip->cap_offs = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CAP_OFFS(S_IRUGO | S_IWUSR,
+		ad774x_show_cap_offs,
+		ad774x_store_cap_offs);
+
+static ssize_t ad774x_show_cap_gain(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->cap_gain);
+}
+
+static ssize_t ad774x_store_cap_gain(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+
+	if ((!ret) && (data < 0x10000)) {
+		ad774x_i2c_write(chip, AD774X_CAP_GAINH, data >> 8);
+		ad774x_i2c_write(chip, AD774X_CAP_GAINL, data);
+		chip->cap_gain = data;
+		return len;
+	}
+
+	return -EINVAL;
+}
+
+static IIO_DEV_ATTR_CAP_GAIN(S_IRUGO | S_IWUSR,
+		ad774x_show_cap_gain,
+		ad774x_store_cap_gain);
+
+static ssize_t ad774x_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad774x_show_name, NULL, 0);
+
+static struct attribute *ad774x_attributes[] = {
+	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
+	&iio_dev_attr_conversion_mode.dev_attr.attr,
+	&iio_dev_attr_cap_setup.dev_attr.attr,
+	&iio_dev_attr_in0_setup.dev_attr.attr,
+	&iio_dev_attr_exec_setup.dev_attr.attr,
+	&iio_dev_attr_cap_offs.dev_attr.attr,
+	&iio_dev_attr_cap_gain.dev_attr.attr,
+	&iio_dev_attr_in0_gain.dev_attr.attr,
+	&iio_dev_attr_in0_raw.dev_attr.attr,
+	&iio_dev_attr_cap0_raw.dev_attr.attr,
+	&iio_dev_attr_capdac0_raw.dev_attr.attr,
+	&iio_dev_attr_capdac1_raw.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad774x_attribute_group = {
+	.attrs = ad774x_attributes,
+};
+
+/*
+ * data ready events
+ */
+
+#define IIO_EVENT_CODE_CAP_RDY     IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_VT_RDY      IIO_BUFFER_EVENT_CODE(1)
+
+#define IIO_EVENT_ATTR_CAP_RDY_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(cap_rdy, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_ATTR_VT_RDY_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(vt_rdy, _evlist, _show, _store, _mask)
+
+static void ad774x_interrupt_handler_bh(struct work_struct *work_s)
+{
+	struct ad774x_chip_info *chip =
+		container_of(work_s, struct ad774x_chip_info, thresh_work);
+	u8 int_status;
+
+	enable_irq(chip->client->irq);
+
+	ad774x_i2c_read(chip, AD774X_STATUS, &int_status, 1);
+
+	if (int_status & AD774X_STATUS_RDYCAP)
+		iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_CAP_RDY,
+				chip->last_timestamp);
+
+	if (int_status & AD774X_STATUS_RDYVT)
+		iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_VT_RDY,
+				chip->last_timestamp);
+}
+
+static int ad774x_interrupt_handler_th(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct ad774x_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(data_rdy, &ad774x_interrupt_handler_th);
+
+static ssize_t ad774x_query_out_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	/*
+	 * AD774X provides one /RDY pin, which can be used as interrupt
+	 * but the pin is not configurable
+	 */
+	return sprintf(buf, "1\n");
+}
+
+static ssize_t ad774x_set_out_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return len;
+}
+
+IIO_EVENT_ATTR_CAP_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0);
+IIO_EVENT_ATTR_VT_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0);
+
+static struct attribute *ad774x_event_attributes[] = {
+	&iio_event_attr_cap_rdy.dev_attr.attr,
+	&iio_event_attr_vt_rdy.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ad774x_event_attribute_group = {
+	.attrs = ad774x_event_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit ad774x_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int ret = 0, regdone = 0;
+	struct ad774x_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, chip);
+
+	chip->client = client;
+	chip->name = id->name;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	/* Establish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->attrs = &ad774x_attribute_group;
+	chip->indio_dev->event_attrs = &ad774x_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)(chip);
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = 1;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+	regdone = 1;
+
+	if (client->irq) {
+		ret = iio_register_interrupt_line(client->irq,
+				chip->indio_dev,
+				0,
+				IRQF_TRIGGER_FALLING,
+				"ad774x");
+		if (ret)
+			goto error_free_dev;
+
+		iio_add_event_to_list(iio_event_attr_cap_rdy.listel,
+				&chip->indio_dev->interrupts[0]->ev_list);
+
+		INIT_WORK(&chip->thresh_work, ad774x_interrupt_handler_bh);
+	}
+
+	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
+
+	return 0;
+
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(chip->indio_dev);
+	else
+		iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad774x_remove(struct i2c_client *client)
+{
+	struct ad774x_chip_info *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	if (client->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad774x_id[] = {
+	{ "ad7745", 0 },
+	{ "ad7746", 0 },
+	{ "ad7747", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, ad774x_id);
+
+static struct i2c_driver ad774x_driver = {
+	.driver = {
+		.name = "ad774x",
+	},
+	.probe = ad774x_probe,
+	.remove = __devexit_p(ad774x_remove),
+	.id_table = ad774x_id,
+};
+
+static __init int ad774x_init(void)
+{
+	return i2c_add_driver(&ad774x_driver);
+}
+
+static __exit void ad774x_exit(void)
+{
+	i2c_del_driver(&ad774x_driver);
+}
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ad7745/6/7 capacitive sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad774x_init);
+module_exit(ad774x_exit);
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
new file mode 100644
index 0000000..ad7415a
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -0,0 +1,535 @@
+/*
+ * AD7816 digital temperature sensor driver supporting AD7816/7/8
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * AD7816 config masks
+ */
+#define AD7816_FULL			0x1
+#define AD7816_PD			0x2
+#define AD7816_CS_MASK			0x7
+#define AD7816_CS_MAX			0x4
+
+/*
+ * AD7816 temperature masks
+ */
+#define AD7816_VALUE_OFFSET		6
+#define AD7816_BOUND_VALUE_BASE		0x8
+#define AD7816_BOUND_VALUE_MIN		-95
+#define AD7816_BOUND_VALUE_MAX		152
+#define AD7816_TEMP_FLOAT_OFFSET	2
+#define AD7816_TEMP_FLOAT_MASK		0x3
+
+
+/*
+ * struct ad7816_chip_info - chip specifc information
+ */
+
+struct ad7816_chip_info {
+	const char *name;
+	struct spi_device *spi_dev;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	s64 last_timestamp;
+	u16 rdwr_pin;
+	u16 convert_pin;
+	u16 busy_pin;
+	u8  oti_data[AD7816_CS_MAX+1];
+	u8  channel_id;	/* 0 always be temperature */
+	u8  mode;
+};
+
+/*
+ * ad7816 data access by SPI
+ */
+static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	int ret = 0;
+
+	gpio_set_value(chip->rdwr_pin, 1);
+	gpio_set_value(chip->rdwr_pin, 0);
+	ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI channel setting error\n");
+		return ret;
+	}
+	gpio_set_value(chip->rdwr_pin, 1);
+
+
+	if (chip->mode == AD7816_PD) { /* operating mode 2 */
+		gpio_set_value(chip->convert_pin, 1);
+		gpio_set_value(chip->convert_pin, 0);
+	} else { /* operating mode 1 */
+		gpio_set_value(chip->convert_pin, 0);
+		gpio_set_value(chip->convert_pin, 1);
+	}
+
+	while (gpio_get_value(chip->busy_pin))
+		cpu_relax();
+
+	gpio_set_value(chip->rdwr_pin, 0);
+	gpio_set_value(chip->rdwr_pin, 1);
+	ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI data read error\n");
+		return ret;
+	}
+
+	*data = be16_to_cpu(*data);
+
+	return ret;
+}
+
+static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	int ret = 0;
+
+	gpio_set_value(chip->rdwr_pin, 1);
+	gpio_set_value(chip->rdwr_pin, 0);
+	ret = spi_write(spi_dev, &data, sizeof(data));
+	if (ret < 0)
+		dev_err(&spi_dev->dev, "SPI oti data write error\n");
+
+	return ret;
+}
+
+static ssize_t ad7816_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+
+	if (chip->mode)
+		return sprintf(buf, "power-save\n");
+	else
+		return sprintf(buf, "full\n");
+}
+
+static ssize_t ad7816_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+
+	if (strcmp(buf, "full")) {
+		gpio_set_value(chip->rdwr_pin, 1);
+		chip->mode = AD7816_FULL;
+	} else {
+		gpio_set_value(chip->rdwr_pin, 0);
+		chip->mode = AD7816_PD;
+	}
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		ad7816_show_mode,
+		ad7816_store_mode,
+		0);
+
+static ssize_t ad7816_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "full\npower-save\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, NULL, 0);
+
+static ssize_t ad7816_show_channel(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", chip->channel_id);
+}
+
+static ssize_t ad7816_store_channel(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
+		dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
+			data, chip->name);
+		return -EINVAL;
+	} else if (strcmp(chip->name, "ad7818") == 0 && data > 1) {
+		dev_err(&chip->spi_dev->dev,
+			"Invalid channel id %lu for ad7818.\n", data);
+		return -EINVAL;
+	} else if (strcmp(chip->name, "ad7816") == 0 && data > 0) {
+		dev_err(&chip->spi_dev->dev,
+			"Invalid channel id %lu for ad7816.\n", data);
+		return -EINVAL;
+	}
+
+	chip->channel_id = data;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(channel, S_IRUGO | S_IWUSR,
+		ad7816_show_channel,
+		ad7816_store_channel,
+		0);
+
+
+static ssize_t ad7816_show_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	s8 value;
+	int ret;
+
+	ret = ad7816_spi_read(chip, &data);
+	if (ret)
+		return -EIO;
+
+	data >>= AD7816_VALUE_OFFSET;
+
+	if (chip->channel_id == 0) {
+		value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
+		data &= AD7816_TEMP_FLOAT_MASK;
+		if (value < 0)
+			data = (1 << AD7816_TEMP_FLOAT_OFFSET) - data;
+		return sprintf(buf, "%d.%.2d\n", value, data * 25);
+	} else
+		return sprintf(buf, "%u\n", data);
+}
+
+static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0);
+
+static ssize_t ad7816_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad7816_show_name, NULL, 0);
+
+static struct attribute *ad7816_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_channel.dev_attr.attr,
+	&iio_dev_attr_value.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7816_attribute_group = {
+	.attrs = ad7816_attributes,
+};
+
+/*
+ * temperature bound events
+ */
+
+#define IIO_EVENT_CODE_AD7816_OTI    IIO_BUFFER_EVENT_CODE(0)
+
+static void ad7816_interrupt_bh(struct work_struct *work_s)
+{
+	struct ad7816_chip_info *chip =
+		container_of(work_s, struct ad7816_chip_info, thresh_work);
+
+	enable_irq(chip->spi_dev->irq);
+
+	iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_AD7816_OTI,
+			chip->last_timestamp);
+}
+
+static int ad7816_interrupt(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(ad7816, &ad7816_interrupt);
+
+static ssize_t ad7816_show_oti(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+	int value;
+
+	if (chip->channel_id > AD7816_CS_MAX) {
+		dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
+		return -EINVAL;
+	} else if (chip->channel_id == 0) {
+		value = AD7816_BOUND_VALUE_MIN +
+			(chip->oti_data[chip->channel_id] -
+			AD7816_BOUND_VALUE_BASE);
+		return sprintf(buf, "%d\n", value);
+	} else
+		return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]);
+}
+
+static inline ssize_t ad7816_set_oti(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct ad7816_chip_info *chip = dev_info->dev_data;
+	long value;
+	u8 data;
+	int ret;
+
+	ret = strict_strtol(buf, 10, &value);
+
+	if (chip->channel_id > AD7816_CS_MAX) {
+		dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
+		return -EINVAL;
+	} else if (chip->channel_id == 0) {
+		if (ret || value < AD7816_BOUND_VALUE_MIN ||
+			value > AD7816_BOUND_VALUE_MAX)
+			return -EINVAL;
+
+		data = (u8)(value - AD7816_BOUND_VALUE_MIN +
+			AD7816_BOUND_VALUE_BASE);
+	} else {
+		if (ret || value < AD7816_BOUND_VALUE_BASE || value > 255)
+			return -EINVAL;
+
+		data = (u8)value;
+	}
+
+	ret = ad7816_spi_write(chip, data);
+	if (ret)
+		return -EIO;
+
+	chip->oti_data[chip->channel_id] = data;
+
+	return len;
+}
+
+IIO_EVENT_ATTR_SH(oti, iio_event_ad7816,
+		ad7816_show_oti, ad7816_set_oti, 0);
+
+static struct attribute *ad7816_event_attributes[] = {
+	&iio_event_attr_oti.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ad7816_event_attribute_group = {
+	.attrs = ad7816_event_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit ad7816_probe(struct spi_device *spi_dev)
+{
+	struct ad7816_chip_info *chip;
+	unsigned short *pins = spi_dev->dev.platform_data;
+	int ret = 0;
+	int i;
+
+	if (!pins) {
+		dev_err(&spi_dev->dev, "No necessary GPIO platform data.\n");
+		return -EINVAL;
+	}
+
+	chip = kzalloc(sizeof(struct ad7816_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	dev_set_drvdata(&spi_dev->dev, chip);
+
+	chip->spi_dev = spi_dev;
+	chip->name = spi_dev->modalias;
+	for (i = 0; i <= AD7816_CS_MAX; i++)
+		chip->oti_data[i] = 203;
+	chip->rdwr_pin = pins[0];
+	chip->convert_pin = pins[1];
+	chip->busy_pin = pins[2];
+
+	ret = gpio_request(chip->rdwr_pin, chip->name);
+	if (ret) {
+		dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
+			chip->rdwr_pin);
+		goto error_free_chip;
+	}
+	gpio_direction_input(chip->rdwr_pin);
+	ret = gpio_request(chip->convert_pin, chip->name);
+	if (ret) {
+		dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
+			chip->convert_pin);
+		goto error_free_gpio_rdwr;
+	}
+	gpio_direction_input(chip->convert_pin);
+	ret = gpio_request(chip->busy_pin, chip->name);
+	if (ret) {
+		dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
+			chip->busy_pin);
+		goto error_free_gpio_convert;
+	}
+	gpio_direction_input(chip->busy_pin);
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_gpio;
+	}
+
+	chip->indio_dev->dev.parent = &spi_dev->dev;
+	chip->indio_dev->attrs = &ad7816_attribute_group;
+	chip->indio_dev->event_attrs = &ad7816_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = 1;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	if (spi_dev->irq) {
+		/* Only low trigger is supported in ad7816/7/8 */
+		ret = iio_register_interrupt_line(spi_dev->irq,
+				chip->indio_dev,
+				0,
+				IRQF_TRIGGER_LOW,
+				chip->name);
+		if (ret)
+			goto error_unreg_dev;
+
+		/*
+		 * The event handler list element refer to iio_event_ad7816.
+		 * All event attributes bind to the same event handler.
+		 * So, only register event handler once.
+		 */
+		iio_add_event_to_list(&iio_event_ad7816,
+				&chip->indio_dev->interrupts[0]->ev_list);
+
+		INIT_WORK(&chip->thresh_work, ad7816_interrupt_bh);
+	}
+
+	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
+			 chip->name);
+
+	return 0;
+
+error_unreg_dev:
+	iio_device_unregister(chip->indio_dev);
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_gpio:
+	gpio_free(chip->busy_pin);
+error_free_gpio_convert:
+	gpio_free(chip->convert_pin);
+error_free_gpio_rdwr:
+	gpio_free(chip->rdwr_pin);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit ad7816_remove(struct spi_device *spi_dev)
+{
+	struct ad7816_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	dev_set_drvdata(&spi_dev->dev, NULL);
+	if (spi_dev->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	gpio_free(chip->busy_pin);
+	gpio_free(chip->convert_pin);
+	gpio_free(chip->rdwr_pin);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct spi_device_id ad7816_id[] = {
+	{ "ad7816", 0 },
+	{ "ad7817", 0 },
+	{ "ad7818", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(spi, ad7816_id);
+
+static struct spi_driver ad7816_driver = {
+	.driver = {
+		.name = "ad7816",
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad7816_probe,
+	.remove = __devexit_p(ad7816_remove),
+	.id_table = ad7816_id,
+};
+
+static __init int ad7816_init(void)
+{
+	return spi_register_driver(&ad7816_driver);
+}
+
+static __exit void ad7816_exit(void)
+{
+	spi_unregister_driver(&ad7816_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices AD7816/7/8 digital"
+			" temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(ad7816_init);
+module_exit(ad7816_exit);
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
new file mode 100644
index 0000000..771a409
--- /dev/null
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -0,0 +1,952 @@
+/*
+ * ADT7310 digital temperature sensor driver supporting ADT7310
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * ADT7310 registers definition
+ */
+
+#define ADT7310_STATUS			0
+#define ADT7310_CONFIG			1
+#define ADT7310_TEMPERATURE		2
+#define ADT7310_ID			3
+#define ADT7310_T_CRIT			4
+#define ADT7310_T_HYST			5
+#define ADT7310_T_ALARM_HIGH		6
+#define ADT7310_T_ALARM_LOW		7
+
+/*
+ * ADT7310 status
+ */
+#define ADT7310_STAT_T_LOW		0x10
+#define ADT7310_STAT_T_HIGH		0x20
+#define ADT7310_STAT_T_CRIT		0x40
+#define ADT7310_STAT_NOT_RDY		0x80
+
+/*
+ * ADT7310 config
+ */
+#define ADT7310_FAULT_QUEUE_MASK	0x3
+#define ADT7310_CT_POLARITY		0x4
+#define ADT7310_INT_POLARITY		0x8
+#define ADT7310_EVENT_MODE		0x10
+#define ADT7310_MODE_MASK		0x60
+#define ADT7310_ONESHOT			0x20
+#define ADT7310_SPS			0x40
+#define ADT7310_PD			0x60
+#define ADT7310_RESOLUTION		0x80
+
+/*
+ * ADT7310 masks
+ */
+#define ADT7310_T16_VALUE_SIGN			0x8000
+#define ADT7310_T16_VALUE_FLOAT_OFFSET		7
+#define ADT7310_T16_VALUE_FLOAT_MASK		0x7F
+#define ADT7310_T13_VALUE_SIGN			0x1000
+#define ADT7310_T13_VALUE_OFFSET		3
+#define ADT7310_T13_VALUE_FLOAT_OFFSET		4
+#define ADT7310_T13_VALUE_FLOAT_MASK		0xF
+#define ADT7310_T_HYST_MASK			0xF
+#define ADT7310_DEVICE_ID_MASK			0x7
+#define ADT7310_MANUFACTORY_ID_MASK		0xF8
+#define ADT7310_MANUFACTORY_ID_OFFSET		3
+
+
+#define ADT7310_CMD_REG_MASK			0x28
+#define ADT7310_CMD_REG_OFFSET			3
+#define ADT7310_CMD_READ			0x40
+#define ADT7310_CMD_CON_READ			0x4
+
+#define ADT7310_IRQS				2
+
+/*
+ * struct adt7310_chip_info - chip specifc information
+ */
+
+struct adt7310_chip_info {
+	const char *name;
+	struct spi_device *spi_dev;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	s64 last_timestamp;
+	u8  config;
+};
+
+/*
+ * adt7310 register access by SPI
+ */
+
+static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
+	int ret = 0;
+
+	command |= ADT7310_CMD_READ;
+	ret = spi_write(spi_dev, &command, sizeof(command));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI write command error\n");
+		return ret;
+	}
+
+	ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI read word error\n");
+		return ret;
+	}
+
+	*data = be16_to_cpu(*data);
+
+	return 0;
+}
+
+static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	u8 buf[3];
+	int ret = 0;
+
+	buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
+	buf[1] = (u8)(data >> 8);
+	buf[2] = (u8)(data & 0xFF);
+
+	ret = spi_write(spi_dev, buf, 3);
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI write word error\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
+	int ret = 0;
+
+	command |= ADT7310_CMD_READ;
+	ret = spi_write(spi_dev, &command, sizeof(command));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI write command error\n");
+		return ret;
+	}
+
+	ret = spi_read(spi_dev, data, sizeof(*data));
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI read byte error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data)
+{
+	struct spi_device *spi_dev = chip->spi_dev;
+	u8 buf[2];
+	int ret = 0;
+
+	buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
+	buf[1] = data;
+
+	ret = spi_write(spi_dev, buf, 2);
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI write byte error\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static ssize_t adt7310_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	u8 config;
+
+	config = chip->config & ADT7310_MODE_MASK;
+
+	switch (config) {
+	case ADT7310_PD:
+		return sprintf(buf, "power-down\n");
+	case ADT7310_ONESHOT:
+		return sprintf(buf, "one-shot\n");
+	case ADT7310_SPS:
+		return sprintf(buf, "sps\n");
+	default:
+		return sprintf(buf, "full\n");
+	}
+}
+
+static ssize_t adt7310_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	u16 config;
+	int ret;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & (~ADT7310_MODE_MASK);
+	if (strcmp(buf, "power-down"))
+		config |= ADT7310_PD;
+	else if (strcmp(buf, "one-shot"))
+		config |= ADT7310_ONESHOT;
+	else if (strcmp(buf, "sps"))
+		config |= ADT7310_SPS;
+
+	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		adt7310_show_mode,
+		adt7310_store_mode,
+		0);
+
+static ssize_t adt7310_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "full\none-shot\nsps\npower-down\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0);
+
+static ssize_t adt7310_show_resolution(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	int ret;
+	int bits;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	if (chip->config & ADT7310_RESOLUTION)
+		bits = 16;
+	else
+		bits = 13;
+
+	return sprintf(buf, "%d bits\n", bits);
+}
+
+static ssize_t adt7310_store_resolution(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	u16 config;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & (~ADT7310_RESOLUTION);
+	if (data)
+		config |= ADT7310_RESOLUTION;
+
+	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
+		adt7310_show_resolution,
+		adt7310_store_resolution,
+		0);
+
+static ssize_t adt7310_show_id(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	u8 id;
+	int ret;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
+			id & ADT7310_DEVICE_ID_MASK,
+			(id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET);
+}
+
+static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
+		adt7310_show_id,
+		NULL,
+		0);
+
+static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip,
+		u16 data, char *buf)
+{
+	char sign = ' ';
+
+	if (chip->config & ADT7310_RESOLUTION) {
+		if (data & ADT7310_T16_VALUE_SIGN) {
+			/* convert supplement to positive value */
+			data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
+			sign = '-';
+		}
+		return sprintf(buf, "%c%d.%.7d\n", sign,
+				(data >> ADT7310_T16_VALUE_FLOAT_OFFSET),
+				(data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125);
+	} else {
+		if (data & ADT7310_T13_VALUE_SIGN) {
+			/* convert supplement to positive value */
+			data >>= ADT7310_T13_VALUE_OFFSET;
+			data = (ADT7310_T13_VALUE_SIGN << 1) - data;
+			sign = '-';
+		}
+		return sprintf(buf, "%c%d.%.4d\n", sign,
+				(data >> ADT7310_T13_VALUE_FLOAT_OFFSET),
+				(data & ADT7310_T13_VALUE_FLOAT_MASK) * 625);
+	}
+}
+
+static ssize_t adt7310_show_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	u8 status;
+	u16 data;
+	int ret, i = 0;
+
+	do {
+		ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
+		if (ret)
+			return -EIO;
+		i++;
+		if (i == 10000)
+			return -EIO;
+	} while (status & ADT7310_STAT_NOT_RDY);
+
+	ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data);
+	if (ret)
+		return -EIO;
+
+	return adt7310_convert_temperature(chip, data, buf);
+}
+
+static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0);
+
+static ssize_t adt7310_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, adt7310_show_name, NULL, 0);
+
+static struct attribute *adt7310_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_resolution.dev_attr.attr,
+	&iio_dev_attr_id.dev_attr.attr,
+	&iio_dev_attr_value.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group adt7310_attribute_group = {
+	.attrs = adt7310_attributes,
+};
+
+/*
+ * temperature bound events
+ */
+
+#define IIO_EVENT_CODE_ADT7310_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_ADT7310_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_ADT7310_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
+
+static void adt7310_interrupt_bh(struct work_struct *work_s)
+{
+	struct adt7310_chip_info *chip =
+		container_of(work_s, struct adt7310_chip_info, thresh_work);
+	u8 status;
+
+	if (adt7310_spi_read_byte(chip, ADT7310_STATUS, &status))
+		return;
+
+	if (status & ADT7310_STAT_T_HIGH)
+		iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT7310_ABOVE_ALARM,
+			chip->last_timestamp);
+	if (status & ADT7310_STAT_T_LOW)
+		iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT7310_BELLOW_ALARM,
+			chip->last_timestamp);
+	if (status & ADT7310_STAT_T_CRIT)
+		iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT7310_ABOVE_CRIT,
+			chip->last_timestamp);
+}
+
+static int adt7310_interrupt(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(adt7310, &adt7310_interrupt);
+IIO_EVENT_SH(adt7310_ct, &adt7310_interrupt);
+
+static ssize_t adt7310_show_event_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	if (chip->config & ADT7310_EVENT_MODE)
+		return sprintf(buf, "interrupt\n");
+	else
+		return sprintf(buf, "comparator\n");
+}
+
+static ssize_t adt7310_set_event_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	u16 config;
+	int ret;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config &= ~ADT7310_EVENT_MODE;
+	if (strcmp(buf, "comparator") != 0)
+		config |= ADT7310_EVENT_MODE;
+
+	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return len;
+}
+
+static ssize_t adt7310_show_available_event_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "comparator\ninterrupt\n");
+}
+
+static ssize_t adt7310_show_fault_queue(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK);
+}
+
+static ssize_t adt7310_set_fault_queue(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+	u8 config;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret || data > 3)
+		return -EINVAL;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT7310_FAULT_QUEUE_MASK;
+	config |= data;
+	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return len;
+}
+
+static inline ssize_t adt7310_show_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	int ret;
+
+	ret = adt7310_spi_read_word(chip, bound_reg, &data);
+	if (ret)
+		return -EIO;
+
+	return adt7310_convert_temperature(chip, data, buf);
+}
+
+static inline ssize_t adt7310_set_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	long tmp1, tmp2;
+	u16 data;
+	char *pos;
+	int ret;
+
+	pos = strchr(buf, '.');
+
+	ret = strict_strtol(buf, 10, &tmp1);
+
+	if (ret || tmp1 > 127 || tmp1 < -128)
+		return -EINVAL;
+
+	if (pos) {
+		len = strlen(pos);
+
+		if (chip->config & ADT7310_RESOLUTION) {
+			if (len > ADT7310_T16_VALUE_FLOAT_OFFSET)
+				len = ADT7310_T16_VALUE_FLOAT_OFFSET;
+			pos[len] = 0;
+			ret = strict_strtol(pos, 10, &tmp2);
+
+			if (!ret)
+				tmp2 = (tmp2 / 78125) * 78125;
+		} else {
+			if (len > ADT7310_T13_VALUE_FLOAT_OFFSET)
+				len = ADT7310_T13_VALUE_FLOAT_OFFSET;
+			pos[len] = 0;
+			ret = strict_strtol(pos, 10, &tmp2);
+
+			if (!ret)
+				tmp2 = (tmp2 / 625) * 625;
+		}
+	}
+
+	if (tmp1 < 0)
+		data = (u16)(-tmp1);
+	else
+		data = (u16)tmp1;
+
+	if (chip->config & ADT7310_RESOLUTION) {
+		data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) |
+			(tmp2 & ADT7310_T16_VALUE_FLOAT_MASK);
+
+		if (tmp1 < 0)
+			/* convert positive value to supplyment */
+			data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
+	} else {
+		data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) |
+			(tmp2 & ADT7310_T13_VALUE_FLOAT_MASK);
+
+		if (tmp1 < 0)
+			/* convert positive value to supplyment */
+			data = (ADT7310_T13_VALUE_SIGN << 1) - data;
+		data <<= ADT7310_T13_VALUE_OFFSET;
+	}
+
+	ret = adt7310_spi_write_word(chip, bound_reg, data);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+static ssize_t adt7310_show_t_alarm_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7310_show_t_bound(dev, attr,
+			ADT7310_T_ALARM_HIGH, buf);
+}
+
+static inline ssize_t adt7310_set_t_alarm_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7310_set_t_bound(dev, attr,
+			ADT7310_T_ALARM_HIGH, buf, len);
+}
+
+static ssize_t adt7310_show_t_alarm_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7310_show_t_bound(dev, attr,
+			ADT7310_T_ALARM_LOW, buf);
+}
+
+static inline ssize_t adt7310_set_t_alarm_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7310_set_t_bound(dev, attr,
+			ADT7310_T_ALARM_LOW, buf, len);
+}
+
+static ssize_t adt7310_show_t_crit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7310_show_t_bound(dev, attr,
+			ADT7310_T_CRIT, buf);
+}
+
+static inline ssize_t adt7310_set_t_crit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7310_set_t_bound(dev, attr,
+			ADT7310_T_CRIT, buf, len);
+}
+
+static ssize_t adt7310_show_t_hyst(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	int ret;
+	u8 t_hyst;
+
+	ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK);
+}
+
+static inline ssize_t adt7310_set_t_hyst(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7310_chip_info *chip = dev_info->dev_data;
+	int ret;
+	unsigned long data;
+	u8 t_hyst;
+
+	ret = strict_strtol(buf, 10, &data);
+
+	if (ret || data > ADT7310_T_HYST_MASK)
+		return -EINVAL;
+
+	t_hyst = (u8)data;
+
+	ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7310,
+		adt7310_show_event_mode, adt7310_set_event_mode, 0);
+IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7310,
+		adt7310_show_available_event_modes, NULL, 0);
+IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7310,
+		adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
+IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7310,
+		adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
+IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7310,
+		adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
+IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7310_ct,
+		adt7310_show_t_crit, adt7310_set_t_crit, 0);
+IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7310,
+		adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
+
+static struct attribute *adt7310_event_int_attributes[] = {
+	&iio_event_attr_event_mode.dev_attr.attr,
+	&iio_event_attr_available_event_modes.dev_attr.attr,
+	&iio_event_attr_fault_queue.dev_attr.attr,
+	&iio_event_attr_t_alarm_high.dev_attr.attr,
+	&iio_event_attr_t_alarm_low.dev_attr.attr,
+	&iio_event_attr_t_hyst.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute *adt7310_event_ct_attributes[] = {
+	&iio_event_attr_event_mode.dev_attr.attr,
+	&iio_event_attr_available_event_modes.dev_attr.attr,
+	&iio_event_attr_fault_queue.dev_attr.attr,
+	&iio_event_attr_t_crit.dev_attr.attr,
+	&iio_event_attr_t_hyst.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
+	{
+		.attrs = adt7310_event_int_attributes,
+	},
+	{
+		.attrs = adt7310_event_ct_attributes,
+	}
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit adt7310_probe(struct spi_device *spi_dev)
+{
+	struct adt7310_chip_info *chip;
+	int ret = 0;
+	unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
+	unsigned long irq_flags;
+
+	chip = kzalloc(sizeof(struct adt7310_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	dev_set_drvdata(&spi_dev->dev, chip);
+
+	chip->spi_dev = spi_dev;
+	chip->name = spi_dev->modalias;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	chip->indio_dev->dev.parent = &spi_dev->dev;
+	chip->indio_dev->attrs = &adt7310_attribute_group;
+	chip->indio_dev->event_attrs = adt7310_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = ADT7310_IRQS;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	/* CT critcal temperature event. line 0 */
+	if (spi_dev->irq) {
+		if (adt7310_platform_data[2])
+			irq_flags = adt7310_platform_data[2];
+		else
+			irq_flags = IRQF_TRIGGER_LOW;
+		ret = iio_register_interrupt_line(spi_dev->irq,
+				chip->indio_dev,
+				0,
+				irq_flags,
+				chip->name);
+		if (ret)
+			goto error_unreg_dev;
+
+		/*
+		 * The event handler list element refer to iio_event_adt7310.
+		 * All event attributes bind to the same event handler.
+		 * One event handler can only be added to one event list.
+		 */
+		iio_add_event_to_list(&iio_event_adt7310,
+				&chip->indio_dev->interrupts[0]->ev_list);
+	}
+
+	/* INT bound temperature alarm event. line 1 */
+	if (adt7310_platform_data[0]) {
+		ret = iio_register_interrupt_line(adt7310_platform_data[0],
+				chip->indio_dev,
+				1,
+				adt7310_platform_data[1],
+				chip->name);
+		if (ret)
+			goto error_unreg_ct_irq;
+
+		/*
+		 * The event handler list element refer to iio_event_adt7310.
+		 * All event attributes bind to the same event handler.
+		 * One event handler can only be added to one event list.
+		 */
+		iio_add_event_to_list(&iio_event_adt7310_ct,
+				&chip->indio_dev->interrupts[1]->ev_list);
+	}
+
+	if (spi_dev->irq && adt7310_platform_data[0]) {
+		INIT_WORK(&chip->thresh_work, adt7310_interrupt_bh);
+
+		ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
+		if (ret) {
+			ret = -EIO;
+			goto error_unreg_int_irq;
+		}
+
+		/* set irq polarity low level */
+		chip->config &= ~ADT7310_CT_POLARITY;
+
+		if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH)
+			chip->config |= ADT7310_INT_POLARITY;
+		else
+			chip->config &= ~ADT7310_INT_POLARITY;
+
+		ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config);
+		if (ret) {
+			ret = -EIO;
+			goto error_unreg_int_irq;
+		}
+	}
+
+	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
+			chip->name);
+
+	return 0;
+
+error_unreg_int_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 1);
+error_unreg_ct_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 0);
+error_unreg_dev:
+	iio_device_unregister(chip->indio_dev);
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit adt7310_remove(struct spi_device *spi_dev)
+{
+	struct adt7310_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
+	struct iio_dev *indio_dev = chip->indio_dev;
+	unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
+
+	dev_set_drvdata(&spi_dev->dev, NULL);
+	if (adt7310_platform_data[0])
+		iio_unregister_interrupt_line(indio_dev, 1);
+	if (spi_dev->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct spi_device_id adt7310_id[] = {
+	{ "adt7310", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(spi, adt7310_id);
+
+static struct spi_driver adt7310_driver = {
+	.driver = {
+		.name = "adt7310",
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = adt7310_probe,
+	.remove = __devexit_p(adt7310_remove),
+	.id_table = adt7310_id,
+};
+
+static __init int adt7310_init(void)
+{
+	return spi_register_driver(&adt7310_driver);
+}
+
+static __exit void adt7310_exit(void)
+{
+	spi_unregister_driver(&adt7310_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADT7310 digital"
+			" temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(adt7310_init);
+module_exit(adt7310_exit);
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
new file mode 100644
index 0000000..c345f27
--- /dev/null
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -0,0 +1,915 @@
+/*
+ * ADT7410 digital temperature sensor driver supporting ADT7410
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * ADT7410 registers definition
+ */
+
+#define ADT7410_TEMPERATURE		0
+#define ADT7410_STATUS			2
+#define ADT7410_CONFIG			3
+#define ADT7410_T_ALARM_HIGH		4
+#define ADT7410_T_ALARM_LOW		6
+#define ADT7410_T_CRIT			8
+#define ADT7410_T_HYST			0xA
+#define ADT7410_ID			0xB
+#define ADT7410_RESET			0x2F
+
+/*
+ * ADT7410 status
+ */
+#define ADT7410_STAT_T_LOW		0x10
+#define ADT7410_STAT_T_HIGH		0x20
+#define ADT7410_STAT_T_CRIT		0x40
+#define ADT7410_STAT_NOT_RDY		0x80
+
+/*
+ * ADT7410 config
+ */
+#define ADT7410_FAULT_QUEUE_MASK	0x3
+#define ADT7410_CT_POLARITY		0x4
+#define ADT7410_INT_POLARITY		0x8
+#define ADT7410_EVENT_MODE		0x10
+#define ADT7410_MODE_MASK		0x60
+#define ADT7410_ONESHOT			0x20
+#define ADT7410_SPS			0x40
+#define ADT7410_PD			0x60
+#define ADT7410_RESOLUTION		0x80
+
+/*
+ * ADT7410 masks
+ */
+#define ADT7410_T16_VALUE_SIGN			0x8000
+#define ADT7410_T16_VALUE_FLOAT_OFFSET		7
+#define ADT7410_T16_VALUE_FLOAT_MASK		0x7F
+#define ADT7410_T13_VALUE_SIGN			0x1000
+#define ADT7410_T13_VALUE_OFFSET		3
+#define ADT7410_T13_VALUE_FLOAT_OFFSET		4
+#define ADT7410_T13_VALUE_FLOAT_MASK		0xF
+#define ADT7410_T_HYST_MASK			0xF
+#define ADT7410_DEVICE_ID_MASK			0xF
+#define ADT7410_MANUFACTORY_ID_MASK		0xF0
+#define ADT7410_MANUFACTORY_ID_OFFSET		4
+
+#define ADT7410_IRQS				2
+
+/*
+ * struct adt7410_chip_info - chip specifc information
+ */
+
+struct adt7410_chip_info {
+	const char *name;
+	struct i2c_client *client;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	s64 last_timestamp;
+	u8  config;
+};
+
+/*
+ * adt7410 register access by I2C
+ */
+
+static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+		return ret;
+	}
+
+	*data = swab16((u16)ret);
+
+	return 0;
+}
+
+static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_smbus_write_word_data(client, reg, swab16(data));
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_smbus_read_byte_data(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+		return ret;
+	}
+
+	*data = (u8)ret;
+
+	return 0;
+}
+
+static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	ret = i2c_smbus_write_byte_data(client, reg, data);
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+static ssize_t adt7410_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	u8 config;
+
+	config = chip->config & ADT7410_MODE_MASK;
+
+	switch (config) {
+	case ADT7410_PD:
+		return sprintf(buf, "power-down\n");
+	case ADT7410_ONESHOT:
+		return sprintf(buf, "one-shot\n");
+	case ADT7410_SPS:
+		return sprintf(buf, "sps\n");
+	default:
+		return sprintf(buf, "full\n");
+	}
+}
+
+static ssize_t adt7410_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	u16 config;
+	int ret;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & (~ADT7410_MODE_MASK);
+	if (strcmp(buf, "power-down"))
+		config |= ADT7410_PD;
+	else if (strcmp(buf, "one-shot"))
+		config |= ADT7410_ONESHOT;
+	else if (strcmp(buf, "sps"))
+		config |= ADT7410_SPS;
+
+	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		adt7410_show_mode,
+		adt7410_store_mode,
+		0);
+
+static ssize_t adt7410_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "full\none-shot\nsps\npower-down\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0);
+
+static ssize_t adt7410_show_resolution(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	int ret;
+	int bits;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	if (chip->config & ADT7410_RESOLUTION)
+		bits = 16;
+	else
+		bits = 13;
+
+	return sprintf(buf, "%d bits\n", bits);
+}
+
+static ssize_t adt7410_store_resolution(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	u16 config;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & (~ADT7410_RESOLUTION);
+	if (data)
+		config |= ADT7410_RESOLUTION;
+
+	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
+		adt7410_show_resolution,
+		adt7410_store_resolution,
+		0);
+
+static ssize_t adt7410_show_id(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	u8 id;
+	int ret;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
+			id & ADT7410_DEVICE_ID_MASK,
+			(id & ADT7410_MANUFACTORY_ID_MASK) >> ADT7410_MANUFACTORY_ID_OFFSET);
+}
+
+static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
+		adt7410_show_id,
+		NULL,
+		0);
+
+static ssize_t adt7410_convert_temperature(struct adt7410_chip_info *chip,
+		u16 data, char *buf)
+{
+	char sign = ' ';
+
+	if (chip->config & ADT7410_RESOLUTION) {
+		if (data & ADT7410_T16_VALUE_SIGN) {
+			/* convert supplement to positive value */
+			data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
+			sign = '-';
+		}
+		return sprintf(buf, "%c%d.%.7d\n", sign,
+				(data >> ADT7410_T16_VALUE_FLOAT_OFFSET),
+				(data & ADT7410_T16_VALUE_FLOAT_MASK) * 78125);
+	} else {
+		if (data & ADT7410_T13_VALUE_SIGN) {
+			/* convert supplement to positive value */
+			data >>= ADT7410_T13_VALUE_OFFSET;
+			data = (ADT7410_T13_VALUE_SIGN << 1) - data;
+			sign = '-';
+		}
+		return sprintf(buf, "%c%d.%.4d\n", sign,
+				(data >> ADT7410_T13_VALUE_FLOAT_OFFSET),
+				(data & ADT7410_T13_VALUE_FLOAT_MASK) * 625);
+	}
+}
+
+static ssize_t adt7410_show_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	u8 status;
+	u16 data;
+	int ret, i = 0;
+
+	do {
+		ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status);
+		if (ret)
+			return -EIO;
+		i++;
+		if (i == 10000)
+			return -EIO;
+	} while (status & ADT7410_STAT_NOT_RDY);
+
+	ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data);
+	if (ret)
+		return -EIO;
+
+	return adt7410_convert_temperature(chip, data, buf);
+}
+
+static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
+
+static ssize_t adt7410_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, adt7410_show_name, NULL, 0);
+
+static struct attribute *adt7410_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_resolution.dev_attr.attr,
+	&iio_dev_attr_id.dev_attr.attr,
+	&iio_dev_attr_value.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group adt7410_attribute_group = {
+	.attrs = adt7410_attributes,
+};
+
+/*
+ * temperature bound events
+ */
+
+#define IIO_EVENT_CODE_ADT7410_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_ADT7410_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_ADT7410_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
+
+static void adt7410_interrupt_bh(struct work_struct *work_s)
+{
+	struct adt7410_chip_info *chip =
+		container_of(work_s, struct adt7410_chip_info, thresh_work);
+	u8 status;
+
+	if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status))
+		return;
+
+	enable_irq(chip->client->irq);
+
+	if (status & ADT7410_STAT_T_HIGH)
+		iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT7410_ABOVE_ALARM,
+			chip->last_timestamp);
+	if (status & ADT7410_STAT_T_LOW)
+		iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT7410_BELLOW_ALARM,
+			chip->last_timestamp);
+	if (status & ADT7410_STAT_T_CRIT)
+		iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT7410_ABOVE_CRIT,
+			chip->last_timestamp);
+}
+
+static int adt7410_interrupt(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(adt7410, &adt7410_interrupt);
+IIO_EVENT_SH(adt7410_ct, &adt7410_interrupt);
+
+static ssize_t adt7410_show_event_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	if (chip->config & ADT7410_EVENT_MODE)
+		return sprintf(buf, "interrupt\n");
+	else
+		return sprintf(buf, "comparator\n");
+}
+
+static ssize_t adt7410_set_event_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	u16 config;
+	int ret;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config &= ~ADT7410_EVENT_MODE;
+	if (strcmp(buf, "comparator") != 0)
+		config |= ADT7410_EVENT_MODE;
+
+	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static ssize_t adt7410_show_available_event_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "comparator\ninterrupt\n");
+}
+
+static ssize_t adt7410_show_fault_queue(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", chip->config & ADT7410_FAULT_QUEUE_MASK);
+}
+
+static ssize_t adt7410_set_fault_queue(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+	u8 config;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret || data > 3)
+		return -EINVAL;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT7410_FAULT_QUEUE_MASK;
+	config |= data;
+	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static inline ssize_t adt7410_show_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	int ret;
+
+	ret = adt7410_i2c_read_word(chip, bound_reg, &data);
+	if (ret)
+		return -EIO;
+
+	return adt7410_convert_temperature(chip, data, buf);
+}
+
+static inline ssize_t adt7410_set_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	long tmp1, tmp2;
+	u16 data;
+	char *pos;
+	int ret;
+
+	pos = strchr(buf, '.');
+
+	ret = strict_strtol(buf, 10, &tmp1);
+
+	if (ret || tmp1 > 127 || tmp1 < -128)
+		return -EINVAL;
+
+	if (pos) {
+		len = strlen(pos);
+
+		if (chip->config & ADT7410_RESOLUTION) {
+			if (len > ADT7410_T16_VALUE_FLOAT_OFFSET)
+				len = ADT7410_T16_VALUE_FLOAT_OFFSET;
+			pos[len] = 0;
+			ret = strict_strtol(pos, 10, &tmp2);
+
+			if (!ret)
+				tmp2 = (tmp2 / 78125) * 78125;
+		} else {
+			if (len > ADT7410_T13_VALUE_FLOAT_OFFSET)
+				len = ADT7410_T13_VALUE_FLOAT_OFFSET;
+			pos[len] = 0;
+			ret = strict_strtol(pos, 10, &tmp2);
+
+			if (!ret)
+				tmp2 = (tmp2 / 625) * 625;
+		}
+	}
+
+	if (tmp1 < 0)
+		data = (u16)(-tmp1);
+	else
+		data = (u16)tmp1;
+
+	if (chip->config & ADT7410_RESOLUTION) {
+		data = (data << ADT7410_T16_VALUE_FLOAT_OFFSET) |
+			(tmp2 & ADT7410_T16_VALUE_FLOAT_MASK);
+
+		if (tmp1 < 0)
+			/* convert positive value to supplyment */
+			data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
+	} else {
+		data = (data << ADT7410_T13_VALUE_FLOAT_OFFSET) |
+			(tmp2 & ADT7410_T13_VALUE_FLOAT_MASK);
+
+		if (tmp1 < 0)
+			/* convert positive value to supplyment */
+			data = (ADT7410_T13_VALUE_SIGN << 1) - data;
+		data <<= ADT7410_T13_VALUE_OFFSET;
+	}
+
+	ret = adt7410_i2c_write_word(chip, bound_reg, data);
+	if (ret)
+		return -EIO;
+
+	return ret;
+}
+
+static ssize_t adt7410_show_t_alarm_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7410_show_t_bound(dev, attr,
+			ADT7410_T_ALARM_HIGH, buf);
+}
+
+static inline ssize_t adt7410_set_t_alarm_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7410_set_t_bound(dev, attr,
+			ADT7410_T_ALARM_HIGH, buf, len);
+}
+
+static ssize_t adt7410_show_t_alarm_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7410_show_t_bound(dev, attr,
+			ADT7410_T_ALARM_LOW, buf);
+}
+
+static inline ssize_t adt7410_set_t_alarm_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7410_set_t_bound(dev, attr,
+			ADT7410_T_ALARM_LOW, buf, len);
+}
+
+static ssize_t adt7410_show_t_crit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7410_show_t_bound(dev, attr,
+			ADT7410_T_CRIT, buf);
+}
+
+static inline ssize_t adt7410_set_t_crit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7410_set_t_bound(dev, attr,
+			ADT7410_T_CRIT, buf, len);
+}
+
+static ssize_t adt7410_show_t_hyst(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	int ret;
+	u8 t_hyst;
+
+	ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", t_hyst & ADT7410_T_HYST_MASK);
+}
+
+static inline ssize_t adt7410_set_t_hyst(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7410_chip_info *chip = dev_info->dev_data;
+	int ret;
+	unsigned long data;
+	u8 t_hyst;
+
+	ret = strict_strtol(buf, 10, &data);
+
+	if (ret || data > ADT7410_T_HYST_MASK)
+		return -EINVAL;
+
+	t_hyst = (u8)data;
+
+	ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst);
+	if (ret)
+		return -EIO;
+
+	return ret;
+}
+
+IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7410,
+		adt7410_show_event_mode, adt7410_set_event_mode, 0);
+IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7410,
+		adt7410_show_available_event_modes, NULL, 0);
+IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7410,
+		adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
+IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7410,
+		adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
+IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7410,
+		adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
+IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7410_ct,
+		adt7410_show_t_crit, adt7410_set_t_crit, 0);
+IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7410,
+		adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
+
+static struct attribute *adt7410_event_int_attributes[] = {
+	&iio_event_attr_event_mode.dev_attr.attr,
+	&iio_event_attr_available_event_modes.dev_attr.attr,
+	&iio_event_attr_fault_queue.dev_attr.attr,
+	&iio_event_attr_t_alarm_high.dev_attr.attr,
+	&iio_event_attr_t_alarm_low.dev_attr.attr,
+	&iio_event_attr_t_hyst.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute *adt7410_event_ct_attributes[] = {
+	&iio_event_attr_event_mode.dev_attr.attr,
+	&iio_event_attr_available_event_modes.dev_attr.attr,
+	&iio_event_attr_fault_queue.dev_attr.attr,
+	&iio_event_attr_t_crit.dev_attr.attr,
+	&iio_event_attr_t_hyst.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
+	{
+		.attrs = adt7410_event_int_attributes,
+	},
+	{
+		.attrs = adt7410_event_ct_attributes,
+	}
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit adt7410_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct adt7410_chip_info *chip;
+	int ret = 0;
+	unsigned long *adt7410_platform_data = client->dev.platform_data;
+
+	chip = kzalloc(sizeof(struct adt7410_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, chip);
+
+	chip->client = client;
+	chip->name = id->name;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->attrs = &adt7410_attribute_group;
+	chip->indio_dev->event_attrs = adt7410_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = ADT7410_IRQS;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	/* CT critcal temperature event. line 0 */
+	if (client->irq) {
+		ret = iio_register_interrupt_line(client->irq,
+				chip->indio_dev,
+				0,
+				IRQF_TRIGGER_LOW,
+				chip->name);
+		if (ret)
+			goto error_unreg_dev;
+
+		/*
+		 * The event handler list element refer to iio_event_adt7410.
+		 * All event attributes bind to the same event handler.
+		 * One event handler can only be added to one event list.
+		 */
+		iio_add_event_to_list(&iio_event_adt7410,
+				&chip->indio_dev->interrupts[0]->ev_list);
+	}
+
+	/* INT bound temperature alarm event. line 1 */
+	if (adt7410_platform_data[0]) {
+		ret = iio_register_interrupt_line(adt7410_platform_data[0],
+				chip->indio_dev,
+				1,
+				adt7410_platform_data[1],
+				chip->name);
+		if (ret)
+			goto error_unreg_ct_irq;
+
+		/*
+		 * The event handler list element refer to iio_event_adt7410.
+		 * All event attributes bind to the same event handler.
+		 * One event handler can only be added to one event list.
+		 */
+		iio_add_event_to_list(&iio_event_adt7410_ct,
+				&chip->indio_dev->interrupts[1]->ev_list);
+	}
+
+	if (client->irq && adt7410_platform_data[0]) {
+		INIT_WORK(&chip->thresh_work, adt7410_interrupt_bh);
+
+		ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
+		if (ret) {
+			ret = -EIO;
+			goto error_unreg_int_irq;
+		}
+
+		/* set irq polarity low level */
+		chip->config &= ~ADT7410_CT_POLARITY;
+
+		if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH)
+			chip->config |= ADT7410_INT_POLARITY;
+		else
+			chip->config &= ~ADT7410_INT_POLARITY;
+
+		ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config);
+		if (ret) {
+			ret = -EIO;
+			goto error_unreg_int_irq;
+		}
+	}
+
+	dev_info(&client->dev, "%s temperature sensor registered.\n",
+			 id->name);
+
+	return 0;
+
+error_unreg_int_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 1);
+error_unreg_ct_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 0);
+error_unreg_dev:
+	iio_device_unregister(chip->indio_dev);
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit adt7410_remove(struct i2c_client *client)
+{
+	struct adt7410_chip_info *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = chip->indio_dev;
+	unsigned long *adt7410_platform_data = client->dev.platform_data;
+
+	if (adt7410_platform_data[0])
+		iio_unregister_interrupt_line(indio_dev, 1);
+	if (client->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct i2c_device_id adt7410_id[] = {
+	{ "adt7410", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, adt7410_id);
+
+static struct i2c_driver adt7410_driver = {
+	.driver = {
+		.name = "adt7410",
+	},
+	.probe = adt7410_probe,
+	.remove = __devexit_p(adt7410_remove),
+	.id_table = adt7410_id,
+};
+
+static __init int adt7410_init(void)
+{
+	return i2c_add_driver(&adt7410_driver);
+}
+
+static __exit void adt7410_exit(void)
+{
+	i2c_del_driver(&adt7410_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADT7410 digital"
+			" temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(adt7410_init);
+module_exit(adt7410_exit);
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
new file mode 100644
index 0000000..aff4d31
--- /dev/null
+++ b/drivers/staging/iio/adc/adt75.c
@@ -0,0 +1,732 @@
+/*
+ * ADT75 digital temperature sensor driver supporting ADT75
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * ADT75 registers definition
+ */
+
+#define ADT75_TEMPERATURE		0
+#define ADT75_CONFIG			1
+#define ADT75_T_HYST			2
+#define ADT75_T_OS			3
+#define ADT75_ONESHOT			4
+
+/*
+ * ADT75 config
+ */
+#define ADT75_PD			0x1
+#define ADT75_OS_INT			0x2
+#define ADT75_OS_POLARITY		0x4
+#define ADT75_FAULT_QUEUE_MASK		0x18
+#define ADT75_FAULT_QUEUE_OFFSET	3
+#define ADT75_SMBUS_ALART		0x8
+
+/*
+ * ADT75 masks
+ */
+#define ADT75_VALUE_SIGN		0x800
+#define ADT75_VALUE_OFFSET		4
+#define ADT75_VALUE_FLOAT_OFFSET	4
+#define ADT75_VALUE_FLOAT_MASK		0xF
+
+
+/*
+ * struct adt75_chip_info - chip specifc information
+ */
+
+struct adt75_chip_info {
+	const char *name;
+	struct i2c_client *client;
+	struct iio_dev *indio_dev;
+	struct work_struct thresh_work;
+	s64 last_timestamp;
+	u8  config;
+};
+
+/*
+ * adt75 register access by I2C
+ */
+
+static int adt75_i2c_read(struct adt75_chip_info *chip, u8 reg, u8 *data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0, len;
+
+	ret = i2c_smbus_write_byte(client, reg);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read register address error\n");
+		return ret;
+	}
+
+	if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT)
+		len = 1;
+	else
+		len = 2;
+
+	ret = i2c_master_recv(client, data, len);
+	if (ret < 0) {
+		dev_err(&client->dev, "I2C read error\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int adt75_i2c_write(struct adt75_chip_info *chip, u8 reg, u8 data)
+{
+	struct i2c_client *client = chip->client;
+	int ret = 0;
+
+	if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT)
+		ret = i2c_smbus_write_byte_data(client, reg, data);
+	else
+		ret = i2c_smbus_write_word_data(client, reg, data);
+
+	if (ret < 0)
+		dev_err(&client->dev, "I2C write error\n");
+
+	return ret;
+}
+
+static ssize_t adt75_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+
+	if (chip->config & ADT75_PD)
+		return sprintf(buf, "power-save\n");
+	else
+		return sprintf(buf, "full\n");
+}
+
+static ssize_t adt75_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	int ret;
+	u8 config;
+
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT75_PD;
+	if (!strcmp(buf, "full"))
+		config |= ADT75_PD;
+
+	ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		adt75_show_mode,
+		adt75_store_mode,
+		0);
+
+static ssize_t adt75_show_available_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "full\npower-down\n");
+}
+
+static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt75_show_available_modes, NULL, 0);
+
+static ssize_t adt75_show_oneshot(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->config & ADT75_ONESHOT));
+}
+
+static ssize_t adt75_store_oneshot(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	unsigned long data = 0;
+	int ret;
+	u8 config;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT75_ONESHOT;
+	if (data)
+		config |= ADT75_ONESHOT;
+
+	ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static IIO_DEVICE_ATTR(oneshot, S_IRUGO | S_IWUSR,
+		adt75_show_oneshot,
+		adt75_store_oneshot,
+		0);
+
+static ssize_t adt75_show_value(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	if (chip->config & ADT75_PD) {
+		dev_err(dev, "Can't read value in power-down mode.\n");
+		return -EIO;
+	}
+
+	if (chip->config & ADT75_ONESHOT) {
+		/* write to active converter */
+		ret = i2c_smbus_write_byte(chip->client, ADT75_ONESHOT);
+		if (ret)
+			return -EIO;
+	}
+
+	ret = adt75_i2c_read(chip, ADT75_TEMPERATURE, (u8 *)&data);
+	if (ret)
+		return -EIO;
+
+	data = swab16(data) >> ADT75_VALUE_OFFSET;
+	if (data & ADT75_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (ADT75_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.4d\n", sign,
+		(data >> ADT75_VALUE_FLOAT_OFFSET),
+		(data & ADT75_VALUE_FLOAT_MASK) * 625);
+}
+
+static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0);
+
+static ssize_t adt75_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, adt75_show_name, NULL, 0);
+
+static struct attribute *adt75_attributes[] = {
+	&iio_dev_attr_available_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_oneshot.dev_attr.attr,
+	&iio_dev_attr_value.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group adt75_attribute_group = {
+	.attrs = adt75_attributes,
+};
+
+/*
+ * temperature bound events
+ */
+
+#define IIO_EVENT_CODE_ADT75_OTI    IIO_BUFFER_EVENT_CODE(0)
+
+static void adt75_interrupt_bh(struct work_struct *work_s)
+{
+	struct adt75_chip_info *chip =
+		container_of(work_s, struct adt75_chip_info, thresh_work);
+
+	enable_irq(chip->client->irq);
+
+	iio_push_event(chip->indio_dev, 0,
+			IIO_EVENT_CODE_ADT75_OTI,
+			chip->last_timestamp);
+}
+
+static int adt75_interrupt(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct adt75_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(adt75, &adt75_interrupt);
+
+static ssize_t adt75_show_oti_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	/* retrive ALART status */
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	if (chip->config & ADT75_OS_INT)
+		return sprintf(buf, "interrupt\n");
+	else
+		return sprintf(buf, "comparator\n");
+}
+
+static ssize_t adt75_set_oti_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	int ret;
+	u8 config;
+
+	/* retrive ALART status */
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT75_OS_INT;
+	if (strcmp(buf, "comparator") != 0)
+		config |= ADT75_OS_INT;
+
+	ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static ssize_t adt75_show_available_oti_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "comparator\ninterrupt\n");
+}
+
+static ssize_t adt75_show_smbus_alart(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	/* retrive ALART status */
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", !!(chip->config & ADT75_SMBUS_ALART));
+}
+
+static ssize_t adt75_set_smbus_alart(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	unsigned long data = 0;
+	int ret;
+	u8 config;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	/* retrive ALART status */
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT75_SMBUS_ALART;
+	if (data)
+		config |= ADT75_SMBUS_ALART;
+
+	ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+
+static ssize_t adt75_show_fault_queue(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	int ret;
+
+	/* retrive ALART status */
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", (chip->config & ADT75_FAULT_QUEUE_MASK) >>
+				ADT75_FAULT_QUEUE_OFFSET);
+}
+
+static ssize_t adt75_set_fault_queue(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+	u8 config;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret || data > 3)
+		return -EINVAL;
+
+	/* retrive ALART status */
+	ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+	if (ret)
+		return -EIO;
+
+	config = chip->config & ~ADT75_FAULT_QUEUE_MASK;
+	config |= (data << ADT75_FAULT_QUEUE_OFFSET);
+	ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
+	if (ret)
+		return -EIO;
+
+	chip->config = config;
+
+	return ret;
+}
+static inline ssize_t adt75_show_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	u16 data;
+	char sign = ' ';
+	int ret;
+
+	ret = adt75_i2c_read(chip, bound_reg, (u8 *)&data);
+	if (ret)
+		return -EIO;
+
+	data = swab16(data) >> ADT75_VALUE_OFFSET;
+	if (data & ADT75_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (ADT75_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.4d\n", sign,
+		(data >> ADT75_VALUE_FLOAT_OFFSET),
+		(data & ADT75_VALUE_FLOAT_MASK) * 625);
+}
+
+static inline ssize_t adt75_set_t_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt75_chip_info *chip = dev_info->dev_data;
+	long tmp1, tmp2;
+	u16 data;
+	char *pos;
+	int ret;
+
+	pos = strchr(buf, '.');
+
+	ret = strict_strtol(buf, 10, &tmp1);
+
+	if (ret || tmp1 > 127 || tmp1 < -128)
+		return -EINVAL;
+
+	if (pos) {
+		len = strlen(pos);
+		if (len > ADT75_VALUE_FLOAT_OFFSET)
+			len = ADT75_VALUE_FLOAT_OFFSET;
+		pos[len] = 0;
+		ret = strict_strtol(pos, 10, &tmp2);
+
+		if (!ret)
+			tmp2 = (tmp2 / 625) * 625;
+	}
+
+	if (tmp1 < 0)
+		data = (u16)(-tmp1);
+	else
+		data = (u16)tmp1;
+	data = (data << ADT75_VALUE_FLOAT_OFFSET) | (tmp2 & ADT75_VALUE_FLOAT_MASK);
+	if (tmp1 < 0)
+		/* convert positive value to supplyment */
+		data = (ADT75_VALUE_SIGN << 1) - data;
+	data <<= ADT75_VALUE_OFFSET;
+	data = swab16(data);
+
+	ret = adt75_i2c_write(chip, bound_reg, (u8)data);
+	if (ret)
+		return -EIO;
+
+	return ret;
+}
+
+static ssize_t adt75_show_t_os(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt75_show_t_bound(dev, attr,
+			ADT75_T_OS, buf);
+}
+
+static inline ssize_t adt75_set_t_os(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt75_set_t_bound(dev, attr,
+			ADT75_T_OS, buf, len);
+}
+
+static ssize_t adt75_show_t_hyst(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt75_show_t_bound(dev, attr,
+			ADT75_T_HYST, buf);
+}
+
+static inline ssize_t adt75_set_t_hyst(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt75_set_t_bound(dev, attr,
+			ADT75_T_HYST, buf, len);
+}
+
+IIO_EVENT_ATTR_SH(oti_mode, iio_event_adt75,
+		adt75_show_oti_mode, adt75_set_oti_mode, 0);
+IIO_EVENT_ATTR_SH(available_oti_modes, iio_event_adt75,
+		adt75_show_available_oti_modes, NULL, 0);
+IIO_EVENT_ATTR_SH(smbus_alart, iio_event_adt75,
+		adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
+IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt75,
+		adt75_show_fault_queue, adt75_set_fault_queue, 0);
+IIO_EVENT_ATTR_SH(t_os, iio_event_adt75,
+		adt75_show_t_os, adt75_set_t_os, 0);
+IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt75,
+		adt75_show_t_hyst, adt75_set_t_hyst, 0);
+
+static struct attribute *adt75_event_attributes[] = {
+	&iio_event_attr_oti_mode.dev_attr.attr,
+	&iio_event_attr_available_oti_modes.dev_attr.attr,
+	&iio_event_attr_smbus_alart.dev_attr.attr,
+	&iio_event_attr_fault_queue.dev_attr.attr,
+	&iio_event_attr_t_os.dev_attr.attr,
+	&iio_event_attr_t_hyst.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adt75_event_attribute_group = {
+	.attrs = adt75_event_attributes,
+};
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit adt75_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct adt75_chip_info *chip;
+	int ret = 0;
+
+	chip = kzalloc(sizeof(struct adt75_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, chip);
+
+	chip->client = client;
+	chip->name = id->name;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	chip->indio_dev->dev.parent = &client->dev;
+	chip->indio_dev->attrs = &adt75_attribute_group;
+	chip->indio_dev->event_attrs = &adt75_event_attribute_group;
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = 1;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	if (client->irq > 0) {
+		ret = iio_register_interrupt_line(client->irq,
+				chip->indio_dev,
+				0,
+				IRQF_TRIGGER_LOW,
+				chip->name);
+		if (ret)
+			goto error_unreg_dev;
+
+		/*
+		 * The event handler list element refer to iio_event_adt75.
+		 * All event attributes bind to the same event handler.
+		 * So, only register event handler once.
+		 */
+		iio_add_event_to_list(&iio_event_adt75,
+				&chip->indio_dev->interrupts[0]->ev_list);
+
+		INIT_WORK(&chip->thresh_work, adt75_interrupt_bh);
+
+		ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
+		if (ret) {
+			ret = -EIO;
+			goto error_unreg_irq;
+		}
+
+		/* set irq polarity low level */
+		chip->config &= ~ADT75_OS_POLARITY;
+
+		ret = adt75_i2c_write(chip, ADT75_CONFIG, chip->config);
+		if (ret) {
+			ret = -EIO;
+			goto error_unreg_irq;
+		}
+	}
+
+	dev_info(&client->dev, "%s temperature sensor registered.\n",
+			 id->name);
+
+	return 0;
+error_unreg_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 0);
+error_unreg_dev:
+	iio_device_unregister(chip->indio_dev);
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+
+static int __devexit adt75_remove(struct i2c_client *client)
+{
+	struct adt75_chip_info *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	if (client->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+
+static const struct i2c_device_id adt75_id[] = {
+	{ "adt75", 0 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, adt75_id);
+
+static struct i2c_driver adt75_driver = {
+	.driver = {
+		.name = "adt75",
+	},
+	.probe = adt75_probe,
+	.remove = __devexit_p(adt75_remove),
+	.id_table = adt75_id,
+};
+
+static __init int adt75_init(void)
+{
+	return i2c_add_driver(&adt75_driver);
+}
+
+static __exit void adt75_exit(void)
+{
+	i2c_del_driver(&adt75_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADT75 digital"
+			" temperature sensor driver");
+MODULE_LICENSE("GPL v2");
+
+module_init(adt75_init);
+module_exit(adt75_exit);
diff --git a/drivers/staging/iio/addac/Kconfig b/drivers/staging/iio/addac/Kconfig
new file mode 100644
index 0000000..9847baf
--- /dev/null
+++ b/drivers/staging/iio/addac/Kconfig
@@ -0,0 +1,25 @@
+#
+# ADDAC drivers
+#
+comment "Analog digital bi-direction convertors"
+
+config ADT7316
+	tristate "Analog Devices ADT7316/7/8 ADT7516/7/9 temperature sensor, ADC and DAC driver"
+	help
+	  Say yes here to build support for Analog Devices ADT7316, ADT7317, ADT7318
+	  and ADT7516, ADT7517, ADT7519 temperature sensors, ADC and DAC.
+
+config ADT7316_SPI
+	tristate "support SPI bus connection"
+	depends on SPI && ADT7316
+	default y
+	help
+	  Say yes here to build SPI bus support for Analog Devices ADT7316/7/8
+	  and ADT7516/7/9.
+
+config ADT7316_I2C
+	tristate "support I2C bus connection"
+	depends on I2C && ADT7316
+	help
+	  Say yes here to build I2C bus support for Analog Devices ADT7316/7/8
+	  and ADT7516/7/9.
diff --git a/drivers/staging/iio/addac/Makefile b/drivers/staging/iio/addac/Makefile
new file mode 100644
index 0000000..4c76861
--- /dev/null
+++ b/drivers/staging/iio/addac/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for industrial I/O ADDAC drivers
+#
+
+obj-$(CONFIG_ADT7316) += adt7316.o
+obj-$(CONFIG_ADT7316_SPI) += adt7316-spi.o
+obj-$(CONFIG_ADT7316_I2C) += adt7316-i2c.o
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c
new file mode 100644
index 0000000..52d1ea3
--- /dev/null
+++ b/drivers/staging/iio/addac/adt7316-i2c.c
@@ -0,0 +1,170 @@
+/*
+ * I2C bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature
+ * sensor, ADC and DAC
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+
+#include "adt7316.h"
+
+/*
+ * adt7316 register access by I2C
+ */
+static int adt7316_i2c_read(void *client, u8 reg, u8 *data)
+{
+	struct i2c_client *cl = client;
+	int ret = 0;
+
+	ret = i2c_smbus_write_byte(cl, reg);
+	if (ret < 0) {
+		dev_err(&cl->dev, "I2C fail to select reg\n");
+		return ret;
+	}
+
+	ret = i2c_smbus_read_byte(client);
+	if (ret < 0) {
+		dev_err(&cl->dev, "I2C read error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int adt7316_i2c_write(void *client, u8 reg, u8 data)
+{
+	struct i2c_client *cl = client;
+	int ret = 0;
+
+	ret = i2c_smbus_write_byte_data(cl, reg, data);
+	if (ret < 0)
+		dev_err(&cl->dev, "I2C write error\n");
+
+	return ret;
+}
+
+static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data)
+{
+	struct i2c_client *cl = client;
+	int i, ret = 0;
+
+	if (count > ADT7316_REG_MAX_ADDR)
+		count = ADT7316_REG_MAX_ADDR;
+
+	for (i = 0; i < count; i++) {
+		ret = adt7316_i2c_read(cl, reg, &data[i]);
+		if (ret < 0) {
+			dev_err(&cl->dev, "I2C multi read error\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data)
+{
+	struct i2c_client *cl = client;
+	int i, ret = 0;
+
+	if (count > ADT7316_REG_MAX_ADDR)
+		count = ADT7316_REG_MAX_ADDR;
+
+	for (i = 0; i < count; i++) {
+		ret = adt7316_i2c_write(cl, reg, data[i]);
+		if (ret < 0) {
+			dev_err(&cl->dev, "I2C multi write error\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit adt7316_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct adt7316_bus bus = {
+		.client = client,
+		.irq = client->irq,
+		.irq_flags = IRQF_TRIGGER_LOW,
+		.read = adt7316_i2c_read,
+		.write = adt7316_i2c_write,
+		.multi_read = adt7316_i2c_multi_read,
+		.multi_write = adt7316_i2c_multi_write,
+	};
+
+	return adt7316_probe(&client->dev, &bus, id->name);
+}
+
+static int __devexit adt7316_i2c_remove(struct i2c_client *client)
+{
+	return adt7316_remove(&client->dev);;
+}
+
+static const struct i2c_device_id adt7316_i2c_id[] = {
+	{ "adt7316", 0 },
+	{ "adt7317", 0 },
+	{ "adt7318", 0 },
+	{ "adt7516", 0 },
+	{ "adt7517", 0 },
+	{ "adt7519", 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, adt7316_i2c_id);
+
+#ifdef CONFIG_PM
+static int adt7316_i2c_suspend(struct i2c_client *client, pm_message_t message)
+{
+	return adt7316_disable(&client->dev);
+}
+
+static int adt7316_i2c_resume(struct i2c_client *client)
+{
+	return adt7316_enable(&client->dev);
+}
+#else
+# define adt7316_i2c_suspend NULL
+# define adt7316_i2c_resume  NULL
+#endif
+
+static struct i2c_driver adt7316_driver = {
+	.driver = {
+		.name = "adt7316",
+		.owner  = THIS_MODULE,
+	},
+	.probe = adt7316_i2c_probe,
+	.remove = __devexit_p(adt7316_i2c_remove),
+	.suspend = adt7316_i2c_suspend,
+	.resume = adt7316_i2c_resume,
+	.id_table = adt7316_i2c_id,
+};
+
+static __init int adt7316_i2c_init(void)
+{
+	return i2c_add_driver(&adt7316_driver);
+}
+
+static __exit void adt7316_i2c_exit(void)
+{
+	i2c_del_driver(&adt7316_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and"
+			"ADT7516/7/8 digital temperature sensor, ADC and DAC");
+MODULE_LICENSE("GPL v2");
+
+module_init(adt7316_i2c_init);
+module_exit(adt7316_i2c_exit);
diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c
new file mode 100644
index 0000000..369d4d0
--- /dev/null
+++ b/drivers/staging/iio/addac/adt7316-spi.c
@@ -0,0 +1,180 @@
+/*
+ * API bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature
+ * sensor, ADC and DAC
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+
+#include "adt7316.h"
+
+#define ADT7316_SPI_MAX_FREQ_HZ		5000000
+#define ADT7316_SPI_CMD_READ		0x91
+#define ADT7316_SPI_CMD_WRITE		0x90
+
+/*
+ * adt7316 register access by SPI
+ */
+
+static int adt7316_spi_multi_read(void *client, u8 reg, u8 count, u8 *data)
+{
+	struct spi_device *spi_dev = client;
+	u8 cmd[2];
+	int ret = 0;
+
+	if (count > ADT7316_REG_MAX_ADDR)
+		count = ADT7316_REG_MAX_ADDR;
+
+	cmd[0] = ADT7316_SPI_CMD_WRITE;
+	cmd[1] = reg;
+
+	ret = spi_write(spi_dev, cmd, 2);
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI fail to select reg\n");
+		return ret;
+	}
+
+	cmd[0] = ADT7316_SPI_CMD_READ;
+
+	ret = spi_write_then_read(spi_dev, cmd, 1, data, count);
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI read data error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int adt7316_spi_multi_write(void *client, u8 reg, u8 count, u8 *data)
+{
+	struct spi_device *spi_dev = client;
+	u8 buf[ADT7316_REG_MAX_ADDR + 2];
+	int i, ret = 0;
+
+	if (count > ADT7316_REG_MAX_ADDR)
+		count = ADT7316_REG_MAX_ADDR;
+
+	buf[0] = ADT7316_SPI_CMD_WRITE;
+	buf[1] = reg;
+	for (i = 0; i < count; i++)
+		buf[i + 2] = data[i];
+
+	ret = spi_write(spi_dev, buf, count + 2);
+	if (ret < 0) {
+		dev_err(&spi_dev->dev, "SPI write error\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int adt7316_spi_read(void *client, u8 reg, u8 *data)
+{
+	return adt7316_spi_multi_read(client, reg, 1, data);
+}
+
+static int adt7316_spi_write(void *client, u8 reg, u8 val)
+{
+	return adt7316_spi_multi_write(client, reg, 1, &val);
+}
+
+/*
+ * device probe and remove
+ */
+
+static int __devinit adt7316_spi_probe(struct spi_device *spi_dev)
+{
+	struct adt7316_bus bus = {
+		.client = spi_dev,
+		.irq = spi_dev->irq,
+		.irq_flags = IRQF_TRIGGER_LOW,
+		.read = adt7316_spi_read,
+		.write = adt7316_spi_write,
+		.multi_read = adt7316_spi_multi_read,
+		.multi_write = adt7316_spi_multi_write,
+	};
+
+	/* don't exceed max specified SPI CLK frequency */
+	if (spi_dev->max_speed_hz > ADT7316_SPI_MAX_FREQ_HZ) {
+		dev_err(&spi_dev->dev, "SPI CLK %d Hz?\n",
+			spi_dev->max_speed_hz);
+		return -EINVAL;
+	}
+
+	/* switch from default I2C protocol to SPI protocol */
+	adt7316_spi_write(spi_dev, 0, 0);
+	adt7316_spi_write(spi_dev, 0, 0);
+	adt7316_spi_write(spi_dev, 0, 0);
+
+	return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias);
+}
+
+static int __devexit adt7316_spi_remove(struct spi_device *spi_dev)
+{
+	return adt7316_remove(&spi_dev->dev);
+}
+
+static const struct spi_device_id adt7316_spi_id[] = {
+	{ "adt7316", 0 },
+	{ "adt7317", 0 },
+	{ "adt7318", 0 },
+	{ "adt7516", 0 },
+	{ "adt7517", 0 },
+	{ "adt7519", 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(spi, adt7316_spi_id);
+
+#ifdef CONFIG_PM
+static int adt7316_spi_suspend(struct spi_device *spi_dev, pm_message_t message)
+{
+	return adt7316_disable(&spi_dev->dev);
+}
+
+static int adt7316_spi_resume(struct spi_device *spi_dev)
+{
+	return adt7316_enable(&spi_dev->dev);
+}
+#else
+# define adt7316_spi_suspend NULL
+# define adt7316_spi_resume  NULL
+#endif
+
+static struct spi_driver adt7316_driver = {
+	.driver = {
+		.name = "adt7316",
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = adt7316_spi_probe,
+	.remove = __devexit_p(adt7316_spi_remove),
+	.suspend = adt7316_spi_suspend,
+	.resume = adt7316_spi_resume,
+	.id_table = adt7316_spi_id,
+};
+
+static __init int adt7316_spi_init(void)
+{
+	return spi_register_driver(&adt7316_driver);
+}
+
+static __exit void adt7316_spi_exit(void)
+{
+	spi_unregister_driver(&adt7316_driver);
+}
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
+			"ADT7516/7/9 digital temperature sensor, ADC and DAC");
+MODULE_LICENSE("GPL v2");
+
+module_init(adt7316_spi_init);
+module_exit(adt7316_spi_exit);
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
new file mode 100644
index 0000000..d1b5b13
--- /dev/null
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -0,0 +1,2402 @@
+/*
+ * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/9
+ *
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "adt7316.h"
+
+/*
+ * ADT7316 registers definition
+ */
+#define ADT7316_INT_STAT1		0x0
+#define ADT7316_INT_STAT2		0x1
+#define ADT7316_LSB_IN_TEMP_VDD		0x3
+#define ADT7316_LSB_IN_TEMP_MASK	0x3
+#define ADT7316_LSB_VDD_MASK		0xC
+#define ADT7316_LSB_VDD_OFFSET		2
+#define ADT7316_LSB_EX_TEMP_AIN		0x4
+#define ADT7316_LSB_EX_TEMP_MASK	0x3
+#define ADT7516_LSB_AIN_SHIFT		2
+#define ADT7316_AD_MSB_DATA_BASE        0x6
+#define ADT7316_AD_MSB_DATA_REGS        3
+#define ADT7516_AD_MSB_DATA_REGS        6
+#define ADT7316_MSB_VDD			0x6
+#define ADT7316_MSB_IN_TEMP		0x7
+#define ADT7316_MSB_EX_TEMP		0x8
+#define ADT7516_MSB_AIN1		0x8
+#define ADT7516_MSB_AIN2		0x9
+#define ADT7516_MSB_AIN3		0xA
+#define ADT7516_MSB_AIN4		0xB
+#define ADT7316_DA_DATA_BASE		0x10
+#define ADT7316_DA_MSB_DATA_REGS	4
+#define ADT7316_LSB_DAC_A		0x10
+#define ADT7316_MSB_DAC_A		0x11
+#define ADT7316_LSB_DAC_B		0x12
+#define ADT7316_MSB_DAC_B		0x13
+#define ADT7316_LSB_DAC_C		0x14
+#define ADT7316_MSB_DAC_C		0x15
+#define ADT7316_LSB_DAC_D		0x16
+#define ADT7316_MSB_DAC_D		0x17
+#define ADT7316_CONFIG1			0x18
+#define ADT7316_CONFIG2			0x19
+#define ADT7316_CONFIG3			0x1A
+#define ADT7316_LDAC_CONFIG		0x1B
+#define ADT7316_DAC_CONFIG		0x1C
+#define ADT7316_INT_MASK1		0x1D
+#define ADT7316_INT_MASK2		0x1E
+#define ADT7316_IN_TEMP_OFFSET		0x1F
+#define ADT7316_EX_TEMP_OFFSET		0x20
+#define ADT7316_IN_ANALOG_TEMP_OFFSET	0x21
+#define ADT7316_EX_ANALOG_TEMP_OFFSET	0x22
+#define ADT7316_VDD_HIGH		0x23
+#define ADT7316_VDD_LOW			0x24
+#define ADT7316_IN_TEMP_HIGH		0x25
+#define ADT7316_IN_TEMP_LOW		0x26
+#define ADT7316_EX_TEMP_HIGH		0x27
+#define ADT7316_EX_TEMP_LOW		0x28
+#define ADT7516_AIN2_HIGH		0x2B
+#define ADT7516_AIN2_LOW		0x2C
+#define ADT7516_AIN3_HIGH		0x2D
+#define ADT7516_AIN3_LOW		0x2E
+#define ADT7516_AIN4_HIGH		0x2F
+#define ADT7516_AIN4_LOW		0x30
+#define ADT7316_DEVICE_ID		0x4D
+#define ADT7316_MANUFACTURE_ID		0x4E
+#define ADT7316_DEVICE_REV		0x4F
+#define ADT7316_SPI_LOCK_STAT		0x7F
+
+/*
+ * ADT7316 config1
+ */
+#define ADT7316_EN			0x1
+#define ADT7516_SEL_EX_TEMP		0x4
+#define ADT7516_SEL_AIN1_2_EX_TEMP_MASK	0x6
+#define ADT7516_SEL_AIN3		0x8
+#define ADT7316_INT_EN			0x20
+#define ADT7316_INT_POLARITY		0x40
+#define ADT7316_PD			0x80
+
+/*
+ * ADT7316 config2
+ */
+#define ADT7316_AD_SINGLE_CH_MASK	0x3
+#define ADT7516_AD_SINGLE_CH_MASK	0x7
+#define ADT7316_AD_SINGLE_CH_VDD	0
+#define ADT7316_AD_SINGLE_CH_IN		1
+#define ADT7316_AD_SINGLE_CH_EX		2
+#define ADT7516_AD_SINGLE_CH_AIN1	2
+#define ADT7516_AD_SINGLE_CH_AIN2	3
+#define ADT7516_AD_SINGLE_CH_AIN3	4
+#define ADT7516_AD_SINGLE_CH_AIN4	5
+#define ADT7316_AD_SINGLE_CH_MODE	0x10
+#define ADT7316_DISABLE_AVERAGING	0x20
+#define ADT7316_EN_SMBUS_TIMEOUT	0x40
+#define ADT7316_RESET			0x80
+
+/*
+ * ADT7316 config3
+ */
+#define ADT7316_ADCLK_22_5		0x1
+#define ADT7316_DA_HIGH_RESOLUTION	0x2
+#define ADT7316_DA_EN_VIA_DAC_LDCA	0x4
+#define ADT7516_AIN_IN_VREF		0x10
+#define ADT7316_EN_IN_TEMP_PROP_DACA	0x20
+#define ADT7316_EN_EX_TEMP_PROP_DACB	0x40
+
+/*
+ * ADT7316 DAC config
+ */
+#define ADT7316_DA_2VREF_CH_MASK	0xF
+#define ADT7316_DA_EN_MODE_MASK		0x30
+#define ADT7316_DA_EN_MODE_SINGLE	0x00
+#define ADT7316_DA_EN_MODE_AB_CD	0x10
+#define ADT7316_DA_EN_MODE_ABCD		0x20
+#define ADT7316_DA_EN_MODE_LDAC		0x30
+#define ADT7316_VREF_BYPASS_DAC_AB	0x40
+#define ADT7316_VREF_BYPASS_DAC_CD	0x80
+
+/*
+ * ADT7316 LDAC config
+ */
+#define ADT7316_LDAC_EN_DA_MASK		0xF
+#define ADT7316_DAC_IN_VREF		0x10
+#define ADT7516_DAC_AB_IN_VREF		0x10
+#define ADT7516_DAC_CD_IN_VREF		0x20
+#define ADT7516_DAC_IN_VREF_OFFSET	4
+#define ADT7516_DAC_IN_VREF_MASK	0x30
+
+/*
+ * ADT7316 INT_MASK2
+ */
+#define ADT7316_INT_MASK2_VDD		0x10
+
+/*
+ * ADT7316 value masks
+ */
+#define ADT7316_VALUE_MASK		0xfff
+#define ADT7316_T_VALUE_SIGN		0x400
+#define ADT7316_T_VALUE_FLOAT_OFFSET	2
+#define ADT7316_T_VALUE_FLOAT_MASK	0x2
+
+/*
+ * Chip ID
+ */
+#define ID_ADT7316		0x1
+#define ID_ADT7317		0x2
+#define ID_ADT7318		0x3
+#define ID_ADT7516		0x11
+#define ID_ADT7517		0x12
+#define ID_ADT7519		0x14
+
+#define ID_FAMILY_MASK		0xF0
+#define ID_ADT73XX		0x0
+#define ID_ADT75XX		0x10
+
+/*
+ * struct adt7316_chip_info - chip specifc information
+ */
+
+struct adt7316_chip_info {
+	const char		*name;
+	struct iio_dev		*indio_dev;
+	struct work_struct	thresh_work;
+	s64			last_timestamp;
+	struct adt7316_bus	bus;
+	u16			ldac_pin;
+	u16			int_mask;	/* 0x2f */
+	u8			config1;
+	u8			config2;
+	u8			config3;
+	u8			dac_config;	/* DAC config */
+	u8			ldac_config;	/* LDAC config */
+	u8			dac_bits;	/* 8, 10, 12 */
+	u8			id;		/* chip id */
+};
+
+/*
+ * Logic interrupt mask for user application to enable
+ * interrupts.
+ */
+#define ADT7316_IN_TEMP_HIGH_INT_MASK	0x1
+#define ADT7316_IN_TEMP_LOW_INT_MASK	0x2
+#define ADT7316_EX_TEMP_HIGH_INT_MASK	0x4
+#define ADT7316_EX_TEMP_LOW_INT_MASK	0x8
+#define ADT7316_EX_TEMP_FAULT_INT_MASK	0x10
+#define ADT7516_AIN1_INT_MASK		0x4
+#define ADT7516_AIN2_INT_MASK		0x20
+#define ADT7516_AIN3_INT_MASK		0x40
+#define ADT7516_AIN4_INT_MASK		0x80
+#define ADT7316_VDD_INT_MASK		0x100
+#define ADT7316_TEMP_INT_MASK		0x1F
+#define ADT7516_AIN_INT_MASK		0xE0
+#define ADT7316_TEMP_AIN_INT_MASK	\
+	(ADT7316_TEMP_INT_MASK | ADT7316_TEMP_INT_MASK)
+
+/*
+ * struct adt7316_chip_info - chip specifc information
+ */
+
+struct adt7316_limit_regs {
+	u16	data_high;
+	u16	data_low;
+};
+
+static ssize_t adt7316_show_enabled(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN));
+}
+
+static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip,
+		int enable)
+{
+	u8 config1;
+	int ret;
+
+	if (enable)
+		config1 = chip->config1 | ADT7316_EN;
+	else
+		config1 = chip->config1 & ~ADT7316_EN;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
+	if (ret)
+		return -EIO;
+
+	chip->config1 = config1;
+
+	return ret;
+
+}
+
+static ssize_t adt7316_store_enabled(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	int enable;
+
+	if (!memcmp(buf, "1", 1))
+		enable = 1;
+	else
+		enable = 0;
+
+	if (_adt7316_store_enabled(chip, enable) < 0)
+		return -EIO;
+	else
+		return len;
+}
+
+static IIO_DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR,
+		adt7316_show_enabled,
+		adt7316_store_enabled,
+		0);
+
+static ssize_t adt7316_show_select_ex_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP));
+}
+
+static ssize_t adt7316_store_select_ex_temp(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config1;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	config1 = chip->config1 & (~ADT7516_SEL_EX_TEMP);
+	if (!memcmp(buf, "1", 1))
+		config1 |= ADT7516_SEL_EX_TEMP;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
+	if (ret)
+		return -EIO;
+
+	chip->config1 = config1;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(select_ex_temp, S_IRUGO | S_IWUSR,
+		adt7316_show_select_ex_temp,
+		adt7316_store_select_ex_temp,
+		0);
+
+static ssize_t adt7316_show_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE)
+		return sprintf(buf, "single_channel\n");
+	else
+		return sprintf(buf, "round_robin\n");
+}
+
+static ssize_t adt7316_store_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config2;
+	int ret;
+
+	config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MODE);
+	if (!memcmp(buf, "single_channel", 14))
+		config2 |= ADT7316_AD_SINGLE_CH_MODE;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
+	if (ret)
+		return -EIO;
+
+	chip->config2 = config2;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+		adt7316_show_mode,
+		adt7316_store_mode,
+		0);
+
+static ssize_t adt7316_show_all_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return sprintf(buf, "single_channel\nround_robin\n");
+}
+
+static IIO_DEVICE_ATTR(all_modes, S_IRUGO, adt7316_show_all_modes, NULL, 0);
+
+static ssize_t adt7316_show_ad_channel(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
+		return -EPERM;
+
+	switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) {
+	case ADT7316_AD_SINGLE_CH_VDD:
+		return sprintf(buf, "0 - VDD\n");
+	case ADT7316_AD_SINGLE_CH_IN:
+		return sprintf(buf, "1 - Internal Temperature\n");
+	case ADT7316_AD_SINGLE_CH_EX:
+		if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) &&
+			(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
+			return sprintf(buf, "2 - AIN1\n");
+		else
+			return sprintf(buf, "2 - External Temperature\n");
+	case ADT7516_AD_SINGLE_CH_AIN2:
+		if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
+			return sprintf(buf, "3 - AIN2\n");
+		else
+			return sprintf(buf, "N/A\n");
+	case ADT7516_AD_SINGLE_CH_AIN3:
+		if (chip->config1 & ADT7516_SEL_AIN3)
+			return sprintf(buf, "4 - AIN3\n");
+		else
+			return sprintf(buf, "N/A\n");
+	case ADT7516_AD_SINGLE_CH_AIN4:
+		return sprintf(buf, "5 - AIN4\n");
+	default:
+		return sprintf(buf, "N/A\n");
+	};
+}
+
+static ssize_t adt7316_store_ad_channel(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config2;
+	unsigned long data = 0;
+	int ret;
+
+	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
+		return -EPERM;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
+		if (data > 5)
+			return -EINVAL;
+
+		config2 = chip->config2 & (~ADT7516_AD_SINGLE_CH_MASK);
+	} else {
+		if (data > 2)
+			return -EINVAL;
+
+		config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MASK);
+	}
+
+
+	config2 |= data;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
+	if (ret)
+		return -EIO;
+
+	chip->config2 = config2;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(ad_channel, S_IRUGO | S_IWUSR,
+		adt7316_show_ad_channel,
+		adt7316_store_ad_channel,
+		0);
+
+static ssize_t adt7316_show_all_ad_channels(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
+		return -EPERM;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+				"2 - External Temperature or AIN2\n"
+				"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
+	else
+		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+				"2 - External Temperature\n");
+}
+
+static IIO_DEVICE_ATTR(all_ad_channels, S_IRUGO,
+		adt7316_show_all_ad_channels, NULL, 0);
+
+static ssize_t adt7316_show_disable_averaging(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->config2 & ADT7316_DISABLE_AVERAGING));
+}
+
+static ssize_t adt7316_store_disable_averaging(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config2;
+	int ret;
+
+	config2 = chip->config2 & (~ADT7316_DISABLE_AVERAGING);
+	if (!memcmp(buf, "1", 1))
+		config2 |= ADT7316_DISABLE_AVERAGING;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
+	if (ret)
+		return -EIO;
+
+	chip->config2 = config2;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(disable_averaging, S_IRUGO | S_IWUSR,
+		adt7316_show_disable_averaging,
+		adt7316_store_disable_averaging,
+		0);
+
+static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT));
+}
+
+static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config2;
+	int ret;
+
+	config2 = chip->config2 & (~ADT7316_EN_SMBUS_TIMEOUT);
+	if (!memcmp(buf, "1", 1))
+		config2 |= ADT7316_EN_SMBUS_TIMEOUT;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
+	if (ret)
+		return -EIO;
+
+	chip->config2 = config2;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR,
+		adt7316_show_enable_smbus_timeout,
+		adt7316_store_enable_smbus_timeout,
+		0);
+
+
+static ssize_t adt7316_store_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config2;
+	int ret;
+
+	config2 = chip->config2 | ADT7316_RESET;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(reset, S_IWUSR,
+		NULL,
+		adt7316_store_reset,
+		0);
+
+static ssize_t adt7316_show_powerdown(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD));
+}
+
+static ssize_t adt7316_store_powerdown(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config1;
+	int ret;
+
+	config1 = chip->config1 & (~ADT7316_PD);
+	if (!memcmp(buf, "1", 1))
+		config1 |= ADT7316_PD;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
+	if (ret)
+		return -EIO;
+
+	chip->config1 = config1;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(powerdown, S_IRUGO | S_IWUSR,
+		adt7316_show_powerdown,
+		adt7316_store_powerdown,
+		0);
+
+static ssize_t adt7316_show_fast_ad_clock(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5));
+}
+
+static ssize_t adt7316_store_fast_ad_clock(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config3;
+	int ret;
+
+	config3 = chip->config3 & (~ADT7316_ADCLK_22_5);
+	if (!memcmp(buf, "1", 1))
+		config3 |= ADT7316_ADCLK_22_5;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
+	if (ret)
+		return -EIO;
+
+	chip->config3 = config3;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(fast_ad_clock, S_IRUGO | S_IWUSR,
+		adt7316_show_fast_ad_clock,
+		adt7316_store_fast_ad_clock,
+		0);
+
+static ssize_t adt7316_show_da_high_resolution(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) {
+		if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
+			return sprintf(buf, "1 (12 bits)\n");
+		else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
+			return sprintf(buf, "1 (10 bits)\n");
+	}
+
+	return sprintf(buf, "0 (8 bits)\n");
+}
+
+static ssize_t adt7316_store_da_high_resolution(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config3;
+	int ret;
+
+	chip->dac_bits = 8;
+
+	if (!memcmp(buf, "1", 1)) {
+		config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION;
+		if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516)
+			chip->dac_bits = 12;
+		else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
+			chip->dac_bits = 10;
+	} else
+		config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION);
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
+	if (ret)
+		return -EIO;
+
+	chip->config3 = config3;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(da_high_resolution, S_IRUGO | S_IWUSR,
+		adt7316_show_da_high_resolution,
+		adt7316_store_da_high_resolution,
+		0);
+
+static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->config3 & ADT7516_AIN_IN_VREF));
+}
+
+static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config3;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	if (memcmp(buf, "1", 1))
+		config3 = chip->config3 & (~ADT7516_AIN_IN_VREF);
+	else
+		config3 = chip->config3 | ADT7516_AIN_IN_VREF;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
+	if (ret)
+		return -EIO;
+
+	chip->config3 = config3;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(AIN_internal_Vref, S_IRUGO | S_IWUSR,
+		adt7316_show_AIN_internal_Vref,
+		adt7316_store_AIN_internal_Vref,
+		0);
+
+
+static ssize_t adt7316_show_enable_prop_DACA(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA));
+}
+
+static ssize_t adt7316_store_enable_prop_DACA(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config3;
+	int ret;
+
+	config3 = chip->config3 & (~ADT7316_EN_IN_TEMP_PROP_DACA);
+	if (!memcmp(buf, "1", 1))
+		config3 |= ADT7316_EN_IN_TEMP_PROP_DACA;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
+	if (ret)
+		return -EIO;
+
+	chip->config3 = config3;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(enable_proportion_DACA, S_IRUGO | S_IWUSR,
+		adt7316_show_enable_prop_DACA,
+		adt7316_store_enable_prop_DACA,
+		0);
+
+static ssize_t adt7316_show_enable_prop_DACB(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB));
+}
+
+static ssize_t adt7316_store_enable_prop_DACB(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config3;
+	int ret;
+
+	config3 = chip->config3 & (~ADT7316_EN_EX_TEMP_PROP_DACB);
+	if (!memcmp(buf, "1", 1))
+		config3 |= ADT7316_EN_EX_TEMP_PROP_DACB;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
+	if (ret)
+		return -EIO;
+
+	chip->config3 = config3;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(enable_proportion_DACB, S_IRUGO | S_IWUSR,
+		adt7316_show_enable_prop_DACB,
+		adt7316_store_enable_prop_DACB,
+		0);
+
+static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%x\n",
+		chip->dac_config & ADT7316_DA_2VREF_CH_MASK);
+}
+
+static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 dac_config;
+	unsigned long data = 0;
+	int ret;
+
+	ret = strict_strtoul(buf, 16, &data);
+	if (ret || data > ADT7316_DA_2VREF_CH_MASK)
+		return -EINVAL;
+
+	dac_config = chip->dac_config & (~ADT7316_DA_2VREF_CH_MASK);
+	dac_config |= data;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
+	if (ret)
+		return -EIO;
+
+	chip->dac_config = dac_config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, S_IRUGO | S_IWUSR,
+		adt7316_show_DAC_2Vref_ch_mask,
+		adt7316_store_DAC_2Vref_ch_mask,
+		0);
+
+static ssize_t adt7316_show_DAC_update_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
+		return sprintf(buf, "manual\n");
+	else {
+		switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) {
+		case ADT7316_DA_EN_MODE_SINGLE:
+			return sprintf(buf, "0 - auto at any MSB DAC writing\n");
+		case ADT7316_DA_EN_MODE_AB_CD:
+			return sprintf(buf, "1 - auto at MSB DAC AB and CD writing\n");
+		case ADT7316_DA_EN_MODE_ABCD:
+			return sprintf(buf, "2 - auto at MSB DAC ABCD writing\n");
+		default: /* ADT7316_DA_EN_MODE_LDAC */
+			return sprintf(buf, "3 - manual\n");
+		};
+	}
+}
+
+static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 dac_config;
+	unsigned long data;
+	int ret;
+
+	if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
+		return -EPERM;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret || data > ADT7316_DA_EN_MODE_MASK)
+		return -EINVAL;
+
+	dac_config = chip->dac_config & (~ADT7316_DA_EN_MODE_MASK);
+	dac_config |= data;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
+	if (ret)
+		return -EIO;
+
+	chip->dac_config = dac_config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(DAC_update_mode, S_IRUGO | S_IWUSR,
+		adt7316_show_DAC_update_mode,
+		adt7316_store_DAC_update_mode,
+		0);
+
+static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)
+		return sprintf(buf, "0 - auto at any MSB DAC writing\n"
+				"1 - auto at MSB DAC AB and CD writing\n"
+				"2 - auto at MSB DAC ABCD writing\n"
+				"3 - manual\n");
+	else
+		return sprintf(buf, "manual\n");
+}
+
+static IIO_DEVICE_ATTR(all_DAC_update_modes, S_IRUGO,
+		adt7316_show_all_DAC_update_modes, NULL, 0);
+
+
+static ssize_t adt7316_store_update_DAC(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 ldac_config;
+	unsigned long data;
+	int ret;
+
+	if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
+		if ((chip->dac_config & ADT7316_DA_EN_MODE_MASK) !=
+			ADT7316_DA_EN_MODE_LDAC)
+			return -EPERM;
+
+		ret = strict_strtoul(buf, 16, &data);
+		if (ret || data > ADT7316_LDAC_EN_DA_MASK)
+			return -EINVAL;
+
+		ldac_config = chip->ldac_config & (~ADT7316_LDAC_EN_DA_MASK);
+		ldac_config |= data;
+
+		ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG,
+			ldac_config);
+		if (ret)
+			return -EIO;
+	} else {
+		gpio_set_value(chip->ldac_pin, 0);
+		gpio_set_value(chip->ldac_pin, 1);
+	}
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(update_DAC, S_IRUGO | S_IWUSR,
+		NULL,
+		adt7316_store_update_DAC,
+		0);
+
+static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB));
+}
+
+static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 dac_config;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
+	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB);
+	if (!memcmp(buf, "1", 1))
+		dac_config |= ADT7316_VREF_BYPASS_DAC_AB;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
+	if (ret)
+		return -EIO;
+
+	chip->dac_config = dac_config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(DA_AB_Vref_bypass, S_IRUGO | S_IWUSR,
+		adt7316_show_DA_AB_Vref_bypass,
+		adt7316_store_DA_AB_Vref_bypass,
+		0);
+
+static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD));
+}
+
+static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 dac_config;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
+	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD);
+	if (!memcmp(buf, "1", 1))
+		dac_config |= ADT7316_VREF_BYPASS_DAC_CD;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config);
+	if (ret)
+		return -EIO;
+
+	chip->dac_config = dac_config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(DA_CD_Vref_bypass, S_IRUGO | S_IWUSR,
+		adt7316_show_DA_CD_Vref_bypass,
+		adt7316_store_DA_CD_Vref_bypass,
+		0);
+
+static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return sprintf(buf, "0x%x\n",
+			(chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >>
+			ADT7516_DAC_IN_VREF_OFFSET);
+	else
+		return sprintf(buf, "%d\n",
+			!!(chip->dac_config & ADT7316_DAC_IN_VREF));
+}
+
+static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 ldac_config;
+	unsigned long data;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
+		ret = strict_strtoul(buf, 16, &data);
+		if (ret || data > 3)
+			return -EINVAL;
+
+		ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK);
+		if (data & 0x1)
+			ldac_config |= ADT7516_DAC_AB_IN_VREF;
+		else if (data & 0x2)
+			ldac_config |= ADT7516_DAC_CD_IN_VREF;
+	} else {
+		ret = strict_strtoul(buf, 16, &data);
+		if (ret)
+			return -EINVAL;
+
+		ldac_config = chip->ldac_config & (~ADT7316_DAC_IN_VREF);
+		if (data)
+			ldac_config = chip->ldac_config | ADT7316_DAC_IN_VREF;
+	}
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, ldac_config);
+	if (ret)
+		return -EIO;
+
+	chip->ldac_config = ldac_config;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(DAC_internal_Vref, S_IRUGO | S_IWUSR,
+		adt7316_show_DAC_internal_Vref,
+		adt7316_store_DAC_internal_Vref,
+		0);
+
+static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
+		int channel, char *buf)
+{
+	u16 data;
+	u8 msb, lsb;
+	char sign = ' ';
+	int ret;
+
+	if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) &&
+		channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK))
+		return -EPERM;
+
+	switch (channel) {
+	case ADT7316_AD_SINGLE_CH_IN:
+		ret = chip->bus.read(chip->bus.client,
+			ADT7316_LSB_IN_TEMP_VDD, &lsb);
+		if (ret)
+			return -EIO;
+
+		ret = chip->bus.read(chip->bus.client,
+			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
+		if (ret)
+			return -EIO;
+
+		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
+		data |= lsb & ADT7316_LSB_IN_TEMP_MASK;
+		break;
+	case ADT7316_AD_SINGLE_CH_VDD:
+		ret = chip->bus.read(chip->bus.client,
+			ADT7316_LSB_IN_TEMP_VDD, &lsb);
+		if (ret)
+			return -EIO;
+
+		ret = chip->bus.read(chip->bus.client,
+
+			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
+		if (ret)
+			return -EIO;
+
+		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
+		data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET;
+		return sprintf(buf, "%d\n", data);
+	default: /* ex_temp and ain */
+		ret = chip->bus.read(chip->bus.client,
+			ADT7316_LSB_EX_TEMP_AIN, &lsb);
+		if (ret)
+			return -EIO;
+
+		ret = chip->bus.read(chip->bus.client,
+			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
+		if (ret)
+			return -EIO;
+
+		data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
+		data |= lsb & (ADT7316_LSB_EX_TEMP_MASK <<
+			(ADT7516_LSB_AIN_SHIFT * (channel -
+			(ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE))));
+
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+			return sprintf(buf, "%d\n", data);
+		else
+			break;
+	};
+
+	if (data & ADT7316_T_VALUE_SIGN) {
+		/* convert supplement to positive value */
+		data = (ADT7316_T_VALUE_SIGN << 1) - data;
+		sign = '-';
+	}
+
+	return sprintf(buf, "%c%d.%.2d\n", sign,
+		(data >> ADT7316_T_VALUE_FLOAT_OFFSET),
+		(data & ADT7316_T_VALUE_FLOAT_MASK) * 25);
+}
+
+static ssize_t adt7316_show_VDD(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf);
+}
+static IIO_DEVICE_ATTR(VDD, S_IRUGO, adt7316_show_VDD, NULL, 0);
+
+static ssize_t adt7316_show_in_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf);
+}
+
+static IIO_DEVICE_ATTR(in_temp, S_IRUGO, adt7316_show_in_temp, NULL, 0);
+
+static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf);
+}
+
+static IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
+static IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
+
+static ssize_t adt7316_show_AIN2(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf);
+}
+static IIO_DEVICE_ATTR(AIN2, S_IRUGO, adt7316_show_AIN2, NULL, 0);
+
+static ssize_t adt7316_show_AIN3(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf);
+}
+static IIO_DEVICE_ATTR(AIN3, S_IRUGO, adt7316_show_AIN3, NULL, 0);
+
+static ssize_t adt7316_show_AIN4(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf);
+}
+static IIO_DEVICE_ATTR(AIN4, S_IRUGO, adt7316_show_AIN4, NULL, 0);
+
+static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
+		int offset_addr, char *buf)
+{
+	int data;
+	u8 val;
+	int ret;
+
+	ret = chip->bus.read(chip->bus.client, offset_addr, &val);
+	if (ret)
+		return -EIO;
+
+	data = (int)val;
+	if (val & 0x80)
+		data -= 256;
+
+	return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
+		int offset_addr, const char *buf, size_t len)
+{
+	long data;
+	u8 val;
+	int ret;
+
+	ret = strict_strtol(buf, 10, &data);
+	if (ret || data > 127 || data < -128)
+		return -EINVAL;
+
+	if (data < 0)
+		data += 256;
+
+	val = (u8)data;
+
+	ret = chip->bus.write(chip->bus.client, offset_addr, val);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+static ssize_t adt7316_show_in_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf);
+}
+
+static ssize_t adt7316_store_in_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len);
+}
+
+static IIO_DEVICE_ATTR(in_temp_offset, S_IRUGO | S_IWUSR,
+		adt7316_show_in_temp_offset,
+		adt7316_store_in_temp_offset, 0);
+
+static ssize_t adt7316_show_ex_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf);
+}
+
+static ssize_t adt7316_store_ex_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len);
+}
+
+static IIO_DEVICE_ATTR(ex_temp_offset, S_IRUGO | S_IWUSR,
+		adt7316_show_ex_temp_offset,
+		adt7316_store_ex_temp_offset, 0);
+
+static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_temp_offset(chip,
+			ADT7316_IN_ANALOG_TEMP_OFFSET, buf);
+}
+
+static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_temp_offset(chip,
+			ADT7316_IN_ANALOG_TEMP_OFFSET, buf, len);
+}
+
+static IIO_DEVICE_ATTR(in_analog_temp_offset, S_IRUGO | S_IWUSR,
+		adt7316_show_in_analog_temp_offset,
+		adt7316_store_in_analog_temp_offset, 0);
+
+static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_temp_offset(chip,
+			ADT7316_EX_ANALOG_TEMP_OFFSET, buf);
+}
+
+static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_temp_offset(chip,
+			ADT7316_EX_ANALOG_TEMP_OFFSET, buf, len);
+}
+
+static IIO_DEVICE_ATTR(ex_analog_temp_offset, S_IRUGO | S_IWUSR,
+		adt7316_show_ex_analog_temp_offset,
+		adt7316_store_ex_analog_temp_offset, 0);
+
+static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip,
+		int channel, char *buf)
+{
+	u16 data;
+	u8 msb, lsb, offset;
+	int ret;
+
+	if (channel >= ADT7316_DA_MSB_DATA_REGS ||
+		(channel == 0 &&
+		(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) ||
+		(channel == 1 &&
+		(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)))
+		return -EPERM;
+
+	offset = chip->dac_bits - 8;
+
+	if (chip->dac_bits > 8) {
+		ret = chip->bus.read(chip->bus.client,
+			ADT7316_DA_DATA_BASE + channel * 2, &lsb);
+		if (ret)
+			return -EIO;
+	}
+
+	ret = chip->bus.read(chip->bus.client,
+		ADT7316_DA_DATA_BASE + 1 + channel * 2, &msb);
+	if (ret)
+		return -EIO;
+
+	data = (msb << offset) + (lsb & ((1 << offset) - 1));
+
+	return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
+		int channel, const char *buf, size_t len)
+{
+	u8 msb, lsb, offset;
+	unsigned long data;
+	int ret;
+
+	if (channel >= ADT7316_DA_MSB_DATA_REGS ||
+		(channel == 0 &&
+		(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) ||
+		(channel == 1 &&
+		(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)))
+		return -EPERM;
+
+	offset = chip->dac_bits - 8;
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret || data >= (1 << chip->dac_bits))
+		return -EINVAL;
+
+	if (chip->dac_bits > 8) {
+		lsb = data & (1 << offset);
+		ret = chip->bus.write(chip->bus.client,
+			ADT7316_DA_DATA_BASE + channel * 2, lsb);
+		if (ret)
+			return -EIO;
+	}
+
+	msb = data >> offset;
+	ret = chip->bus.write(chip->bus.client,
+		ADT7316_DA_DATA_BASE + 1 + channel * 2, msb);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+static ssize_t adt7316_show_DAC_A(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_DAC(chip, 0, buf);
+}
+
+static ssize_t adt7316_store_DAC_A(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_DAC(chip, 0, buf, len);
+}
+
+static IIO_DEVICE_ATTR(DAC_A, S_IRUGO | S_IWUSR, adt7316_show_DAC_A,
+		adt7316_store_DAC_A, 0);
+
+static ssize_t adt7316_show_DAC_B(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_DAC(chip, 1, buf);
+}
+
+static ssize_t adt7316_store_DAC_B(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_DAC(chip, 1, buf, len);
+}
+
+static IIO_DEVICE_ATTR(DAC_B, S_IRUGO | S_IWUSR, adt7316_show_DAC_B,
+		adt7316_store_DAC_B, 0);
+
+static ssize_t adt7316_show_DAC_C(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_DAC(chip, 2, buf);
+}
+
+static ssize_t adt7316_store_DAC_C(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_DAC(chip, 2, buf, len);
+}
+
+static IIO_DEVICE_ATTR(DAC_C, S_IRUGO | S_IWUSR, adt7316_show_DAC_C,
+		adt7316_store_DAC_C, 0);
+
+static ssize_t adt7316_show_DAC_D(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_DAC(chip, 3, buf);
+}
+
+static ssize_t adt7316_store_DAC_D(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_store_DAC(chip, 3, buf, len);
+}
+
+static IIO_DEVICE_ATTR(DAC_D, S_IRUGO | S_IWUSR, adt7316_show_DAC_D,
+		adt7316_store_DAC_D, 0);
+
+static ssize_t adt7316_show_device_id(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 id;
+	int ret;
+
+	ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_ID, &id);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", id);
+}
+
+static IIO_DEVICE_ATTR(device_id, S_IRUGO, adt7316_show_device_id, NULL, 0);
+
+static ssize_t adt7316_show_manufactorer_id(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 id;
+	int ret;
+
+	ret = chip->bus.read(chip->bus.client, ADT7316_MANUFACTURE_ID, &id);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", id);
+}
+
+static IIO_DEVICE_ATTR(manufactorer_id, S_IRUGO,
+		adt7316_show_manufactorer_id, NULL, 0);
+
+static ssize_t adt7316_show_device_rev(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 rev;
+	int ret;
+
+	ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_REV, &rev);
+	if (ret)
+		return -EIO;
+
+	return sprintf(buf, "%d\n", rev);
+}
+
+static IIO_DEVICE_ATTR(device_rev, S_IRUGO, adt7316_show_device_rev, NULL, 0);
+
+static ssize_t adt7316_show_bus_type(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 stat;
+	int ret;
+
+	ret = chip->bus.read(chip->bus.client, ADT7316_SPI_LOCK_STAT, &stat);
+	if (ret)
+		return -EIO;
+
+	if (stat)
+		return sprintf(buf, "spi\n");
+	else
+		return sprintf(buf, "i2c\n");
+}
+
+static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
+
+static ssize_t adt7316_show_name(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%s\n", chip->name);
+}
+
+static IIO_DEVICE_ATTR(name, S_IRUGO, adt7316_show_name, NULL, 0);
+
+static struct attribute *adt7316_attributes[] = {
+	&iio_dev_attr_all_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_dev_attr_enabled.dev_attr.attr,
+	&iio_dev_attr_ad_channel.dev_attr.attr,
+	&iio_dev_attr_all_ad_channels.dev_attr.attr,
+	&iio_dev_attr_disable_averaging.dev_attr.attr,
+	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
+	&iio_dev_attr_powerdown.dev_attr.attr,
+	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
+	&iio_dev_attr_da_high_resolution.dev_attr.attr,
+	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
+	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
+	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
+	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
+	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
+	&iio_dev_attr_update_DAC.dev_attr.attr,
+	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
+	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
+	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
+	&iio_dev_attr_VDD.dev_attr.attr,
+	&iio_dev_attr_in_temp.dev_attr.attr,
+	&iio_dev_attr_ex_temp.dev_attr.attr,
+	&iio_dev_attr_in_temp_offset.dev_attr.attr,
+	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
+	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
+	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
+	&iio_dev_attr_DAC_A.dev_attr.attr,
+	&iio_dev_attr_DAC_B.dev_attr.attr,
+	&iio_dev_attr_DAC_C.dev_attr.attr,
+	&iio_dev_attr_DAC_D.dev_attr.attr,
+	&iio_dev_attr_device_id.dev_attr.attr,
+	&iio_dev_attr_manufactorer_id.dev_attr.attr,
+	&iio_dev_attr_device_rev.dev_attr.attr,
+	&iio_dev_attr_bus_type.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group adt7316_attribute_group = {
+	.attrs = adt7316_attributes,
+};
+
+static struct attribute *adt7516_attributes[] = {
+	&iio_dev_attr_all_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_select_ex_temp.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_dev_attr_enabled.dev_attr.attr,
+	&iio_dev_attr_ad_channel.dev_attr.attr,
+	&iio_dev_attr_all_ad_channels.dev_attr.attr,
+	&iio_dev_attr_disable_averaging.dev_attr.attr,
+	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
+	&iio_dev_attr_powerdown.dev_attr.attr,
+	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
+	&iio_dev_attr_AIN_internal_Vref.dev_attr.attr,
+	&iio_dev_attr_da_high_resolution.dev_attr.attr,
+	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
+	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
+	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
+	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
+	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
+	&iio_dev_attr_update_DAC.dev_attr.attr,
+	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
+	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
+	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
+	&iio_dev_attr_VDD.dev_attr.attr,
+	&iio_dev_attr_in_temp.dev_attr.attr,
+	&iio_dev_attr_ex_temp_AIN1.dev_attr.attr,
+	&iio_dev_attr_AIN2.dev_attr.attr,
+	&iio_dev_attr_AIN3.dev_attr.attr,
+	&iio_dev_attr_AIN4.dev_attr.attr,
+	&iio_dev_attr_in_temp_offset.dev_attr.attr,
+	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
+	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
+	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
+	&iio_dev_attr_DAC_A.dev_attr.attr,
+	&iio_dev_attr_DAC_B.dev_attr.attr,
+	&iio_dev_attr_DAC_C.dev_attr.attr,
+	&iio_dev_attr_DAC_D.dev_attr.attr,
+	&iio_dev_attr_device_id.dev_attr.attr,
+	&iio_dev_attr_manufactorer_id.dev_attr.attr,
+	&iio_dev_attr_device_rev.dev_attr.attr,
+	&iio_dev_attr_bus_type.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group adt7516_attribute_group = {
+	.attrs = adt7516_attributes,
+};
+
+
+/*
+ * temperature bound events
+ */
+
+#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(0)
+#define IIO_EVENT_CODE_ADT7316_IN_TEMP_LOW    IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(2)
+#define IIO_EVENT_CODE_ADT7316_EX_TEMP_LOW    IIO_BUFFER_EVENT_CODE(3)
+#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT  IIO_BUFFER_EVENT_CODE(4)
+#define IIO_EVENT_CODE_ADT7516_AIN1           IIO_BUFFER_EVENT_CODE(5)
+#define IIO_EVENT_CODE_ADT7516_AIN2           IIO_BUFFER_EVENT_CODE(6)
+#define IIO_EVENT_CODE_ADT7516_AIN3           IIO_BUFFER_EVENT_CODE(7)
+#define IIO_EVENT_CODE_ADT7516_AIN4           IIO_BUFFER_EVENT_CODE(8)
+#define IIO_EVENT_CODE_ADT7316_VDD            IIO_BUFFER_EVENT_CODE(9)
+
+static void adt7316_interrupt_bh(struct work_struct *work_s)
+{
+	struct adt7316_chip_info *chip =
+		container_of(work_s, struct adt7316_chip_info, thresh_work);
+	u8 stat1, stat2;
+	int i, ret, count;
+
+	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1);
+	if (!ret) {
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+			count = 8;
+		else
+			count = 5;
+
+		for (i = 0; i < count; i++) {
+			if (stat1 & (1 << i))
+				iio_push_event(chip->indio_dev, 0,
+					IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i,
+					chip->last_timestamp);
+		}
+	}
+
+	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2);
+	if (!ret) {
+		if (stat2 & ADT7316_INT_MASK2_VDD)
+			iio_push_event(chip->indio_dev, 0,
+				IIO_EVENT_CODE_ADT7316_VDD,
+				chip->last_timestamp);
+	}
+
+	enable_irq(chip->bus.irq);
+}
+
+static int adt7316_interrupt(struct iio_dev *dev_info,
+		int index,
+		s64 timestamp,
+		int no_test)
+{
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	chip->last_timestamp = timestamp;
+	schedule_work(&chip->thresh_work);
+
+	return 0;
+}
+
+IIO_EVENT_SH(adt7316, &adt7316_interrupt);
+
+/*
+ * Show mask of enabled interrupts in Hex.
+ */
+static ssize_t adt7316_show_int_mask(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "0x%x\n", chip->int_mask);
+}
+
+/*
+ * Set 1 to the mask in Hex to enabled interrupts.
+ */
+static ssize_t adt7316_set_int_mask(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	unsigned long data;
+	int ret;
+	u8 mask;
+
+	ret = strict_strtoul(buf, 16, &data);
+	if (ret || data >= ADT7316_VDD_INT_MASK + 1)
+		return -EINVAL;
+
+	if (data & ADT7316_VDD_INT_MASK)
+		mask = 0;			/* enable vdd int */
+	else
+		mask = ADT7316_INT_MASK2_VDD;	/* disable vdd int */
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK2, mask);
+	if (!ret) {
+		chip->int_mask &= ~ADT7316_VDD_INT_MASK;
+		chip->int_mask |= data & ADT7316_VDD_INT_MASK;
+	}
+
+	if (data & ADT7316_TEMP_AIN_INT_MASK) {
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX)
+			/* mask in reg is opposite, set 1 to disable */
+			mask = (~data) & ADT7316_TEMP_INT_MASK;
+		else
+			/* mask in reg is opposite, set 1 to disable */
+			mask = (~data) & ADT7316_TEMP_AIN_INT_MASK;
+	}
+	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK1, mask);
+
+	chip->int_mask = mask;
+
+	return len;
+}
+static inline ssize_t adt7316_show_ad_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 val;
+	int data;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
+		bound_reg > ADT7316_EX_TEMP_LOW)
+		return -EPERM;
+
+	ret = chip->bus.read(chip->bus.client, bound_reg, &val);
+	if (ret)
+		return -EIO;
+
+	data = (int)val;
+
+	if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
+		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) {
+		if (data & 0x80)
+			data -= 256;
+	}
+
+	return sprintf(buf, "%d\n", data);
+}
+
+static inline ssize_t adt7316_set_ad_bound(struct device *dev,
+		struct device_attribute *attr,
+		u8 bound_reg,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	long data;
+	u8 val;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
+		bound_reg > ADT7316_EX_TEMP_LOW)
+		return -EPERM;
+
+	ret = strict_strtol(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
+		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) {
+		if (data > 255 || data < 0)
+			return -EINVAL;
+	} else {
+		if (data > 127 || data < -128)
+			return -EINVAL;
+
+		if (data < 0)
+			data += 256;
+	}
+
+	val = (u8)data;
+
+	ret = chip->bus.write(chip->bus.client, bound_reg, val);
+	if (ret)
+		return -EIO;
+
+	return len;
+}
+
+static ssize_t adt7316_show_in_temp_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7316_IN_TEMP_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_in_temp_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7316_IN_TEMP_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_in_temp_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7316_IN_TEMP_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_in_temp_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7316_IN_TEMP_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_ex_temp_ain1_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7316_EX_TEMP_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ex_temp_ain1_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7316_EX_TEMP_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ex_temp_ain1_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7316_EX_TEMP_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ex_temp_ain1_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7316_EX_TEMP_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_ain2_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN2_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ain2_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN2_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ain2_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN2_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ain2_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN2_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_ain3_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN3_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ain3_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN3_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ain3_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN3_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ain3_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN3_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_ain4_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN4_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ain4_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN4_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ain4_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN4_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ain4_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN4_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_int_enabled(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN));
+}
+
+static ssize_t adt7316_set_int_enabled(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config1;
+	int ret;
+
+	config1 = chip->config1 & (~ADT7316_INT_EN);
+	if (!memcmp(buf, "1", 1))
+		config1 |= ADT7316_INT_EN;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
+	if (ret)
+		return -EIO;
+
+	chip->config1 = config1;
+
+	return len;
+}
+
+
+IIO_EVENT_ATTR_SH(int_mask, iio_event_adt7316,
+		adt7316_show_int_mask, adt7316_set_int_mask, 0);
+IIO_EVENT_ATTR_SH(in_temp_high, iio_event_adt7316,
+		adt7316_show_in_temp_high, adt7316_set_in_temp_high, 0);
+IIO_EVENT_ATTR_SH(in_temp_low, iio_event_adt7316,
+		adt7316_show_in_temp_low, adt7316_set_in_temp_low, 0);
+IIO_EVENT_ATTR_SH(ex_temp_high, iio_event_adt7316,
+		adt7316_show_ex_temp_ain1_high,
+		adt7316_set_ex_temp_ain1_high, 0);
+IIO_EVENT_ATTR_SH(ex_temp_low, iio_event_adt7316,
+		adt7316_show_ex_temp_ain1_low,
+		adt7316_set_ex_temp_ain1_low, 0);
+IIO_EVENT_ATTR_SH(ex_temp_ain1_high, iio_event_adt7316,
+		adt7316_show_ex_temp_ain1_high,
+		adt7316_set_ex_temp_ain1_high, 0);
+IIO_EVENT_ATTR_SH(ex_temp_ain1_low, iio_event_adt7316,
+		adt7316_show_ex_temp_ain1_low,
+		adt7316_set_ex_temp_ain1_low, 0);
+IIO_EVENT_ATTR_SH(ain2_high, iio_event_adt7316,
+		adt7316_show_ain2_high, adt7316_set_ain2_high, 0);
+IIO_EVENT_ATTR_SH(ain2_low, iio_event_adt7316,
+		adt7316_show_ain2_low, adt7316_set_ain2_low, 0);
+IIO_EVENT_ATTR_SH(ain3_high, iio_event_adt7316,
+		adt7316_show_ain3_high, adt7316_set_ain3_high, 0);
+IIO_EVENT_ATTR_SH(ain3_low, iio_event_adt7316,
+		adt7316_show_ain3_low, adt7316_set_ain3_low, 0);
+IIO_EVENT_ATTR_SH(ain4_high, iio_event_adt7316,
+		adt7316_show_ain4_high, adt7316_set_ain4_high, 0);
+IIO_EVENT_ATTR_SH(ain4_low, iio_event_adt7316,
+		adt7316_show_ain4_low, adt7316_set_ain4_low, 0);
+IIO_EVENT_ATTR_SH(int_enabled, iio_event_adt7316,
+		adt7316_show_int_enabled, adt7316_set_int_enabled, 0);
+
+static struct attribute *adt7316_event_attributes[] = {
+	&iio_event_attr_int_mask.dev_attr.attr,
+	&iio_event_attr_in_temp_high.dev_attr.attr,
+	&iio_event_attr_in_temp_low.dev_attr.attr,
+	&iio_event_attr_ex_temp_high.dev_attr.attr,
+	&iio_event_attr_ex_temp_low.dev_attr.attr,
+	&iio_event_attr_int_enabled.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adt7316_event_attribute_group = {
+	.attrs = adt7316_event_attributes,
+};
+
+static struct attribute *adt7516_event_attributes[] = {
+	&iio_event_attr_int_mask.dev_attr.attr,
+	&iio_event_attr_in_temp_high.dev_attr.attr,
+	&iio_event_attr_in_temp_low.dev_attr.attr,
+	&iio_event_attr_ex_temp_ain1_high.dev_attr.attr,
+	&iio_event_attr_ex_temp_ain1_low.dev_attr.attr,
+	&iio_event_attr_ain2_high.dev_attr.attr,
+	&iio_event_attr_ain2_low.dev_attr.attr,
+	&iio_event_attr_ain3_high.dev_attr.attr,
+	&iio_event_attr_ain3_low.dev_attr.attr,
+	&iio_event_attr_ain4_high.dev_attr.attr,
+	&iio_event_attr_ain4_low.dev_attr.attr,
+	&iio_event_attr_int_enabled.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adt7516_event_attribute_group = {
+	.attrs = adt7516_event_attributes,
+};
+
+#ifdef CONFIG_PM
+int adt7316_disable(struct device *dev)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return _adt7316_store_enabled(chip, 0);
+}
+EXPORT_SYMBOL(adt7316_disable);
+
+int adt7316_enable(struct device *dev)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return _adt7316_store_enabled(chip, 1);
+}
+EXPORT_SYMBOL(adt7316_enable);
+#endif
+
+/*
+ * device probe and remove
+ */
+int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus,
+		const char *name)
+{
+	struct adt7316_chip_info *chip;
+	unsigned short *adt7316_platform_data = dev->platform_data;
+	int ret = 0;
+
+	chip = kzalloc(sizeof(struct adt7316_chip_info), GFP_KERNEL);
+
+	if (chip == NULL)
+		return -ENOMEM;
+
+	/* this is only used for device removal purposes */
+	dev_set_drvdata(dev, chip);
+
+	chip->bus = *bus;
+	chip->name = name;
+
+	if (name[4] == '3')
+		chip->id = ID_ADT7316 + (name[6] - '6');
+	else if (name[4] == '5')
+		chip->id = ID_ADT7516 + (name[6] - '6');
+	else
+		return -ENODEV;
+
+	chip->ldac_pin = adt7316_platform_data[1];
+	if (chip->ldac_pin) {
+		chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA;
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+			chip->config1 |= ADT7516_SEL_AIN3;
+	}
+	chip->int_mask = ADT7316_TEMP_INT_MASK | ADT7316_VDD_INT_MASK;
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		chip->int_mask |= ADT7516_AIN_INT_MASK;
+
+	chip->indio_dev = iio_allocate_device();
+	if (chip->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_chip;
+	}
+
+	chip->indio_dev->dev.parent = dev;
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
+		chip->indio_dev->attrs = &adt7516_attribute_group;
+		chip->indio_dev->event_attrs = &adt7516_event_attribute_group;
+	} else {
+		chip->indio_dev->attrs = &adt7316_attribute_group;
+		chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
+	}
+	chip->indio_dev->dev_data = (void *)chip;
+	chip->indio_dev->driver_module = THIS_MODULE;
+	chip->indio_dev->num_interrupt_lines = 1;
+	chip->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(chip->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	if (chip->bus.irq > 0) {
+		if (adt7316_platform_data[0])
+			chip->bus.irq_flags = adt7316_platform_data[0];
+
+		ret = iio_register_interrupt_line(chip->bus.irq,
+				chip->indio_dev,
+				0,
+				chip->bus.irq_flags,
+				chip->name);
+		if (ret)
+			goto error_unreg_dev;
+
+		/*
+		 * The event handler list element refer to iio_event_adt7316.
+		 * All event attributes bind to the same event handler.
+		 * So, only register event handler once.
+		 */
+		iio_add_event_to_list(&iio_event_adt7316,
+				&chip->indio_dev->interrupts[0]->ev_list);
+
+		INIT_WORK(&chip->thresh_work, adt7316_interrupt_bh);
+
+		if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
+			chip->config1 |= ADT7316_INT_POLARITY;
+	}
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
+	if (ret) {
+		ret = -EIO;
+		goto error_unreg_irq;
+	}
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
+	if (ret) {
+		ret = -EIO;
+		goto error_unreg_irq;
+	}
+
+	dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
+			chip->name);
+
+	return 0;
+
+error_unreg_irq:
+	iio_unregister_interrupt_line(chip->indio_dev, 0);
+error_unreg_dev:
+	iio_device_unregister(chip->indio_dev);
+error_free_dev:
+	iio_free_device(chip->indio_dev);
+error_free_chip:
+	kfree(chip);
+
+	return ret;
+}
+EXPORT_SYMBOL(adt7316_probe);
+
+int __devexit adt7316_remove(struct device *dev)
+{
+
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	struct iio_dev *indio_dev = chip->indio_dev;
+
+	dev_set_drvdata(dev, NULL);
+	if (chip->bus.irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_device_unregister(indio_dev);
+	iio_free_device(chip->indio_dev);
+	kfree(chip);
+
+	return 0;
+}
+EXPORT_SYMBOL(adt7316_remove);
+
+MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital"
+			" temperature sensor, ADC and DAC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h
new file mode 100644
index 0000000..d34bd67
--- /dev/null
+++ b/drivers/staging/iio/addac/adt7316.h
@@ -0,0 +1,33 @@
+/*
+ * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/9
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _ADT7316_H_
+#define _ADT7316_H_
+
+#include <linux/types.h>
+
+#define ADT7316_REG_MAX_ADDR		0x3F
+
+struct adt7316_bus {
+	void *client;
+	int irq;
+	int irq_flags;
+	int (*read) (void *client, u8 reg, u8 *data);
+	int (*write) (void *client, u8 reg, u8 val);
+	int (*multi_read) (void *client, u8 first_reg, u8 count, u8 *data);
+	int (*multi_write) (void *client, u8 first_reg, u8 count, u8 *data);
+};
+
+#ifdef CONFIG_PM
+int adt7316_disable(struct device *dev);
+int adt7316_enable(struct device *dev);
+#endif
+int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name);
+int adt7316_remove(struct device *dev);
+
+#endif
diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig
new file mode 100644
index 0000000..583df78
--- /dev/null
+++ b/drivers/staging/iio/dac/Kconfig
@@ -0,0 +1,11 @@
+#
+# DAC drivers
+#
+comment "Digital to analog convertors"
+
+config AD5624R_SPI
+	tristate "Analog Devices AD5624/44/64R DAC spi driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD5624R, AD5644R and
+	  AD5664R convertors (DAC). This driver uses the common SPI interface.
diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile
new file mode 100644
index 0000000..7ddf05d
--- /dev/null
+++ b/drivers/staging/iio/dac/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for industrial I/O DAC drivers
+#
+
+obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h
new file mode 100644
index 0000000..ce518be
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5624r.h
@@ -0,0 +1,21 @@
+#ifndef SPI_AD5624R_H_
+#define SPI_AD5624R_H_
+
+#define AD5624R_DAC_CHANNELS	4
+
+#define AD5624R_ADDR_DAC0	0x0
+#define AD5624R_ADDR_DAC1	0x1
+#define AD5624R_ADDR_DAC2	0x2
+#define AD5624R_ADDR_DAC3	0x3
+#define AD5624R_ADDR_ALL_DAC	0x7
+
+#define AD5624R_CMD_WRITE_INPUT_N             0x0
+#define AD5624R_CMD_UPDATE_DAC_N              0x1
+#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL  0x2
+#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N    0x3
+#define AD5624R_CMD_POWERDOWN_DAC             0x4
+#define AD5624R_CMD_RESET                     0x5
+#define AD5624R_CMD_LDAC_SETUP                0x6
+#define AD5624R_CMD_INTERNAL_REFER_SETUP      0x7
+
+#endif
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
new file mode 100644
index 0000000..705ff50
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5624r_spi.c
@@ -0,0 +1,313 @@
+/*
+ * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/delay.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "dac.h"
+#include "ad5624r.h"
+
+/**
+ * struct ad5624r_state - device related storage
+ * @indio_dev:	associated industrial IO device
+ * @us:		spi device
+ **/
+struct ad5624r_state {
+	struct iio_dev *indio_dev;
+	struct spi_device *us;
+	int data_len;
+	int ldac_mode;
+	int dac_power_mode[AD5624R_DAC_CHANNELS];
+	int internal_ref;
+};
+
+static int ad5624r_spi_write(struct spi_device *spi, u8 cmd, u8 addr, u16 val, u8 len)
+{
+	struct spi_transfer t;
+	struct spi_message m;
+	u32 data;
+	u8 msg[3];
+
+	/*
+	 * The input shift register is 24 bits wide. The first two bits are don't care bits.
+	 * The next three are the command bits, C2 to C0, followed by the 3-bit DAC address,
+	 * A2 to A0, and then the 16-, 14-, 12-bit data-word. The data-word comprises the 16-,
+	 * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, for the AD5664R,
+	 * AD5644R, and AD5624R, respectively.
+	 */
+	data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len));
+	msg[0] = data >> 16;
+	msg[1] = data >> 8;
+	msg[2] = data;
+
+	spi_message_init(&m);
+	memset(&t, 0, (sizeof t));
+	t.tx_buf = &msg[0];
+	t.len = 3;
+
+	spi_message_add_tail(&t, &m);
+	spi_sync(spi, &m);
+
+	return len;
+}
+
+static ssize_t ad5624r_write_dac(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	long readin;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
+			this_attr->address, readin, st->data_len);
+	return ret ? ret : len;
+}
+
+static ssize_t ad5624r_read_ldac_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+
+	return sprintf(buf, "%x\n", st->ldac_mode);
+}
+
+static ssize_t ad5624r_write_ldac_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	long readin;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+
+	ret = strict_strtol(buf, 16, &readin);
+	if (ret)
+		return ret;
+
+	ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, readin & 0xF, 16);
+	st->ldac_mode = readin & 0xF;
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad5624r_read_dac_power_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	return sprintf(buf, "%d\n", st->dac_power_mode[this_attr->address]);
+}
+
+static ssize_t ad5624r_write_dac_power_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	long readin;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0,
+			((readin & 0x3) << 4) | (1 << this_attr->address), 16);
+
+	st->dac_power_mode[this_attr->address] = readin & 0x3;
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad5624r_read_internal_ref_mode(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+
+	return sprintf(buf, "%d\n", st->internal_ref);
+}
+
+static ssize_t ad5624r_write_internal_ref_mode(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	long readin;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5624r_state *st = indio_dev->dev_data;
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, !!readin, 16);
+
+	st->internal_ref = !!readin;
+
+	return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_DAC(0, ad5624r_write_dac, AD5624R_ADDR_DAC0);
+static IIO_DEV_ATTR_DAC(1, ad5624r_write_dac, AD5624R_ADDR_DAC1);
+static IIO_DEV_ATTR_DAC(2, ad5624r_write_dac, AD5624R_ADDR_DAC2);
+static IIO_DEV_ATTR_DAC(3, ad5624r_write_dac, AD5624R_ADDR_DAC3);
+
+static IIO_DEVICE_ATTR(ldac_mode, S_IRUGO | S_IWUSR, ad5624r_read_ldac_mode,
+		ad5624r_write_ldac_mode, 0);
+static IIO_DEVICE_ATTR(internal_ref, S_IRUGO | S_IWUSR, ad5624r_read_internal_ref_mode,
+		ad5624r_write_internal_ref_mode, 0);
+
+#define IIO_DEV_ATTR_DAC_POWER_MODE(_num, _show, _store, _addr)			\
+	IIO_DEVICE_ATTR(dac_power_mode_##_num, S_IRUGO | S_IWUSR, _show, _store, _addr)
+
+static IIO_DEV_ATTR_DAC_POWER_MODE(0, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 0);
+static IIO_DEV_ATTR_DAC_POWER_MODE(1, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 1);
+static IIO_DEV_ATTR_DAC_POWER_MODE(2, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 2);
+static IIO_DEV_ATTR_DAC_POWER_MODE(3, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 3);
+
+static struct attribute *ad5624r_attributes[] = {
+	&iio_dev_attr_dac_0.dev_attr.attr,
+	&iio_dev_attr_dac_1.dev_attr.attr,
+	&iio_dev_attr_dac_2.dev_attr.attr,
+	&iio_dev_attr_dac_3.dev_attr.attr,
+	&iio_dev_attr_dac_power_mode_0.dev_attr.attr,
+	&iio_dev_attr_dac_power_mode_1.dev_attr.attr,
+	&iio_dev_attr_dac_power_mode_2.dev_attr.attr,
+	&iio_dev_attr_dac_power_mode_3.dev_attr.attr,
+	&iio_dev_attr_ldac_mode.dev_attr.attr,
+	&iio_dev_attr_internal_ref.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad5624r_attribute_group = {
+	.attrs = ad5624r_attributes,
+};
+
+static int __devinit ad5624r_probe(struct spi_device *spi)
+{
+
+	struct ad5624r_state *st;
+	int ret = 0;
+	char *chip_name = spi->dev.platform_data;
+
+	if (!chip_name)
+		return -ENODEV;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	if (strcmp(chip_name, "ad5624r") == 0)
+		st->data_len = 12;
+	else if (strcmp(chip_name, "ad5644r") == 0)
+		st->data_len = 14;
+	else if (strcmp(chip_name, "ad5664r") == 0)
+		st->data_len = 16;
+	else {
+		dev_err(&spi->dev, "not supported chip type\n");
+		ret = -EINVAL;
+		goto error_ret;
+	}
+
+	st->us = spi;
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 0;
+	st->indio_dev->event_attrs = NULL;
+
+	st->indio_dev->attrs = &ad5624r_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	spi->mode = SPI_MODE_0;
+	spi_setup(spi);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->indio_dev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad5624r_remove(struct spi_device *spi)
+{
+	struct ad5624r_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->indio_dev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad5624r_driver = {
+	.driver = {
+		.name = "ad5624r",
+		.owner = THIS_MODULE,
+	},
+	.probe = ad5624r_probe,
+	.remove = __devexit_p(ad5624r_remove),
+};
+
+static __init int ad5624r_spi_init(void)
+{
+	return spi_register_driver(&ad5624r_driver);
+}
+module_init(ad5624r_spi_init);
+
+static __exit void ad5624r_spi_exit(void)
+{
+	spi_unregister_driver(&ad5624r_driver);
+}
+module_exit(ad5624r_spi_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/dac.h b/drivers/staging/iio/dac/dac.h
new file mode 100644
index 0000000..55005ee
--- /dev/null
+++ b/drivers/staging/iio/dac/dac.h
@@ -0,0 +1,6 @@
+/*
+ * dac.h - sysfs attributes associated with DACs
+ */
+
+#define IIO_DEV_ATTR_DAC(_num, _store, _addr)			\
+	IIO_DEVICE_ATTR(dac_##_num, S_IWUSR, NULL, _store, _addr)
diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig
new file mode 100644
index 0000000..d045ed6
--- /dev/null
+++ b/drivers/staging/iio/dds/Kconfig
@@ -0,0 +1,46 @@
+#
+# Direct Digital Synthesis drivers
+#
+comment "Direct Digital Synthesis"
+
+config AD5930
+	tristate "Analog Devices ad5930/5932 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices DDS chip
+	  ad5930/ad5932, provides direct access via sysfs.
+
+config AD9832
+	tristate "Analog Devices ad9832/3/4/5 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices DDS chip
+	  ad9832/3/4/5, provides direct access via sysfs.
+
+config AD9850
+	tristate "Analog Devices ad9850/1 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices DDS chip
+	  ad9850/1, provides direct access via sysfs.
+
+config AD9852
+	tristate "Analog Devices ad9852/4 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices DDS chip
+	  ad9852/4, provides direct access via sysfs.
+
+config AD9910
+	tristate "Analog Devices ad9910 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices DDS chip
+	  ad9910, provides direct access via sysfs.
+
+config AD9951
+	tristate "Analog Devices ad9951 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices DDS chip
+	  ad9951, provides direct access via sysfs.
diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile
new file mode 100644
index 0000000..6f274ac
--- /dev/null
+++ b/drivers/staging/iio/dds/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for Direct Digital Synthesis drivers
+#
+
+obj-$(CONFIG_AD5930) += ad5930.o
+obj-$(CONFIG_AD9832) += ad9832.o
+obj-$(CONFIG_AD9850) += ad9850.o
+obj-$(CONFIG_AD9852) += ad9852.o
+obj-$(CONFIG_AD9910) += ad9910.o
+obj-$(CONFIG_AD9951) += ad9951.o
diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c
new file mode 100644
index 0000000..f80039c
--- /dev/null
+++ b/drivers/staging/iio/dds/ad5930.c
@@ -0,0 +1,170 @@
+/*
+ * Driver for ADI Direct Digital Synthesis ad5930
+ *
+ * Copyright (c) 2010-2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad5930"
+
+#define value_mask (u16)0xf000
+#define addr_shift 12
+
+/* Register format: 4 bits addr + 12 bits value */
+struct ad5903_config {
+	u16 control;
+	u16 incnum;
+	u16 frqdelt[2];
+	u16 incitvl;
+	u16 buritvl;
+	u16 strtfrq[2];
+};
+
+struct ad5930_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+};
+
+static ssize_t ad5930_set_parameter(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	struct ad5903_config *config = (struct ad5903_config *)buf;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad5930_state *st = idev->dev_data;
+
+	config->control = (config->control & ~value_mask);
+	config->incnum = (config->control & ~value_mask) | (1 << addr_shift);
+	config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift);
+	config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift;
+	config->incitvl = (config->control & ~value_mask) | 4 << addr_shift;
+	config->buritvl = (config->control & ~value_mask) | 8 << addr_shift;
+	config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift;
+	config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift;
+
+	xfer.len = len;
+	xfer.tx_buf = config;
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad5930_set_parameter, 0);
+
+static struct attribute *ad5930_attributes[] = {
+	&iio_dev_attr_dds.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad5930_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad5930_attributes,
+};
+
+static int __devinit ad5930_probe(struct spi_device *spi)
+{
+	struct ad5930_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad5930_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+	spi->max_speed_hz = 2000000;
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 16;
+	spi_setup(spi);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad5930_remove(struct spi_device *spi)
+{
+	struct ad5930_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad5930_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad5930_probe,
+	.remove = __devexit_p(ad5930_remove),
+};
+
+static __init int ad5930_spi_init(void)
+{
+	return spi_register_driver(&ad5930_driver);
+}
+module_init(ad5930_spi_init);
+
+static __exit void ad5930_spi_exit(void)
+{
+	spi_unregister_driver(&ad5930_driver);
+}
+module_exit(ad5930_spi_exit);
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION("Analog Devices ad5930 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c
new file mode 100644
index 0000000..a4bb0482
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9832.c
@@ -0,0 +1,266 @@
+/*
+ * Driver for ADI Direct Digital Synthesis ad9832
+ *
+ * Copyright (c) 2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad9832"
+
+#define value_mask (u16)0xf000
+#define cmd_shift 12
+#define add_shift 8
+#define AD9832_SYNC (1 << 13)
+#define AD9832_SELSRC (1 << 12)
+#define AD9832_SLEEP (1 << 13)
+#define AD9832_RESET (1 << 12)
+#define AD9832_CLR (1 << 11)
+
+#define ADD_FREQ0LL 0x0
+#define ADD_FREQ0HL 0x1
+#define ADD_FREQ0LM 0x2
+#define ADD_FREQ0HM 0x3
+#define ADD_FREQ1LL 0x4
+#define ADD_FREQ1HL 0x5
+#define ADD_FREQ1LM 0x6
+#define ADD_FREQ1HM 0x7
+#define ADD_PHASE0L 0x8
+#define ADD_PHASE0H 0x9
+#define ADD_PHASE1L 0xa
+#define ADD_PHASE1H 0xb
+#define ADD_PHASE2L 0xc
+#define ADD_PHASE2H 0xd
+#define ADD_PHASE3L 0xe
+#define ADD_PHASE3H 0xf
+
+#define CMD_PHA8BITSW 0x1
+#define CMD_PHA16BITSW 0x0
+#define CMD_FRE8BITSW 0x3
+#define CMD_FRE16BITSW 0x2
+#define CMD_SELBITSCTL 0x6
+
+struct ad9832_setting {
+	u16 freq0[4];
+	u16 freq1[4];
+	u16 phase0[2];
+	u16 phase1[2];
+	u16 phase2[2];
+	u16 phase3[2];
+};
+
+struct ad9832_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+};
+
+static ssize_t ad9832_set_parameter(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	struct ad9832_setting config;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad9832_state *st = idev->dev_data;
+
+	config.freq0[0] = (CMD_FRE8BITSW << add_shift | ADD_FREQ0LL << add_shift | buf[0]);
+	config.freq0[1] = (CMD_FRE16BITSW << add_shift | ADD_FREQ0HL << add_shift | buf[1]);
+	config.freq0[2] = (CMD_FRE8BITSW << add_shift | ADD_FREQ0LM << add_shift | buf[2]);
+	config.freq0[3] = (CMD_FRE16BITSW << add_shift | ADD_FREQ0HM << add_shift | buf[3]);
+	config.freq1[0] = (CMD_FRE8BITSW << add_shift | ADD_FREQ1LL << add_shift | buf[4]);
+	config.freq1[1] = (CMD_FRE16BITSW << add_shift | ADD_FREQ1HL << add_shift | buf[5]);
+	config.freq1[2] = (CMD_FRE8BITSW << add_shift | ADD_FREQ1LM << add_shift | buf[6]);
+	config.freq1[3] = (CMD_FRE16BITSW << add_shift | ADD_FREQ1HM << add_shift | buf[7]);
+
+	config.phase0[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE0L << add_shift | buf[9]);
+	config.phase0[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE0H << add_shift | buf[10]);
+	config.phase1[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE1L << add_shift | buf[11]);
+	config.phase1[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE1H << add_shift | buf[12]);
+	config.phase2[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE2L << add_shift | buf[13]);
+	config.phase2[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE2H << add_shift | buf[14]);
+	config.phase3[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE3L << add_shift | buf[15]);
+	config.phase3[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE3H << add_shift | buf[16]);
+
+	xfer.len = 2 * len;
+	xfer.tx_buf = &config;
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9832_set_parameter, 0);
+
+static struct attribute *ad9832_attributes[] = {
+	&iio_dev_attr_dds.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad9832_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad9832_attributes,
+};
+
+static void ad9832_init(struct ad9832_state *st)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	u16 config = 0;
+
+	config = 0x3 << 14 | AD9832_SLEEP | AD9832_RESET | AD9832_CLR;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 2;
+	xfer.tx_buf = &config;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	config = 0x2 << 14 | AD9832_SYNC | AD9832_SELSRC;
+	xfer.len = 2;
+	xfer.tx_buf = &config;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	config = CMD_SELBITSCTL << cmd_shift;
+	xfer.len = 2;
+	xfer.tx_buf = &config;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	config = 0x3 << 14;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 2;
+	xfer.tx_buf = &config;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+
+
+}
+
+static int __devinit ad9832_probe(struct spi_device *spi)
+{
+	struct ad9832_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad9832_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+	spi->max_speed_hz = 2000000;
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 16;
+	spi_setup(spi);
+	ad9832_init(st);
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad9832_remove(struct spi_device *spi)
+{
+	struct ad9832_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad9832_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad9832_probe,
+	.remove = __devexit_p(ad9832_remove),
+};
+
+static __init int ad9832_spi_init(void)
+{
+	return spi_register_driver(&ad9832_driver);
+}
+module_init(ad9832_spi_init);
+
+static __exit void ad9832_spi_exit(void)
+{
+	spi_unregister_driver(&ad9832_driver);
+}
+module_exit(ad9832_spi_exit);
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION("Analog Devices ad9832 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c
new file mode 100644
index 0000000..b259bfe
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9850.c
@@ -0,0 +1,156 @@
+/*
+ * Driver for ADI Direct Digital Synthesis ad9850
+ *
+ * Copyright (c) 2010-2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad9850"
+
+#define value_mask (u16)0xf000
+#define addr_shift 12
+
+/* Register format: 4 bits addr + 12 bits value */
+struct ad9850_config {
+	u8 control[5];
+};
+
+struct ad9850_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+};
+
+static ssize_t ad9850_set_parameter(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	struct ad9850_config *config = (struct ad9850_config *)buf;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad9850_state *st = idev->dev_data;
+
+	xfer.len = len;
+	xfer.tx_buf = config;
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9850_set_parameter, 0);
+
+static struct attribute *ad9850_attributes[] = {
+	&iio_dev_attr_dds.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad9850_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad9850_attributes,
+};
+
+static int __devinit ad9850_probe(struct spi_device *spi)
+{
+	struct ad9850_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad9850_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+	spi->max_speed_hz = 2000000;
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 16;
+	spi_setup(spi);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad9850_remove(struct spi_device *spi)
+{
+	struct ad9850_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad9850_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad9850_probe,
+	.remove = __devexit_p(ad9850_remove),
+};
+
+static __init int ad9850_spi_init(void)
+{
+	return spi_register_driver(&ad9850_driver);
+}
+module_init(ad9850_spi_init);
+
+static __exit void ad9850_spi_exit(void)
+{
+	spi_unregister_driver(&ad9850_driver);
+}
+module_exit(ad9850_spi_exit);
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION("Analog Devices ad9850 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c
new file mode 100644
index 0000000..0a41d25
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9852.c
@@ -0,0 +1,314 @@
+/*
+ * Driver for ADI Direct Digital Synthesis ad9852
+ *
+ * Copyright (c) 2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad9852"
+
+#define addr_phaad1 0x0
+#define addr_phaad2 0x1
+#define addr_fretu1 0x2
+#define addr_fretu2 0x3
+#define addr_delfre 0x4
+#define addr_updclk 0x5
+#define addr_ramclk 0x6
+#define addr_contrl 0x7
+#define addr_optskm 0x8
+#define addr_optskr 0xa
+#define addr_dacctl 0xb
+
+#define COMPPD		(1 << 4)
+#define REFMULT2	(1 << 2)
+#define BYPPLL		(1 << 5)
+#define PLLRANG		(1 << 6)
+#define IEUPCLK		(1)
+#define OSKEN		(1 << 5)
+
+#define read_bit	(1 << 7)
+
+/* Register format: 1 byte addr + value */
+struct ad9852_config {
+	u8 phajst0[3];
+	u8 phajst1[3];
+	u8 fretun1[6];
+	u8 fretun2[6];
+	u8 dltafre[6];
+	u8 updtclk[5];
+	u8 ramprat[4];
+	u8 control[5];
+	u8 outpskm[3];
+	u8 outpskr[2];
+	u8 daccntl[3];
+};
+
+struct ad9852_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+};
+
+static ssize_t ad9852_set_parameter(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	struct ad9852_config *config = (struct ad9852_config *)buf;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad9852_state *st = idev->dev_data;
+
+	xfer.len = 3;
+	xfer.tx_buf = &config->phajst0[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 3;
+	xfer.tx_buf = &config->phajst1[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 6;
+	xfer.tx_buf = &config->fretun1[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 6;
+	xfer.tx_buf = &config->fretun2[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 6;
+	xfer.tx_buf = &config->dltafre[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->updtclk[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 4;
+	xfer.tx_buf = &config->ramprat[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->control[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 3;
+	xfer.tx_buf = &config->outpskm[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 2;
+	xfer.tx_buf = &config->outpskr[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 3;
+	xfer.tx_buf = &config->daccntl[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0);
+
+static void ad9852_init(struct ad9852_state *st)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	u8 config[5];
+
+	config[0] = addr_contrl;
+	config[1] = COMPPD;
+	config[2] = REFMULT2 | BYPPLL | PLLRANG;
+	config[3] = IEUPCLK;
+	config[4] = OSKEN;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 5;
+	xfer.tx_buf = &config;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+
+
+}
+
+static struct attribute *ad9852_attributes[] = {
+	&iio_dev_attr_dds.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad9852_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad9852_attributes,
+};
+
+static int __devinit ad9852_probe(struct spi_device *spi)
+{
+	struct ad9852_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad9852_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+	spi->max_speed_hz = 2000000;
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+	ad9852_init(st);
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad9852_remove(struct spi_device *spi)
+{
+	struct ad9852_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad9852_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad9852_probe,
+	.remove = __devexit_p(ad9852_remove),
+};
+
+static __init int ad9852_spi_init(void)
+{
+	return spi_register_driver(&ad9852_driver);
+}
+module_init(ad9852_spi_init);
+
+static __exit void ad9852_spi_exit(void)
+{
+	spi_unregister_driver(&ad9852_driver);
+}
+module_exit(ad9852_spi_exit);
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION("Analog Devices ad9852 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c
new file mode 100644
index 0000000..c59b4079
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9910.c
@@ -0,0 +1,454 @@
+/*
+ * Driver for ADI Direct Digital Synthesis ad9910
+ *
+ * Copyright (c) 2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad9910"
+
+#define CFR1 0x0
+#define CFR2 0x1
+#define CFR3 0x2
+
+#define AUXDAC 0x3
+#define IOUPD 0x4
+#define FTW 0x7
+#define POW 0x8
+#define ASF 0x9
+#define MULTC 0x0A
+#define DIG_RAMPL 0x0B
+#define DIG_RAMPS 0x0C
+#define DIG_RAMPR 0x0D
+#define SIN_TONEP0 0x0E
+#define SIN_TONEP1 0x0F
+#define SIN_TONEP2 0x10
+#define SIN_TONEP3 0x11
+#define SIN_TONEP4 0x12
+#define SIN_TONEP5 0x13
+#define SIN_TONEP6 0x14
+#define SIN_TONEP7 0x15
+
+#define RAM_ENABLE	(1 << 7)
+
+#define MANUAL_OSK	(1 << 7)
+#define INVSIC		(1 << 6)
+#define DDS_SINEOP	(1)
+
+#define AUTO_OSK	(1)
+#define OSKEN		(1 << 1)
+#define LOAD_ARR	(1 << 2)
+#define CLR_PHA		(1 << 3)
+#define CLR_DIG		(1 << 4)
+#define ACLR_PHA	(1 << 5)
+#define ACLR_DIG	(1 << 6)
+#define LOAD_LRR	(1 << 7)
+
+#define LSB_FST		(1)
+#define SDIO_IPT	(1 << 1)
+#define EXT_PWD		(1 << 3)
+#define ADAC_PWD	(1 << 4)
+#define REFCLK_PWD	(1 << 5)
+#define DAC_PWD		(1 << 6)
+#define DIG_PWD		(1 << 7)
+
+#define ENA_AMP		(1)
+#define READ_FTW	(1)
+#define DIGR_LOW	(1 << 1)
+#define DIGR_HIGH	(1 << 2)
+#define DIGR_ENA	(1 << 3)
+#define SYNCCLK_ENA	(1 << 6)
+#define ITER_IOUPD	(1 << 7)
+
+#define TX_ENA		(1 << 1)
+#define PDCLK_INV	(1 << 2)
+#define PDCLK_ENB	(1 << 3)
+
+#define PARA_ENA	(1 << 4)
+#define SYNC_DIS	(1 << 5)
+#define DATA_ASS	(1 << 6)
+#define MATCH_ENA	(1 << 7)
+
+#define PLL_ENA		(1)
+#define PFD_RST		(1 << 2)
+#define REFCLK_RST	(1 << 6)
+#define REFCLK_BYP	(1 << 7)
+
+/* Register format: 1 byte addr + value */
+struct ad9910_config {
+	u8 auxdac[5];
+	u8 ioupd[5];
+	u8 ftw[5];
+	u8 pow[3];
+	u8 asf[5];
+	u8 multc[5];
+	u8 dig_rampl[9];
+	u8 dig_ramps[9];
+	u8 dig_rampr[5];
+	u8 sin_tonep0[9];
+	u8 sin_tonep1[9];
+	u8 sin_tonep2[9];
+	u8 sin_tonep3[9];
+	u8 sin_tonep4[9];
+	u8 sin_tonep5[9];
+	u8 sin_tonep6[9];
+	u8 sin_tonep7[9];
+};
+
+struct ad9910_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+};
+
+static ssize_t ad9910_set_parameter(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	struct ad9910_config *config = (struct ad9910_config *)buf;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad9910_state *st = idev->dev_data;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->auxdac[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->ioupd[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->ftw[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 3;
+	xfer.tx_buf = &config->pow[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->asf[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->multc[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 9;
+	xfer.tx_buf = &config->dig_rampl[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 9;
+	xfer.tx_buf = &config->dig_ramps[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->dig_rampr[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep0[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep1[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep2[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep3[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep4[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep5[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep6[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	xfer.len = 9;
+	xfer.tx_buf = &config->sin_tonep7[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
+
+static void ad9910_init(struct ad9910_state *st)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	u8 cfr[5];
+
+	cfr[0] = CFR1;
+	cfr[1] = 0;
+	cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP;
+	cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR;
+	cfr[4] = 0;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 5;
+	xfer.tx_buf = &cfr;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	cfr[0] = CFR2;
+	cfr[1] = ENA_AMP;
+	cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD;
+	cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB;
+	cfr[4] = PARA_ENA;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 5;
+	xfer.tx_buf = &cfr;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	cfr[0] = CFR3;
+	cfr[1] = PLL_ENA;
+	cfr[2] = 0;
+	cfr[3] = REFCLK_RST | REFCLK_BYP;
+	cfr[4] = 0;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 5;
+	xfer.tx_buf = &cfr;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+
+
+}
+
+static struct attribute *ad9910_attributes[] = {
+	&iio_dev_attr_dds.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad9910_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad9910_attributes,
+};
+
+static int __devinit ad9910_probe(struct spi_device *spi)
+{
+	struct ad9910_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad9910_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+	spi->max_speed_hz = 2000000;
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+	ad9910_init(st);
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad9910_remove(struct spi_device *spi)
+{
+	struct ad9910_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad9910_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad9910_probe,
+	.remove = __devexit_p(ad9910_remove),
+};
+
+static __init int ad9910_spi_init(void)
+{
+	return spi_register_driver(&ad9910_driver);
+}
+module_init(ad9910_spi_init);
+
+static __exit void ad9910_spi_exit(void)
+{
+	spi_unregister_driver(&ad9910_driver);
+}
+module_exit(ad9910_spi_exit);
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION("Analog Devices ad9910 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c
new file mode 100644
index 0000000..bc3beff
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9951.c
@@ -0,0 +1,254 @@
+/*
+ * Driver for ADI Direct Digital Synthesis ad9951
+ *
+ * Copyright (c) 2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad9951"
+
+#define CFR1 0x0
+#define CFR2 0x1
+
+#define AUTO_OSK	(1)
+#define OSKEN		(1 << 1)
+#define LOAD_ARR	(1 << 2)
+
+#define AUTO_SYNC	(1 << 7)
+
+#define LSB_FST		(1)
+#define SDIO_IPT	(1 << 1)
+#define CLR_PHA		(1 << 2)
+#define SINE_OPT	(1 << 4)
+#define ACLR_PHA	(1 << 5)
+
+#define VCO_RANGE	(1 << 2)
+
+#define CRS_OPT		(1 << 1)
+#define HMANU_SYNC	(1 << 2)
+#define HSPD_SYNC	(1 << 3)
+
+/* Register format: 1 byte addr + value */
+struct ad9951_config {
+	u8 asf[3];
+	u8 arr[2];
+	u8 ftw0[5];
+	u8 ftw1[3];
+};
+
+struct ad9951_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+};
+
+static ssize_t ad9951_set_parameter(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	struct ad9951_config *config = (struct ad9951_config *)buf;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad9951_state *st = idev->dev_data;
+
+	xfer.len = 3;
+	xfer.tx_buf = &config->asf[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 2;
+	xfer.tx_buf = &config->arr[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 5;
+	xfer.tx_buf = &config->ftw0[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	xfer.len = 3;
+	xfer.tx_buf = &config->ftw1[0];
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
+
+static void ad9951_init(struct ad9951_state *st)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	u8 cfr[5];
+
+	cfr[0] = CFR1;
+	cfr[1] = 0;
+	cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA;
+	cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR;
+	cfr[4] = 0;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 5;
+	xfer.tx_buf = &cfr;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+	cfr[0] = CFR2;
+	cfr[1] = VCO_RANGE;
+	cfr[2] = HSPD_SYNC;
+	cfr[3] = 0;
+
+	mutex_lock(&st->lock);
+
+	xfer.len = 4;
+	xfer.tx_buf = &cfr;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+
+
+}
+
+static struct attribute *ad9951_attributes[] = {
+	&iio_dev_attr_dds.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad9951_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad9951_attributes,
+};
+
+static int __devinit ad9951_probe(struct spi_device *spi)
+{
+	struct ad9951_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad9951_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+	spi->max_speed_hz = 2000000;
+	spi->mode = SPI_MODE_3;
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+	ad9951_init(st);
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad9951_remove(struct spi_device *spi)
+{
+	struct ad9951_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad9951_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad9951_probe,
+	.remove = __devexit_p(ad9951_remove),
+};
+
+static __init int ad9951_spi_init(void)
+{
+	return spi_register_driver(&ad9951_driver);
+}
+module_init(ad9951_spi_init);
+
+static __exit void ad9951_spi_exit(void)
+{
+	spi_unregister_driver(&ad9951_driver);
+}
+module_exit(ad9951_spi_exit);
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION("Analog Devices ad9951 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig
index c404361..236f15f 100644
--- a/drivers/staging/iio/gyro/Kconfig
+++ b/drivers/staging/iio/gyro/Kconfig
@@ -3,11 +3,45 @@
 #
 comment "Digital gyroscope sensors"
 
+config ADIS16060
+	tristate "Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices adis16060 wide bandwidth
+	  yaw rate gyroscope with SPI.
+
+config ADIS16080
+	tristate "Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices adis16080/100 Yaw Rate
+	  Gyroscope with SPI.
+
+config ADIS16130
+	tristate "Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADIS16130 High Precision
+	  Angular Rate Sensor driver.
+
 config ADIS16260
-	tristate "Analog Devices ADIS16260/5 Digital Gyroscope Sensor SPI driver"
+	tristate "Analog Devices ADIS16260 ADIS16265 Digital Gyroscope Sensor SPI driver"
 	depends on SPI
 	select IIO_TRIGGER if IIO_RING_BUFFER
 	select IIO_SW_RING if IIO_RING_BUFFER
 	help
-	  Say yes here to build support for Analog Devices adis16260/5
+	  Say yes here to build support for Analog Devices ADIS16260 ADIS16265
 	  programmable digital gyroscope sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adis16260.
+
+config ADIS16251
+	tristate "Analog Devices ADIS16251 Digital Gyroscope Sensor SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices adis16261 programmable
+	  digital gyroscope sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adis16251.
diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile
index b5f0dc0..2764c15 100644
--- a/drivers/staging/iio/gyro/Makefile
+++ b/drivers/staging/iio/gyro/Makefile
@@ -2,6 +2,18 @@
 # Makefile for digital gyroscope sensor drivers
 #
 
+adis16060-y             := adis16060_core.o
+obj-$(CONFIG_ADIS16060) += adis16060.o
+
+adis16080-y             := adis16080_core.o
+obj-$(CONFIG_ADIS16080) += adis16080.o
+
+adis16130-y             := adis16130_core.o
+obj-$(CONFIG_ADIS16130) += adis16130.o
+
 adis16260-y             := adis16260_core.o
 adis16260-$(CONFIG_IIO_RING_BUFFER) += adis16260_ring.o adis16260_trigger.o
 obj-$(CONFIG_ADIS16260) += adis16260.o
+
+adis16251-y             := adis16251_core.o
+obj-$(CONFIG_ADIS16251) += adis16251.o
diff --git a/drivers/staging/iio/gyro/adis16060.h b/drivers/staging/iio/gyro/adis16060.h
new file mode 100644
index 0000000..5c00e53
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16060.h
@@ -0,0 +1,101 @@
+#ifndef SPI_ADIS16060_H_
+#define SPI_ADIS16060_H_
+
+#define ADIS16060_GYRO       0x20 /* Measure Angular Rate (Gyro) */
+#define ADIS16060_SUPPLY_OUT 0x10 /* Measure Temperature */
+#define ADIS16060_AIN2       0x80 /* Measure AIN2 */
+#define ADIS16060_AIN1       0x40 /* Measure AIN1 */
+#define ADIS16060_TEMP_OUT   0x22 /* Set Positive Self-Test and Output for Angular Rate */
+#define ADIS16060_ANGL_OUT   0x21 /* Set Negative Self-Test and Output for Angular Rate */
+
+#define ADIS16060_MAX_TX     3
+#define ADIS16060_MAX_RX     3
+
+/**
+ * struct adis16060_state - device instance specific data
+ * @us_w:			actual spi_device to write data
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16060_state {
+	struct spi_device		*us_w;
+	struct spi_device		*us_r;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum adis16060_scan {
+	ADIS16060_SCAN_GYRO,
+	ADIS16060_SCAN_TEMP,
+	ADIS16060_SCAN_ADC_1,
+	ADIS16060_SCAN_ADC_2,
+};
+
+void adis16060_remove_trigger(struct iio_dev *indio_dev);
+int adis16060_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16060_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+
+int adis16060_configure_ring(struct iio_dev *indio_dev);
+void adis16060_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16060_initialize_ring(struct iio_ring_buffer *ring);
+void adis16060_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16060_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16060_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16060_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16060_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16060_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16060_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16060_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16060_H_ */
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
new file mode 100644
index 0000000..fc48aca
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -0,0 +1,319 @@
+/*
+ * ADIS16060 Wide Bandwidth Yaw Rate Gyroscope with SPI driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16060.h"
+
+#define DRIVER_NAME		"adis16060"
+
+struct adis16060_state *adis16060_st;
+
+int adis16060_spi_write(struct device *dev,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16060_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = 0;
+	st->tx[1] = 0;
+	st->tx[2] = val; /* The last 8 bits clocked in are latched */
+
+	ret = spi_write(st->us_w, st->tx, 3);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+int adis16060_spi_read(struct device *dev,
+		u16 *val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16060_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+
+	ret = spi_read(st->us_r, st->rx, 3);
+
+	/* The internal successive approximation ADC begins the conversion process
+	 * on the falling edge of MSEL1 and starts to place data MSB first on the
+	 * DOUT line at the 6th falling edge of SCLK
+	 */
+	if (ret == 0)
+		*val = ((st->rx[0] & 0x3) << 12) | (st->rx[1] << 4) | ((st->rx[2] >> 4) & 0xF);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static ssize_t adis16060_read(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	u16 val;
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	ret =  adis16060_spi_read(dev, &val);
+	mutex_unlock(&indio_dev->mlock);
+
+	if (ret == 0)
+		return sprintf(buf, "%d\n", val);
+	else
+		return ret;
+}
+
+static ssize_t adis16060_write(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 16, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16060_spi_write(dev, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+#define IIO_DEV_ATTR_IN(_show)				\
+	IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0)
+
+#define IIO_DEV_ATTR_OUT(_store)				\
+	IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0)
+
+static IIO_DEV_ATTR_IN(adis16060_read);
+static IIO_DEV_ATTR_OUT(adis16060_write);
+
+static IIO_CONST_ATTR(name, "adis16060");
+
+static struct attribute *adis16060_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16060_event_attribute_group = {
+	.attrs = adis16060_event_attributes,
+};
+
+static struct attribute *adis16060_attributes[] = {
+	&iio_dev_attr_in.dev_attr.attr,
+	&iio_dev_attr_out.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16060_attribute_group = {
+	.attrs = adis16060_attributes,
+};
+
+static int __devinit adis16060_r_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16060_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16060_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16060_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us_r = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16060_event_attribute_group;
+	st->indio_dev->attrs = &adis16060_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16060_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16060_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16060");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16060_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	adis16060_st = st;
+	return 0;
+
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16060_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16060_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int adis16060_r_remove(struct spi_device *spi)
+{
+	struct adis16060_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	adis16060_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16060_uninitialize_ring(indio_dev->ring);
+	adis16060_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static int __devinit adis16060_w_probe(struct spi_device *spi)
+{
+	int ret;
+	struct adis16060_state *st = adis16060_st;
+	if (!st) {
+		ret =  -ENODEV;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+	st->us_w = spi;
+	return 0;
+
+error_ret:
+	return ret;
+}
+
+static int adis16060_w_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+static struct spi_driver adis16060_r_driver = {
+	.driver = {
+		.name = "adis16060_r",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16060_r_probe,
+	.remove = __devexit_p(adis16060_r_remove),
+};
+
+static struct spi_driver adis16060_w_driver = {
+	.driver = {
+		.name = "adis16060_w",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16060_w_probe,
+	.remove = __devexit_p(adis16060_w_remove),
+};
+
+static __init int adis16060_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&adis16060_r_driver);
+	if (ret < 0)
+		return ret;
+
+	ret = spi_register_driver(&adis16060_w_driver);
+	if (ret < 0) {
+		spi_unregister_driver(&adis16060_r_driver);
+		return ret;
+	}
+
+	return 0;
+}
+module_init(adis16060_init);
+
+static __exit void adis16060_exit(void)
+{
+	spi_unregister_driver(&adis16060_w_driver);
+	spi_unregister_driver(&adis16060_r_driver);
+}
+module_exit(adis16060_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/adis16080.h b/drivers/staging/iio/gyro/adis16080.h
new file mode 100644
index 0000000..3fcbe67
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16080.h
@@ -0,0 +1,102 @@
+#ifndef SPI_ADIS16080_H_
+#define SPI_ADIS16080_H_
+
+#define ADIS16080_DIN_CODE   4 /* Output data format setting. 0: Twos complement. 1: Offset binary. */
+#define ADIS16080_DIN_GYRO   (0 << 10) /* Gyroscope output */
+#define ADIS16080_DIN_TEMP   (1 << 10) /* Temperature output */
+#define ADIS16080_DIN_AIN1   (2 << 10)
+#define ADIS16080_DIN_AIN2   (3 << 10)
+#define ADIS16080_DIN_WRITE  (1 << 15) /* 1: Write contents on DIN to control register.
+					* 0: No changes to control register.
+					*/
+
+#define ADIS16080_MAX_TX     2
+#define ADIS16080_MAX_RX     2
+
+/**
+ * struct adis16080_state - device instance specific data
+ * @us:			actual spi_device to write data
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16080_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum adis16080_scan {
+	ADIS16080_SCAN_GYRO,
+	ADIS16080_SCAN_TEMP,
+	ADIS16080_SCAN_ADC_1,
+	ADIS16080_SCAN_ADC_2,
+};
+
+void adis16080_remove_trigger(struct iio_dev *indio_dev);
+int adis16080_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16080_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+
+int adis16080_configure_ring(struct iio_dev *indio_dev);
+void adis16080_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16080_initialize_ring(struct iio_ring_buffer *ring);
+void adis16080_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16080_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16080_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16080_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16080_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16080_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16080_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16080_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16080_H_ */
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
new file mode 100644
index 0000000..0efb768
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -0,0 +1,271 @@
+/*
+ * ADIS16080/100 Yaw Rate Gyroscope with SPI driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16080.h"
+
+#define DRIVER_NAME		"adis16080"
+
+struct adis16080_state *adis16080_st;
+
+int adis16080_spi_write(struct device *dev,
+		u16 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16080_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = val >> 8;
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+int adis16080_spi_read(struct device *dev,
+		u16 *val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16080_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+
+	ret = spi_read(st->us, st->rx, 2);
+
+	if (ret == 0)
+		*val = ((st->rx[0] & 0xF) << 8) | st->rx[1];
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static ssize_t adis16080_read(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	u16 val;
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	ret =  adis16080_spi_read(dev, &val);
+	mutex_unlock(&indio_dev->mlock);
+
+	if (ret == 0)
+		return sprintf(buf, "%d\n", val);
+	else
+		return ret;
+}
+
+static ssize_t adis16080_write(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 16, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16080_spi_write(dev, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+#define IIO_DEV_ATTR_IN(_show)				\
+	IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0)
+
+#define IIO_DEV_ATTR_OUT(_store)				\
+	IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0)
+
+static IIO_DEV_ATTR_IN(adis16080_read);
+static IIO_DEV_ATTR_OUT(adis16080_write);
+
+static IIO_CONST_ATTR(name, "adis16080");
+
+static struct attribute *adis16080_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16080_event_attribute_group = {
+	.attrs = adis16080_event_attributes,
+};
+
+static struct attribute *adis16080_attributes[] = {
+	&iio_dev_attr_in.dev_attr.attr,
+	&iio_dev_attr_out.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16080_attribute_group = {
+	.attrs = adis16080_attributes,
+};
+
+static int __devinit adis16080_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16080_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16080_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16080_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16080_event_attribute_group;
+	st->indio_dev->attrs = &adis16080_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16080_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16080_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16080");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16080_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	adis16080_st = st;
+	return 0;
+
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16080_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16080_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int adis16080_remove(struct spi_device *spi)
+{
+	struct adis16080_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	adis16080_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16080_uninitialize_ring(indio_dev->ring);
+	adis16080_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver adis16080_driver = {
+	.driver = {
+		.name = "adis16080",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16080_probe,
+	.remove = __devexit_p(adis16080_remove),
+};
+
+static __init int adis16080_init(void)
+{
+	return spi_register_driver(&adis16080_driver);
+}
+module_init(adis16080_init);
+
+static __exit void adis16080_exit(void)
+{
+	spi_unregister_driver(&adis16080_driver);
+}
+module_exit(adis16080_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/adis16130.h b/drivers/staging/iio/gyro/adis16130.h
new file mode 100644
index 0000000..ab80ef6
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16130.h
@@ -0,0 +1,108 @@
+#ifndef SPI_ADIS16130_H_
+#define SPI_ADIS16130_H_
+
+#define ADIS16130_CON         0x0
+#define ADIS16130_CON_RD      (1 << 6)
+#define ADIS16130_IOP         0x1
+#define ADIS16130_IOP_ALL_RDY (1 << 3) /* 1 = data-ready signal low when unread data on all channels; */
+#define ADIS16130_IOP_SYNC    (1 << 0) /* 1 = synchronization enabled */
+#define ADIS16130_RATEDATA    0x8 /* Gyroscope output, rate of rotation */
+#define ADIS16130_TEMPDATA    0xA /* Temperature output */
+#define ADIS16130_RATECS      0x28 /* Gyroscope channel setup */
+#define ADIS16130_RATECS_EN   (1 << 3) /* 1 = channel enable; */
+#define ADIS16130_TEMPCS      0x2A /* Temperature channel setup */
+#define ADIS16130_TEMPCS_EN   (1 << 3)
+#define ADIS16130_RATECONV    0x30
+#define ADIS16130_TEMPCONV    0x32
+#define ADIS16130_MODE        0x38
+#define ADIS16130_MODE_24BIT  (1 << 1) /* 1 = 24-bit resolution; */
+
+#define ADIS16130_MAX_TX     4
+#define ADIS16130_MAX_RX     4
+
+/**
+ * struct adis16130_state - device instance specific data
+ * @us:			actual spi_device to write data
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16130_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	u32                             mode; /* 1: 24bits mode 0:16bits mode */
+	struct mutex			buf_lock;
+};
+
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum adis16130_scan {
+	ADIS16130_SCAN_GYRO,
+	ADIS16130_SCAN_TEMP,
+};
+
+void adis16130_remove_trigger(struct iio_dev *indio_dev);
+int adis16130_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16130_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+
+int adis16130_configure_ring(struct iio_dev *indio_dev);
+void adis16130_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16130_initialize_ring(struct iio_ring_buffer *ring);
+void adis16130_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16130_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16130_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16130_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16130_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16130_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16130_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16130_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16130_H_ */
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c
new file mode 100644
index 0000000..49ffc7b
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16130_core.c
@@ -0,0 +1,313 @@
+/*
+ * ADIS16130 Digital Output, High Precision Angular Rate Sensor driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16130.h"
+
+#define DRIVER_NAME		"adis16130"
+
+struct adis16130_state *adis16130_st;
+
+int adis16130_spi_write(struct device *dev, u8 reg_addr,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16130_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = reg_addr;
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+int adis16130_spi_read(struct device *dev, u8 reg_addr,
+		u32 *val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16130_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+
+	st->tx[0] = ADIS16130_CON_RD | reg_addr;
+	if (st->mode)
+		ret = spi_read(st->us, st->rx, 4);
+	else
+		ret = spi_read(st->us, st->rx, 3);
+
+	if (ret == 0) {
+		if (st->mode)
+			*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+		else
+			*val = (st->rx[1] << 8) | st->rx[2];
+	}
+
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static ssize_t adis16130_gyro_read(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	u32 val;
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	ret =  adis16130_spi_read(dev, ADIS16130_RATEDATA, &val);
+	mutex_unlock(&indio_dev->mlock);
+
+	if (ret == 0)
+		return sprintf(buf, "%d\n", val);
+	else
+		return ret;
+}
+
+static ssize_t adis16130_temp_read(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	u32 val;
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	ret =  adis16130_spi_read(dev, ADIS16130_TEMPDATA, &val);
+	mutex_unlock(&indio_dev->mlock);
+
+	if (ret == 0)
+		return sprintf(buf, "%d\n", val);
+	else
+		return ret;
+}
+
+static ssize_t adis16130_bitsmode_read(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16130_state *st = iio_dev_get_devdata(indio_dev);
+
+	return sprintf(buf, "%d\n", st->mode);
+}
+
+static ssize_t adis16130_bitsmode_write(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 16, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16130_spi_write(dev, ADIS16130_MODE, !!val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_TEMP_RAW(adis16130_temp_read);
+
+static IIO_CONST_ATTR(name, "adis16130");
+
+static IIO_DEV_ATTR_GYRO(adis16130_gyro_read,
+		ADIS16130_RATEDATA);
+
+#define IIO_DEV_ATTR_BITS_MODE(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(bits_mode, _mode, _show, _store, _addr)
+
+static IIO_DEV_ATTR_BITS_MODE(S_IWUSR | S_IRUGO, adis16130_bitsmode_read, adis16130_bitsmode_write,
+			ADIS16130_MODE);
+
+static struct attribute *adis16130_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16130_event_attribute_group = {
+	.attrs = adis16130_event_attributes,
+};
+
+static struct attribute *adis16130_attributes[] = {
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_gyro_raw.dev_attr.attr,
+	&iio_dev_attr_bits_mode.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16130_attribute_group = {
+	.attrs = adis16130_attributes,
+};
+
+static int __devinit adis16130_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16130_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16130_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16130_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16130_event_attribute_group;
+	st->indio_dev->attrs = &adis16130_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	st->mode = 1;
+
+	ret = adis16130_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16130_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16130");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16130_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	adis16130_st = st;
+	return 0;
+
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16130_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16130_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int adis16130_remove(struct spi_device *spi)
+{
+	struct adis16130_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	adis16130_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16130_uninitialize_ring(indio_dev->ring);
+	adis16130_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver adis16130_driver = {
+	.driver = {
+		.name = "adis16130",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16130_probe,
+	.remove = __devexit_p(adis16130_remove),
+};
+
+static __init int adis16130_init(void)
+{
+	return spi_register_driver(&adis16130_driver);
+}
+module_init(adis16130_init);
+
+static __exit void adis16130_exit(void)
+{
+	spi_unregister_driver(&adis16130_driver);
+}
+module_exit(adis16130_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate Sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/adis16251.h b/drivers/staging/iio/gyro/adis16251.h
new file mode 100644
index 0000000..999db49
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16251.h
@@ -0,0 +1,185 @@
+#ifndef SPI_ADIS16251_H_
+#define SPI_ADIS16251_H_
+
+#define ADIS16251_STARTUP_DELAY	220 /* ms */
+
+#define ADIS16251_READ_REG(a)    a
+#define ADIS16251_WRITE_REG(a) ((a) | 0x80)
+
+#define ADIS16251_ENDURANCE  0x00 /* Flash memory write count */
+#define ADIS16251_SUPPLY_OUT 0x02 /* Power supply measurement */
+#define ADIS16251_GYRO_OUT   0x04 /* X-axis gyroscope output */
+#define ADIS16251_AUX_ADC    0x0A /* analog input channel measurement */
+#define ADIS16251_TEMP_OUT   0x0C /* internal temperature measurement */
+#define ADIS16251_ANGL_OUT   0x0E /* angle displacement */
+#define ADIS16251_GYRO_OFF   0x14 /* Calibration, offset/bias adjustment */
+#define ADIS16251_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
+#define ADIS16251_ALM_MAG1   0x20 /* Alarm 1 magnitude/polarity setting */
+#define ADIS16251_ALM_MAG2   0x22 /* Alarm 2 magnitude/polarity setting */
+#define ADIS16251_ALM_SMPL1  0x24 /* Alarm 1 dynamic rate of change setting */
+#define ADIS16251_ALM_SMPL2  0x26 /* Alarm 2 dynamic rate of change setting */
+#define ADIS16251_ALM_CTRL   0x28 /* Alarm control */
+#define ADIS16251_AUX_DAC    0x30 /* Auxiliary DAC data */
+#define ADIS16251_GPIO_CTRL  0x32 /* Control, digital I/O line */
+#define ADIS16251_MSC_CTRL   0x34 /* Control, data ready, self-test settings */
+#define ADIS16251_SMPL_PRD   0x36 /* Control, internal sample rate */
+#define ADIS16251_SENS_AVG   0x38 /* Control, dynamic range, filtering */
+#define ADIS16251_SLP_CNT    0x3A /* Control, sleep mode initiation */
+#define ADIS16251_DIAG_STAT  0x3C /* Diagnostic, error flags */
+#define ADIS16251_GLOB_CMD   0x3E /* Control, global commands */
+
+#define ADIS16251_ERROR_ACTIVE			(1<<14)
+#define ADIS16251_NEW_DATA			(1<<14)
+
+/* MSC_CTRL */
+#define ADIS16251_MSC_CTRL_INT_SELF_TEST	(1<<10) /* Internal self-test enable */
+#define ADIS16251_MSC_CTRL_NEG_SELF_TEST	(1<<9)
+#define ADIS16251_MSC_CTRL_POS_SELF_TEST	(1<<8)
+#define ADIS16251_MSC_CTRL_DATA_RDY_EN		(1<<2)
+#define ADIS16251_MSC_CTRL_DATA_RDY_POL_HIGH	(1<<1)
+#define ADIS16251_MSC_CTRL_DATA_RDY_DIO2	(1<<0)
+
+/* SMPL_PRD */
+#define ADIS16251_SMPL_PRD_TIME_BASE	(1<<7) /* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
+#define ADIS16251_SMPL_PRD_DIV_MASK	0x7F
+
+/* SLP_CNT */
+#define ADIS16251_SLP_CNT_POWER_OFF     0x80
+
+/* DIAG_STAT */
+#define ADIS16251_DIAG_STAT_ALARM2	(1<<9)
+#define ADIS16251_DIAG_STAT_ALARM1	(1<<8)
+#define ADIS16251_DIAG_STAT_SELF_TEST	(1<<5)
+#define ADIS16251_DIAG_STAT_OVERFLOW	(1<<4)
+#define ADIS16251_DIAG_STAT_SPI_FAIL	(1<<3)
+#define ADIS16251_DIAG_STAT_FLASH_UPT	(1<<2)
+#define ADIS16251_DIAG_STAT_POWER_HIGH	(1<<1)
+#define ADIS16251_DIAG_STAT_POWER_LOW	(1<<0)
+
+#define ADIS16251_DIAG_STAT_ERR_MASK (ADIS16261_DIAG_STAT_ALARM2 | \
+				      ADIS16261_DIAG_STAT_ALARM1 | \
+				      ADIS16261_DIAG_STAT_SELF_TEST | \
+				      ADIS16261_DIAG_STAT_OVERFLOW | \
+				      ADIS16261_DIAG_STAT_SPI_FAIL | \
+				      ADIS16261_DIAG_STAT_FLASH_UPT | \
+				      ADIS16261_DIAG_STAT_POWER_HIGH | \
+				      ADIS16261_DIAG_STAT_POWER_LOW)
+
+/* GLOB_CMD */
+#define ADIS16251_GLOB_CMD_SW_RESET	(1<<7)
+#define ADIS16251_GLOB_CMD_FLASH_UPD	(1<<3)
+#define ADIS16251_GLOB_CMD_DAC_LATCH	(1<<2)
+#define ADIS16251_GLOB_CMD_FAC_CALIB	(1<<1)
+#define ADIS16251_GLOB_CMD_AUTO_NULL	(1<<0)
+
+#define ADIS16251_MAX_TX 24
+#define ADIS16251_MAX_RX 24
+
+#define ADIS16251_SPI_SLOW	(u32)(300 * 1000)
+#define ADIS16251_SPI_BURST	(u32)(1000 * 1000)
+#define ADIS16251_SPI_FAST	(u32)(2000 * 1000)
+
+/**
+ * struct adis16251_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adis16251_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+int adis16251_spi_write_reg_8(struct device *dev,
+			      u8 reg_address,
+			      u8 val);
+
+int adis16251_spi_read_burst(struct device *dev, u8 *rx);
+
+int adis16251_spi_read_sequence(struct device *dev,
+				      u8 *tx, u8 *rx, int num);
+
+int adis16251_set_irq(struct device *dev, bool enable);
+
+int adis16251_reset(struct device *dev);
+
+int adis16251_stop_device(struct device *dev);
+
+int adis16251_check_status(struct device *dev);
+
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum adis16251_scan {
+	ADIS16251_SCAN_SUPPLY,
+	ADIS16251_SCAN_GYRO,
+	ADIS16251_SCAN_TEMP,
+	ADIS16251_SCAN_ADC_0,
+};
+
+void adis16251_remove_trigger(struct iio_dev *indio_dev);
+int adis16251_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t adis16251_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+
+int adis16251_configure_ring(struct iio_dev *indio_dev);
+void adis16251_unconfigure_ring(struct iio_dev *indio_dev);
+
+int adis16251_initialize_ring(struct iio_ring_buffer *ring);
+void adis16251_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void adis16251_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16251_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+adis16251_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int adis16251_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void adis16251_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+
+static inline int adis16251_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+
+static inline void adis16251_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_ADIS16251_H_ */
diff --git a/drivers/staging/iio/gyro/adis16251_core.c b/drivers/staging/iio/gyro/adis16251_core.c
new file mode 100644
index 0000000..a0d400f
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16251_core.c
@@ -0,0 +1,777 @@
+/*
+ * ADIS16251 Programmable Digital Gyroscope Sensor Driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "gyro.h"
+#include "../adc/adc.h"
+
+#include "adis16251.h"
+
+#define DRIVER_NAME		"adis16251"
+
+/* At the moment the spi framework doesn't allow global setting of cs_change.
+ * It's in the likely to be added comment at the top of spi.h.
+ * This means that use cannot be made of spi_write etc.
+ */
+
+/**
+ * adis16251_spi_write_reg_8() - write single byte to a register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be written
+ * @val: the value to write
+ **/
+int adis16251_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16251_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16251_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16251_spi_write_reg_16() - write 2 bytes to a pair of registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: value to be written
+ **/
+static int adis16251_spi_write_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16251_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.tx_buf = st->tx + 2,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16251_WRITE_REG(lower_reg_address);
+	st->tx[1] = value & 0xFF;
+	st->tx[2] = ADIS16251_WRITE_REG(lower_reg_address + 1);
+	st->tx[3] = (value >> 8) & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * adis16251_spi_read_reg_16() - read 2 bytes from a 16-bit register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: somewhere to pass back the value read
+ **/
+static int adis16251_spi_read_reg_16(struct device *dev,
+		u8 lower_reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16251_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16251_READ_REG(lower_reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				lower_reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[0] << 8) | st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+/**
+ * adis16251_spi_read_burst() - read all data registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read (min size is 24 bytes)
+ **/
+int adis16251_spi_read_burst(struct device *dev, u8 *rx)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16251_state *st = iio_dev_get_devdata(indio_dev);
+	u32 old_speed_hz = st->us->max_speed_hz;
+	int ret;
+
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 0,
+		}, {
+			.rx_buf = rx,
+			.bits_per_word = 8,
+			.len = 24,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADIS16251_READ_REG(ADIS16251_GLOB_CMD);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+
+	st->us->max_speed_hz = min(ADIS16251_SPI_BURST, old_speed_hz);
+	spi_setup(st->us);
+
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when burst reading");
+
+	st->us->max_speed_hz = old_speed_hz;
+	spi_setup(st->us);
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+/**
+ * adis16251_spi_read_sequence() - read a sequence of 16-bit registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes)
+ * @rx: somewhere to pass back the value read (min size is 2*num bytes)
+ **/
+int adis16251_spi_read_sequence(struct device *dev,
+		u8 *tx, u8 *rx, int num)
+{
+	struct spi_message msg;
+	struct spi_transfer *xfers;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16251_state *st = iio_dev_get_devdata(indio_dev);
+	int ret, i;
+
+	xfers = kzalloc(num + 1, GFP_KERNEL);
+	if (xfers == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed");
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	/* tx: |add1|addr2|addr3|...|addrN |zero|
+	 * rx: |zero|res1 |res2 |...|resN-1|resN| */
+	spi_message_init(&msg);
+	for (i = 0; i < num + 1; i++) {
+		if (i > 0)
+			xfers[i].rx_buf = st->rx + 2*(i - 1);
+		if (i < num)
+			xfers[i].tx_buf = st->tx + 2*i;
+		xfers[i].bits_per_word = 8;
+		xfers[i].len = 2;
+		xfers[i].cs_change = 1;
+		spi_message_add_tail(&xfers[i], &msg);
+	}
+
+	mutex_lock(&st->buf_lock);
+
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when reading sequence");
+
+	mutex_unlock(&st->buf_lock);
+	kfree(xfers);
+
+error_ret:
+	return ret;
+}
+
+static ssize_t adis16251_spi_read_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf,
+		unsigned bits)
+{
+	int ret;
+	s16 val = 0;
+	unsigned shift = 16 - bits;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = adis16251_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	if (ret)
+		return ret;
+
+	if (val & ADIS16251_ERROR_ACTIVE)
+		adis16251_check_status(dev);
+	val = ((s16)(val << shift) >> shift);
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t adis16251_read_12bit_unsigned(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = adis16251_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	if (val & ADIS16251_ERROR_ACTIVE)
+		adis16251_check_status(dev);
+
+	return sprintf(buf, "%u\n", val & 0x0FFF);
+}
+
+static ssize_t adis16251_read_14bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	ret =  adis16251_spi_read_signed(dev, attr, buf, 14);
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16251_read_12bit_signed(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	ret =  adis16251_spi_read_signed(dev, attr, buf, 12);
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t adis16251_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = adis16251_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t adis16251_read_frequency(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret, len = 0;
+	u16 t;
+	int sps;
+	ret = adis16251_spi_read_reg_16(dev,
+			ADIS16251_SMPL_PRD,
+			&t);
+	if (ret)
+		return ret;
+	sps =  (t & ADIS16251_SMPL_PRD_TIME_BASE) ? 8 : 256;
+	sps /= (t & ADIS16251_SMPL_PRD_DIV_MASK) + 1;
+	len = sprintf(buf, "%d SPS\n", sps);
+	return len;
+}
+
+static ssize_t adis16251_write_frequency(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16251_state *st = iio_dev_get_devdata(indio_dev);
+	long val;
+	int ret;
+	u8 t;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	t = (256 / val);
+	if (t > 0)
+		t--;
+	t &= ADIS16251_SMPL_PRD_DIV_MASK;
+	if ((t & ADIS16251_SMPL_PRD_DIV_MASK) >= 0x0A)
+		st->us->max_speed_hz = ADIS16251_SPI_SLOW;
+	else
+		st->us->max_speed_hz = ADIS16251_SPI_FAST;
+
+	ret = adis16251_spi_write_reg_8(dev,
+			ADIS16251_SMPL_PRD,
+			t);
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+static ssize_t adis16251_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -1;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return adis16251_reset(dev);
+	}
+	return -1;
+}
+
+
+
+int adis16251_set_irq(struct device *dev, bool enable)
+{
+	int ret;
+	u16 msc;
+	ret = adis16251_spi_read_reg_16(dev, ADIS16251_MSC_CTRL, &msc);
+	if (ret)
+		goto error_ret;
+
+	msc |= ADIS16251_MSC_CTRL_DATA_RDY_POL_HIGH;
+	if (enable)
+		msc |= ADIS16251_MSC_CTRL_DATA_RDY_EN;
+	else
+		msc &= ~ADIS16251_MSC_CTRL_DATA_RDY_EN;
+
+	ret = adis16251_spi_write_reg_16(dev, ADIS16251_MSC_CTRL, msc);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	return ret;
+}
+
+int adis16251_reset(struct device *dev)
+{
+	int ret;
+	ret = adis16251_spi_write_reg_8(dev,
+			ADIS16251_GLOB_CMD,
+			ADIS16251_GLOB_CMD_SW_RESET);
+	if (ret)
+		dev_err(dev, "problem resetting device");
+
+	return ret;
+}
+
+/* Power down the device */
+int adis16251_stop_device(struct device *dev)
+{
+	int ret;
+	u16 val = ADIS16251_SLP_CNT_POWER_OFF;
+
+	ret = adis16251_spi_write_reg_16(dev, ADIS16251_SLP_CNT, val);
+	if (ret)
+		dev_err(dev, "problem with turning device off: SLP_CNT");
+
+	return ret;
+}
+
+static int adis16251_self_test(struct device *dev)
+{
+	int ret;
+
+	ret = adis16251_spi_write_reg_16(dev,
+			ADIS16251_MSC_CTRL,
+			ADIS16251_MSC_CTRL_INT_SELF_TEST);
+	if (ret) {
+		dev_err(dev, "problem starting self test");
+		goto err_ret;
+	}
+
+	adis16251_check_status(dev);
+
+err_ret:
+	return ret;
+}
+
+int adis16251_check_status(struct device *dev)
+{
+	u16 status;
+	int ret;
+
+	ret = adis16251_spi_read_reg_16(dev, ADIS16251_DIAG_STAT, &status);
+
+	if (ret < 0) {
+		dev_err(dev, "Reading status failed\n");
+		goto error_ret;
+	}
+
+	if (!(status & ADIS16251_DIAG_STAT_ERR_MASK)) {
+		ret = 0;
+		goto error_ret;
+	}
+
+	ret = -EFAULT;
+
+	if (status & ADIS16251_DIAG_STAT_ALARM2)
+		dev_err(dev, "Alarm 2 active\n");
+	if (status & ADIS16251_DIAG_STAT_ALARM1)
+		dev_err(dev, "Alarm 1 active\n");
+	if (status & ADIS16251_DIAG_STAT_SELF_TEST)
+		dev_err(dev, "Self test error\n");
+	if (status & ADIS16251_DIAG_STAT_OVERFLOW)
+		dev_err(dev, "Sensor overrange\n");
+	if (status & ADIS16251_DIAG_STAT_SPI_FAIL)
+		dev_err(dev, "SPI failure\n");
+	if (status & ADIS16251_DIAG_STAT_FLASH_UPT)
+		dev_err(dev, "Flash update failed\n");
+	if (status & ADIS16251_DIAG_STAT_POWER_HIGH)
+		dev_err(dev, "Power supply above 5.25V\n");
+	if (status & ADIS16251_DIAG_STAT_POWER_LOW)
+		dev_err(dev, "Power supply below 4.75V\n");
+
+error_ret:
+	return ret;
+}
+
+static int adis16251_initial_setup(struct adis16251_state *st)
+{
+	int ret;
+	u16 smp_prd;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* use low spi speed for init */
+	st->us->max_speed_hz = ADIS16251_SPI_SLOW;
+	st->us->mode = SPI_MODE_3;
+	spi_setup(st->us);
+
+	/* Disable IRQ */
+	ret = adis16251_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	/* Do self test */
+
+	/* Read status register to check the result */
+	ret = adis16251_check_status(dev);
+	if (ret) {
+		adis16251_reset(dev);
+		dev_err(dev, "device not playing ball -> reset");
+		msleep(ADIS16251_STARTUP_DELAY);
+		ret = adis16251_check_status(dev);
+		if (ret) {
+			dev_err(dev, "giving up");
+			goto err_ret;
+		}
+	}
+
+	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
+			st->us->chip_select, st->us->irq);
+
+	/* use high spi speed if possible */
+	ret = adis16251_spi_read_reg_16(dev, ADIS16251_SMPL_PRD, &smp_prd);
+	if (!ret && (smp_prd & ADIS16251_SMPL_PRD_DIV_MASK) < 0x0A) {
+		st->us->max_speed_hz = ADIS16251_SPI_SLOW;
+		spi_setup(st->us);
+	}
+
+err_ret:
+	return ret;
+}
+
+static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16251_read_12bit_signed,
+		ADIS16251_SUPPLY_OUT);
+static IIO_CONST_ATTR(in0_supply_scale, "0.0018315");
+
+static IIO_DEV_ATTR_GYRO(adis16251_read_14bit_signed,
+		ADIS16251_GYRO_OUT);
+static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO,
+		adis16251_read_12bit_signed,
+		adis16251_write_16bit,
+		ADIS16251_GYRO_SCALE);
+static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO,
+		adis16251_read_12bit_signed,
+		adis16251_write_16bit,
+		ADIS16251_GYRO_OFF);
+
+static IIO_DEV_ATTR_TEMP_RAW(adis16251_read_12bit_signed);
+static IIO_CONST_ATTR(temp_offset, "25 K");
+static IIO_CONST_ATTR(temp_scale, "0.1453 K");
+
+static IIO_DEV_ATTR_IN_NAMED_RAW(1, aux, adis16251_read_12bit_unsigned,
+		ADIS16251_AUX_ADC);
+static IIO_CONST_ATTR(in1_aux_scale, "0.0006105");
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+		adis16251_read_frequency,
+		adis16251_write_frequency);
+static IIO_DEV_ATTR_ANGL(adis16251_read_14bit_signed,
+		ADIS16251_ANGL_OUT);
+
+static IIO_DEV_ATTR_RESET(adis16251_write_reset);
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.129 ~ 256");
+
+static IIO_CONST_ATTR(name, "adis16251");
+
+static struct attribute *adis16251_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group adis16251_event_attribute_group = {
+	.attrs = adis16251_event_attributes,
+};
+
+static struct attribute *adis16251_attributes[] = {
+	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
+	&iio_const_attr_in0_supply_scale.dev_attr.attr,
+	&iio_dev_attr_gyro_raw.dev_attr.attr,
+	&iio_dev_attr_gyro_scale.dev_attr.attr,
+	&iio_dev_attr_gyro_offset.dev_attr.attr,
+	&iio_dev_attr_angl_raw.dev_attr.attr,
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_in1_aux_raw.dev_attr.attr,
+	&iio_const_attr_in1_aux_scale.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16251_attribute_group = {
+	.attrs = adis16251_attributes,
+};
+
+static int __devinit adis16251_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adis16251_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADIS16251_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADIS16251_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &adis16251_event_attribute_group;
+	st->indio_dev->attrs = &adis16251_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = adis16251_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = adis16251_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_RISING,
+				"adis16251");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = adis16251_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = adis16251_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		adis16251_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	adis16251_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	adis16251_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int adis16251_remove(struct spi_device *spi)
+{
+	int ret;
+	struct adis16251_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	ret = adis16251_stop_device(&(indio_dev->dev));
+	if (ret)
+		goto err_ret;
+
+	flush_scheduled_work();
+
+	adis16251_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	adis16251_uninitialize_ring(indio_dev->ring);
+	adis16251_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+
+err_ret:
+	return ret;
+}
+
+static struct spi_driver adis16251_driver = {
+	.driver = {
+		.name = "adis16251",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16251_probe,
+	.remove = __devexit_p(adis16251_remove),
+};
+
+static __init int adis16251_init(void)
+{
+	return spi_register_driver(&adis16251_driver);
+}
+module_init(adis16251_init);
+
+static __exit void adis16251_exit(void)
+{
+	spi_unregister_driver(&adis16251_driver);
+}
+module_exit(adis16251_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16251 Digital Gyroscope Sensor SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 7d7716e..8190c0f 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -1,5 +1,5 @@
 /*
- * ADIS16260 Programmable Digital Gyroscope Sensor Driver
+ * ADIS16260/ADIS16265 Programmable Digital Gyroscope Sensor Driver
  *
  * Copyright 2010 Analog Devices Inc.
  *
diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
index 97c1ec8..cf7176b 100644
--- a/drivers/staging/iio/imu/adis16350_core.c
+++ b/drivers/staging/iio/imu/adis16350_core.c
@@ -570,6 +570,7 @@
 	&iio_dev_attr_temp_y_raw.dev_attr.attr,
 	&iio_dev_attr_temp_z_raw.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
 	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig
new file mode 100644
index 0000000..12e36e4
--- /dev/null
+++ b/drivers/staging/iio/meter/Kconfig
@@ -0,0 +1,61 @@
+#
+# IIO meter drivers configuration
+#
+comment "Active energy metering IC"
+
+config ADE7753
+	tristate "Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction
+	  Metering IC with di/dt Sensor Interface.
+
+config ADE7754
+	tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADE7754 Polyphase
+	  Multifunction Energy Metering IC Driver.
+
+config ADE7758
+	tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver"
+	depends on SPI
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select IIO_SW_RING if IIO_RING_BUFFER
+	help
+	  Say yes here to build support for Analog Devices ADE7758 Polyphase
+	  Multifunction Energy Metering IC with Per Phase Information Driver.
+
+config ADE7759
+	tristate "Analog Devices ADE7759 Active Energy Metering IC Driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADE7758 Active Energy
+	  Metering IC with di/dt Sensor Interface.
+
+config ADE7854
+	tristate "Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver"
+	depends on SPI || I2C
+	help
+	  Say yes here to build support for Analog Devices ADE7854/58/68/78 Polyphase
+	  Multifunction Energy Metering IC Driver.
+
+config ADE7854_I2C
+	tristate "support I2C bus connection"
+	depends on ADE7854 && I2C
+	default y
+	help
+	  Say Y here if you have ADE7854/58/68/78 hooked to an I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ade7854-i2c.
+
+config ADE7854_SPI
+	tristate "support SPI bus connection"
+	depends on ADE7854 && SPI
+	default y
+	help
+	  Say Y here if you have ADE7854/58/68/78 hooked to a SPI bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ade7854-spi.
diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile
new file mode 100644
index 0000000..0cc7d51
--- /dev/null
+++ b/drivers/staging/iio/meter/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for metering ic drivers
+#
+
+obj-$(CONFIG_ADE7753) += ade7753.o
+obj-$(CONFIG_ADE7754) += ade7754.o
+
+ade7758-y             := ade7758_core.o
+ade7758-$(CONFIG_IIO_RING_BUFFER) += ade7758_ring.o ade7758_trigger.o
+obj-$(CONFIG_ADE7758) += ade7758.o
+
+obj-$(CONFIG_ADE7759) += ade7759.o
+obj-$(CONFIG_ADE7854) += ade7854.o
+obj-$(CONFIG_ADE7854_I2C) += ade7854-i2c.o
+obj-$(CONFIG_ADE7854_SPI) += ade7854-spi.o
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
new file mode 100644
index 0000000..e72afbd
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -0,0 +1,730 @@
+/*
+ * ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface Driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "meter.h"
+#include "ade7753.h"
+
+int ade7753_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7753_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7753_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7753_spi_write_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7753_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 3,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7753_WRITE_REG(reg_address);
+	st->tx[1] = (value >> 8) & 0xFF;
+	st->tx[2] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7753_spi_read_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7753_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7753_READ_REG(reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7753_spi_read_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7753_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 3,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7753_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 8) | st->rx[2];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7753_spi_read_reg_24(struct device *dev,
+		u8 reg_address,
+		u32 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7753_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7753_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t ade7753_read_8bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u8 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7753_spi_read_reg_8(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7753_read_16bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7753_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7753_read_24bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u32 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7753_spi_read_reg_24(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val & 0xFFFFFF);
+}
+
+static ssize_t ade7753_write_8bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7753_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int ade7753_reset(struct device *dev)
+{
+	int ret;
+	u16 val;
+	ade7753_spi_read_reg_16(dev,
+			ADE7753_MODE,
+			&val);
+	val |= 1 << 6; /* Software Chip Reset */
+	ret = ade7753_spi_write_reg_16(dev,
+			ADE7753_MODE,
+			val);
+
+	return ret;
+}
+
+static ssize_t ade7753_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -1;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return ade7753_reset(dev);
+	}
+	return -1;
+}
+
+static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
+static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
+static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
+static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY);
+static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_CFDEN);
+static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_CFNUM);
+static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM);
+static IIO_DEV_ATTR_PHCAL(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_PHCAL);
+static IIO_DEV_ATTR_APOS(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_APOS);
+static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_SAGCYC);
+static IIO_DEV_ATTR_SAGLVL(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_SAGLVL);
+static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_LINECYC);
+static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_WDIV);
+static IIO_DEV_ATTR_IRMS(S_IWUSR | S_IRUGO,
+		ade7753_read_24bit,
+		NULL,
+		ADE7753_IRMS);
+static IIO_DEV_ATTR_VRMS(S_IRUGO,
+		ade7753_read_24bit,
+		NULL,
+		ADE7753_VRMS);
+static IIO_DEV_ATTR_IRMSOS(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_IRMSOS);
+static IIO_DEV_ATTR_VRMSOS(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_VRMSOS);
+static IIO_DEV_ATTR_WGAIN(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_WGAIN);
+static IIO_DEV_ATTR_VAGAIN(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_VAGAIN);
+static IIO_DEV_ATTR_PGA_GAIN(S_IWUSR | S_IRUGO,
+		ade7753_read_16bit,
+		ade7753_write_16bit,
+		ADE7753_GAIN);
+static IIO_DEV_ATTR_IPKLVL(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_IPKLVL);
+static IIO_DEV_ATTR_VPKLVL(S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_VPKLVL);
+static IIO_DEV_ATTR_IPEAK(S_IRUGO,
+		ade7753_read_24bit,
+		NULL,
+		ADE7753_IPEAK);
+static IIO_DEV_ATTR_VPEAK(S_IRUGO,
+		ade7753_read_24bit,
+		NULL,
+		ADE7753_VPEAK);
+static IIO_DEV_ATTR_VPERIOD(S_IRUGO,
+		ade7753_read_16bit,
+		NULL,
+		ADE7753_PERIOD);
+static IIO_DEV_ATTR_CH_OFF(1, S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_CH1OS);
+static IIO_DEV_ATTR_CH_OFF(2, S_IWUSR | S_IRUGO,
+		ade7753_read_8bit,
+		ade7753_write_8bit,
+		ADE7753_CH2OS);
+
+static int ade7753_set_irq(struct device *dev, bool enable)
+{
+	int ret;
+	u8 irqen;
+	ret = ade7753_spi_read_reg_8(dev, ADE7753_IRQEN, &irqen);
+	if (ret)
+		goto error_ret;
+
+	if (enable)
+		irqen |= 1 << 3; /* Enables an interrupt when a data is
+				    present in the waveform register */
+	else
+		irqen &= ~(1 << 3);
+
+	ret = ade7753_spi_write_reg_8(dev, ADE7753_IRQEN, irqen);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	return ret;
+}
+
+/* Power down the device */
+int ade7753_stop_device(struct device *dev)
+{
+	int ret;
+	u16 val;
+	ade7753_spi_read_reg_16(dev,
+			ADE7753_MODE,
+			&val);
+	val |= 1 << 4;  /* AD converters can be turned off */
+	ret = ade7753_spi_write_reg_16(dev,
+			ADE7753_MODE,
+			val);
+
+	return ret;
+}
+
+static int ade7753_initial_setup(struct ade7753_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* use low spi speed for init */
+	st->us->mode = SPI_MODE_3;
+	spi_setup(st->us);
+
+	/* Disable IRQ */
+	ret = ade7753_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	ade7753_reset(dev);
+	msleep(ADE7753_STARTUP_DELAY);
+
+err_ret:
+	return ret;
+}
+
+static ssize_t ade7753_read_frequency(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret, len = 0;
+	u8 t;
+	int sps;
+	ret = ade7753_spi_read_reg_8(dev,
+			ADE7753_MODE,
+			&t);
+	if (ret)
+		return ret;
+
+	t = (t >> 11) & 0x3;
+	sps = 27900 / (1 + t);
+
+	len = sprintf(buf, "%d SPS\n", sps);
+	return len;
+}
+
+static ssize_t ade7753_write_frequency(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7753_state *st = iio_dev_get_devdata(indio_dev);
+	unsigned long val;
+	int ret;
+	u16 reg, t;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	t = (27900 / val);
+	if (t > 0)
+		t--;
+
+	if (t > 1)
+		st->us->max_speed_hz = ADE7753_SPI_SLOW;
+	else
+		st->us->max_speed_hz = ADE7753_SPI_FAST;
+
+	ret = ade7753_spi_read_reg_16(dev,
+			ADE7753_MODE,
+			&reg);
+	if (ret)
+		goto out;
+
+	reg &= ~(3 << 11);
+	reg |= t << 11;
+
+	ret = ade7753_spi_write_reg_16(dev,
+			ADE7753_MODE,
+			reg);
+
+out:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit);
+static IIO_CONST_ATTR(temp_offset, "-25 C");
+static IIO_CONST_ATTR(temp_scale, "0.67 C");
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+		ade7753_read_frequency,
+		ade7753_write_frequency);
+
+static IIO_DEV_ATTR_RESET(ade7753_write_reset);
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
+
+static IIO_CONST_ATTR(name, "ade7753");
+
+static struct attribute *ade7753_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group ade7753_event_attribute_group = {
+	.attrs = ade7753_event_attributes,
+};
+
+static struct attribute *ade7753_attributes[] = {
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_phcal.dev_attr.attr,
+	&iio_dev_attr_cfden.dev_attr.attr,
+	&iio_dev_attr_aenergy.dev_attr.attr,
+	&iio_dev_attr_laenergy.dev_attr.attr,
+	&iio_dev_attr_vaenergy.dev_attr.attr,
+	&iio_dev_attr_lvaenergy.dev_attr.attr,
+	&iio_dev_attr_cfnum.dev_attr.attr,
+	&iio_dev_attr_apos.dev_attr.attr,
+	&iio_dev_attr_sagcyc.dev_attr.attr,
+	&iio_dev_attr_saglvl.dev_attr.attr,
+	&iio_dev_attr_linecyc.dev_attr.attr,
+	&iio_dev_attr_chksum.dev_attr.attr,
+	&iio_dev_attr_pga_gain.dev_attr.attr,
+	&iio_dev_attr_wgain.dev_attr.attr,
+	&iio_dev_attr_choff_1.dev_attr.attr,
+	&iio_dev_attr_choff_2.dev_attr.attr,
+	&iio_dev_attr_wdiv.dev_attr.attr,
+	&iio_dev_attr_irms.dev_attr.attr,
+	&iio_dev_attr_vrms.dev_attr.attr,
+	&iio_dev_attr_irmsos.dev_attr.attr,
+	&iio_dev_attr_vrmsos.dev_attr.attr,
+	&iio_dev_attr_vagain.dev_attr.attr,
+	&iio_dev_attr_ipklvl.dev_attr.attr,
+	&iio_dev_attr_vpklvl.dev_attr.attr,
+	&iio_dev_attr_ipeak.dev_attr.attr,
+	&iio_dev_attr_vpeak.dev_attr.attr,
+	&iio_dev_attr_vperiod.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ade7753_attribute_group = {
+	.attrs = ade7753_attributes,
+};
+
+static int __devinit ade7753_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct ade7753_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADE7753_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADE7753_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &ade7753_event_attribute_group;
+	st->indio_dev->attrs = &ade7753_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = ade7753_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = ade7753_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_FALLING,
+				"ade7753");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = ade7753_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = ade7753_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7753_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	ade7753_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	ade7753_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int ade7753_remove(struct spi_device *spi)
+{
+	int ret;
+	struct ade7753_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	ret = ade7753_stop_device(&(indio_dev->dev));
+	if (ret)
+		goto err_ret;
+
+	flush_scheduled_work();
+
+	ade7753_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	ade7753_uninitialize_ring(indio_dev->ring);
+	ade7753_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+
+err_ret:
+	return ret;
+}
+
+static struct spi_driver ade7753_driver = {
+	.driver = {
+		.name = "ade7753",
+		.owner = THIS_MODULE,
+	},
+	.probe = ade7753_probe,
+	.remove = __devexit_p(ade7753_remove),
+};
+
+static __init int ade7753_init(void)
+{
+	return spi_register_driver(&ade7753_driver);
+}
+module_init(ade7753_init);
+
+static __exit void ade7753_exit(void)
+{
+	spi_unregister_driver(&ade7753_driver);
+}
+module_exit(ade7753_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h
new file mode 100644
index 0000000..a3722b8
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7753.h
@@ -0,0 +1,140 @@
+#ifndef _ADE7753_H
+#define _ADE7753_H
+
+#define ADE7753_WAVEFORM   0x01
+#define ADE7753_AENERGY    0x02
+#define ADE7753_RAENERGY   0x03
+#define ADE7753_LAENERGY   0x04
+#define ADE7753_VAENERGY   0x05
+#define ADE7753_RVAENERGY  0x06
+#define ADE7753_LVAENERGY  0x07
+#define ADE7753_LVARENERGY 0x08
+#define ADE7753_MODE       0x09
+#define ADE7753_IRQEN      0x0A
+#define ADE7753_STATUS     0x0B
+#define ADE7753_RSTSTATUS  0x0C
+#define ADE7753_CH1OS      0x0D
+#define ADE7753_CH2OS      0x0E
+#define ADE7753_GAIN       0x0F
+#define ADE7753_PHCAL      0x10
+#define ADE7753_APOS       0x11
+#define ADE7753_WGAIN      0x12
+#define ADE7753_WDIV       0x13
+#define ADE7753_CFNUM      0x14
+#define ADE7753_CFDEN      0x15
+#define ADE7753_IRMS       0x16
+#define ADE7753_VRMS       0x17
+#define ADE7753_IRMSOS     0x18
+#define ADE7753_VRMSOS     0x19
+#define ADE7753_VAGAIN     0x1A
+#define ADE7753_VADIV      0x1B
+#define ADE7753_LINECYC    0x1C
+#define ADE7753_ZXTOUT     0x1D
+#define ADE7753_SAGCYC     0x1E
+#define ADE7753_SAGLVL     0x1F
+#define ADE7753_IPKLVL     0x20
+#define ADE7753_VPKLVL     0x21
+#define ADE7753_IPEAK      0x22
+#define ADE7753_RSTIPEAK   0x23
+#define ADE7753_VPEAK      0x24
+#define ADE7753_RSTVPEAK   0x25
+#define ADE7753_TEMP       0x26
+#define ADE7753_PERIOD     0x27
+#define ADE7753_TMODE      0x3D
+#define ADE7753_CHKSUM     0x3E
+#define ADE7753_DIEREV     0x3F
+
+#define ADE7753_READ_REG(a)    a
+#define ADE7753_WRITE_REG(a) ((a) | 0x80)
+
+#define ADE7753_MAX_TX    4
+#define ADE7753_MAX_RX    4
+#define ADE7753_STARTUP_DELAY 1
+
+#define ADE7753_SPI_SLOW	(u32)(300 * 1000)
+#define ADE7753_SPI_BURST	(u32)(1000 * 1000)
+#define ADE7753_SPI_FAST	(u32)(2000 * 1000)
+
+#define DRIVER_NAME		"ade7753"
+
+/**
+ * struct ade7753_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct ade7753_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum ade7753_scan {
+	ADE7753_SCAN_ACTIVE_POWER,
+	ADE7753_SCAN_CH1,
+	ADE7753_SCAN_CH2,
+};
+
+void ade7753_remove_trigger(struct iio_dev *indio_dev);
+int ade7753_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t ade7753_read_data_from_ring(struct device *dev,
+		struct device_attribute *attr,
+		char *buf);
+
+
+int ade7753_configure_ring(struct iio_dev *indio_dev);
+void ade7753_unconfigure_ring(struct iio_dev *indio_dev);
+
+int ade7753_initialize_ring(struct iio_ring_buffer *ring);
+void ade7753_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void ade7753_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7753_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+ade7753_read_data_from_ring(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return 0;
+}
+
+static int ade7753_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+static inline void ade7753_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7753_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+static inline void ade7753_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+#endif /* CONFIG_IIO_RING_BUFFER */
+
+#endif
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
new file mode 100644
index 0000000..23dedfa
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -0,0 +1,756 @@
+/*
+ * ADE7754 Polyphase Multifunction Energy Metering IC Driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "meter.h"
+#include "ade7754.h"
+
+static int ade7754_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7754_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7754_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7754_spi_write_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7754_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 3,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7754_WRITE_REG(reg_address);
+	st->tx[1] = (value >> 8) & 0xFF;
+	st->tx[2] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7754_spi_read_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7754_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7754_READ_REG(reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7754_spi_read_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7754_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 3,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7754_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 8) | st->rx[2];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7754_spi_read_reg_24(struct device *dev,
+		u8 reg_address,
+		u32 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7754_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7754_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t ade7754_read_8bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u8 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7754_spi_read_reg_8(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7754_read_16bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7754_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7754_read_24bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u32 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7754_spi_read_reg_24(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val & 0xFFFFFF);
+}
+
+static ssize_t ade7754_write_8bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7754_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int ade7754_reset(struct device *dev)
+{
+	int ret;
+	u8 val;
+	ade7754_spi_read_reg_8(dev,
+			ADE7754_OPMODE,
+			&val);
+	val |= 1 << 6; /* Software Chip Reset */
+	ret = ade7754_spi_write_reg_8(dev,
+			ADE7754_OPMODE,
+			val);
+
+	return ret;
+}
+
+
+static ssize_t ade7754_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -1;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return ade7754_reset(dev);
+	}
+	return -1;
+}
+
+static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
+static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
+static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
+static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY);
+static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_VPEAK);
+static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_VPEAK);
+static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_APHCAL);
+static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_BPHCAL);
+static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_CPHCAL);
+static IIO_DEV_ATTR_AAPOS(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_AAPOS);
+static IIO_DEV_ATTR_BAPOS(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_BAPOS);
+static IIO_DEV_ATTR_CAPOS(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_CAPOS);
+static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_WDIV);
+static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO,
+		ade7754_read_8bit,
+		ade7754_write_8bit,
+		ADE7754_VADIV);
+static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_CFNUM);
+static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_CFDEN);
+static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_AAPGAIN);
+static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_BAPGAIN);
+static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_CAPGAIN);
+static IIO_DEV_ATTR_AIRMS(S_IRUGO,
+		ade7754_read_24bit,
+		NULL,
+		ADE7754_AIRMS);
+static IIO_DEV_ATTR_BIRMS(S_IRUGO,
+		ade7754_read_24bit,
+		NULL,
+		ADE7754_BIRMS);
+static IIO_DEV_ATTR_CIRMS(S_IRUGO,
+		ade7754_read_24bit,
+		NULL,
+		ADE7754_CIRMS);
+static IIO_DEV_ATTR_AVRMS(S_IRUGO,
+		ade7754_read_24bit,
+		NULL,
+		ADE7754_AVRMS);
+static IIO_DEV_ATTR_BVRMS(S_IRUGO,
+		ade7754_read_24bit,
+		NULL,
+		ADE7754_BVRMS);
+static IIO_DEV_ATTR_CVRMS(S_IRUGO,
+		ade7754_read_24bit,
+		NULL,
+		ADE7754_CVRMS);
+static IIO_DEV_ATTR_AIRMSOS(S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_AIRMSOS);
+static IIO_DEV_ATTR_BIRMSOS(S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_BIRMSOS);
+static IIO_DEV_ATTR_CIRMSOS(S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_CIRMSOS);
+static IIO_DEV_ATTR_AVRMSOS(S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_AVRMSOS);
+static IIO_DEV_ATTR_BVRMSOS(S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_BVRMSOS);
+static IIO_DEV_ATTR_CVRMSOS(S_IRUGO,
+		ade7754_read_16bit,
+		ade7754_write_16bit,
+		ADE7754_CVRMSOS);
+
+static int ade7754_set_irq(struct device *dev, bool enable)
+{
+	int ret;
+	u16 irqen;
+	ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen);
+	if (ret)
+		goto error_ret;
+
+	if (enable)
+		irqen |= 1 << 14; /* Enables an interrupt when a data is
+				     present in the waveform register */
+	else
+		irqen &= ~(1 << 14);
+
+	ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	return ret;
+}
+
+/* Power down the device */
+static int ade7754_stop_device(struct device *dev)
+{
+	int ret;
+	u8 val;
+	ade7754_spi_read_reg_8(dev,
+			ADE7754_OPMODE,
+			&val);
+	val |= 7 << 3;  /* ADE7754 powered down */
+	ret = ade7754_spi_write_reg_8(dev,
+			ADE7754_OPMODE,
+			val);
+
+	return ret;
+}
+
+static int ade7754_initial_setup(struct ade7754_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* use low spi speed for init */
+	st->us->mode = SPI_MODE_3;
+	spi_setup(st->us);
+
+	/* Disable IRQ */
+	ret = ade7754_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	ade7754_reset(dev);
+	msleep(ADE7754_STARTUP_DELAY);
+
+err_ret:
+	return ret;
+}
+
+static ssize_t ade7754_read_frequency(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret, len = 0;
+	u8 t;
+	int sps;
+	ret = ade7754_spi_read_reg_8(dev,
+			ADE7754_WAVMODE,
+			&t);
+	if (ret)
+		return ret;
+
+	t = (t >> 3) & 0x3;
+	sps = 26000 / (1 + t);
+
+	len = sprintf(buf, "%d SPS\n", sps);
+	return len;
+}
+
+static ssize_t ade7754_write_frequency(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7754_state *st = iio_dev_get_devdata(indio_dev);
+	unsigned long val;
+	int ret;
+	u8 reg, t;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	t = (26000 / val);
+	if (t > 0)
+		t--;
+
+	if (t > 1)
+		st->us->max_speed_hz = ADE7754_SPI_SLOW;
+	else
+		st->us->max_speed_hz = ADE7754_SPI_FAST;
+
+	ret = ade7754_spi_read_reg_8(dev,
+			ADE7754_WAVMODE,
+			&reg);
+	if (ret)
+		goto out;
+
+	reg &= ~(3 << 3);
+	reg |= t << 3;
+
+	ret = ade7754_spi_write_reg_8(dev,
+			ADE7754_WAVMODE,
+			reg);
+
+out:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit);
+static IIO_CONST_ATTR(temp_offset, "129 C");
+static IIO_CONST_ATTR(temp_scale, "4 C");
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+		ade7754_read_frequency,
+		ade7754_write_frequency);
+
+static IIO_DEV_ATTR_RESET(ade7754_write_reset);
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
+
+static IIO_CONST_ATTR(name, "ade7754");
+
+static struct attribute *ade7754_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group ade7754_event_attribute_group = {
+	.attrs = ade7754_event_attributes,
+};
+
+static struct attribute *ade7754_attributes[] = {
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_aenergy.dev_attr.attr,
+	&iio_dev_attr_laenergy.dev_attr.attr,
+	&iio_dev_attr_vaenergy.dev_attr.attr,
+	&iio_dev_attr_lvaenergy.dev_attr.attr,
+	&iio_dev_attr_vpeak.dev_attr.attr,
+	&iio_dev_attr_ipeak.dev_attr.attr,
+	&iio_dev_attr_aphcal.dev_attr.attr,
+	&iio_dev_attr_bphcal.dev_attr.attr,
+	&iio_dev_attr_cphcal.dev_attr.attr,
+	&iio_dev_attr_aapos.dev_attr.attr,
+	&iio_dev_attr_bapos.dev_attr.attr,
+	&iio_dev_attr_capos.dev_attr.attr,
+	&iio_dev_attr_wdiv.dev_attr.attr,
+	&iio_dev_attr_vadiv.dev_attr.attr,
+	&iio_dev_attr_cfnum.dev_attr.attr,
+	&iio_dev_attr_cfden.dev_attr.attr,
+	&iio_dev_attr_active_power_a_gain.dev_attr.attr,
+	&iio_dev_attr_active_power_b_gain.dev_attr.attr,
+	&iio_dev_attr_active_power_c_gain.dev_attr.attr,
+	&iio_dev_attr_airms.dev_attr.attr,
+	&iio_dev_attr_birms.dev_attr.attr,
+	&iio_dev_attr_cirms.dev_attr.attr,
+	&iio_dev_attr_avrms.dev_attr.attr,
+	&iio_dev_attr_bvrms.dev_attr.attr,
+	&iio_dev_attr_cvrms.dev_attr.attr,
+	&iio_dev_attr_airmsos.dev_attr.attr,
+	&iio_dev_attr_birmsos.dev_attr.attr,
+	&iio_dev_attr_cirmsos.dev_attr.attr,
+	&iio_dev_attr_avrmsos.dev_attr.attr,
+	&iio_dev_attr_bvrmsos.dev_attr.attr,
+	&iio_dev_attr_cvrmsos.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ade7754_attribute_group = {
+	.attrs = ade7754_attributes,
+};
+
+
+
+static int __devinit ade7754_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct ade7754_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADE7754_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADE7754_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &ade7754_event_attribute_group;
+	st->indio_dev->attrs = &ade7754_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = ade7754_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = ade7754_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_FALLING,
+				"ade7754");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = ade7754_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = ade7754_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7754_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	ade7754_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	ade7754_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int ade7754_remove(struct spi_device *spi)
+{
+	int ret;
+	struct ade7754_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	ret = ade7754_stop_device(&(indio_dev->dev));
+	if (ret)
+		goto err_ret;
+
+	flush_scheduled_work();
+
+	ade7754_remove_trigger(indio_dev);
+	if (spi->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	ade7754_uninitialize_ring(indio_dev->ring);
+	ade7754_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+
+err_ret:
+	return ret;
+}
+
+static struct spi_driver ade7754_driver = {
+	.driver = {
+		.name = "ade7754",
+		.owner = THIS_MODULE,
+	},
+	.probe = ade7754_probe,
+	.remove = __devexit_p(ade7754_remove),
+};
+
+static __init int ade7754_init(void)
+{
+	return spi_register_driver(&ade7754_driver);
+}
+module_init(ade7754_init);
+
+static __exit void ade7754_exit(void)
+{
+	spi_unregister_driver(&ade7754_driver);
+}
+module_exit(ade7754_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h
new file mode 100644
index 0000000..f6a3e4b
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7754.h
@@ -0,0 +1,161 @@
+#ifndef _ADE7754_H
+#define _ADE7754_H
+
+#define ADE7754_AENERGY   0x01
+#define ADE7754_RAENERGY  0x02
+#define ADE7754_LAENERGY  0x03
+#define ADE7754_VAENERGY  0x04
+#define ADE7754_RVAENERGY 0x05
+#define ADE7754_LVAENERGY 0x06
+#define ADE7754_PERIOD    0x07
+#define ADE7754_TEMP      0x08
+#define ADE7754_WFORM     0x09
+#define ADE7754_OPMODE    0x0A
+#define ADE7754_MMODE     0x0B
+#define ADE7754_WAVMODE   0x0C
+#define ADE7754_WATMODE   0x0D
+#define ADE7754_VAMODE    0x0E
+#define ADE7754_IRQEN     0x0F
+#define ADE7754_STATUS    0x10
+#define ADE7754_RSTATUS   0x11
+#define ADE7754_ZXTOUT    0x12
+#define ADE7754_LINCYC    0x13
+#define ADE7754_SAGCYC    0x14
+#define ADE7754_SAGLVL    0x15
+#define ADE7754_VPEAK     0x16
+#define ADE7754_IPEAK     0x17
+#define ADE7754_GAIN      0x18
+#define ADE7754_AWG       0x19
+#define ADE7754_BWG       0x1A
+#define ADE7754_CWG       0x1B
+#define ADE7754_AVAG      0x1C
+#define ADE7754_BVAG      0x1D
+#define ADE7754_CVAG      0x1E
+#define ADE7754_APHCAL    0x1F
+#define ADE7754_BPHCAL    0x20
+#define ADE7754_CPHCAL    0x21
+#define ADE7754_AAPOS     0x22
+#define ADE7754_BAPOS     0x23
+#define ADE7754_CAPOS     0x24
+#define ADE7754_CFNUM     0x25
+#define ADE7754_CFDEN     0x26
+#define ADE7754_WDIV      0x27
+#define ADE7754_VADIV     0x28
+#define ADE7754_AIRMS     0x29
+#define ADE7754_BIRMS     0x2A
+#define ADE7754_CIRMS     0x2B
+#define ADE7754_AVRMS     0x2C
+#define ADE7754_BVRMS     0x2D
+#define ADE7754_CVRMS     0x2E
+#define ADE7754_AIRMSOS   0x2F
+#define ADE7754_BIRMSOS   0x30
+#define ADE7754_CIRMSOS   0x31
+#define ADE7754_AVRMSOS   0x32
+#define ADE7754_BVRMSOS   0x33
+#define ADE7754_CVRMSOS   0x34
+#define ADE7754_AAPGAIN   0x35
+#define ADE7754_BAPGAIN   0x36
+#define ADE7754_CAPGAIN   0x37
+#define ADE7754_AVGAIN    0x38
+#define ADE7754_BVGAIN    0x39
+#define ADE7754_CVGAIN    0x3A
+#define ADE7754_CHKSUM    0x3E
+#define ADE7754_VERSION   0x3F
+
+#define ADE7754_READ_REG(a)    a
+#define ADE7754_WRITE_REG(a) ((a) | 0x80)
+
+#define ADE7754_MAX_TX    4
+#define ADE7754_MAX_RX    4
+#define ADE7754_STARTUP_DELAY 1
+
+#define ADE7754_SPI_SLOW	(u32)(300 * 1000)
+#define ADE7754_SPI_BURST	(u32)(1000 * 1000)
+#define ADE7754_SPI_FAST	(u32)(2000 * 1000)
+
+#define DRIVER_NAME		"ade7754"
+
+/**
+ * struct ade7754_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct ade7754_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum ade7754_scan {
+	ADE7754_SCAN_PHA_V,
+	ADE7754_SCAN_PHB_V,
+	ADE7754_SCAN_PHC_V,
+	ADE7754_SCAN_PHA_I,
+	ADE7754_SCAN_PHB_I,
+	ADE7754_SCAN_PHC_I,
+};
+
+void ade7754_remove_trigger(struct iio_dev *indio_dev);
+int ade7754_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t ade7754_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+
+int ade7754_configure_ring(struct iio_dev *indio_dev);
+void ade7754_unconfigure_ring(struct iio_dev *indio_dev);
+
+int ade7754_initialize_ring(struct iio_ring_buffer *ring);
+void ade7754_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void ade7754_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7754_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+ade7754_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static int ade7754_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+static inline void ade7754_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7754_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+static inline void ade7754_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+#endif /* CONFIG_IIO_RING_BUFFER */
+
+#endif
diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
new file mode 100644
index 0000000..df5bb7ba
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -0,0 +1,171 @@
+#ifndef _ADE7758_H
+#define _ADE7758_H
+
+#define ADE7758_AWATTHR   0x01
+#define ADE7758_BWATTHR   0x02
+#define ADE7758_CWATTHR   0x03
+#define ADE7758_AVARHR    0x04
+#define ADE7758_BVARHR    0x05
+#define ADE7758_CVARHR    0x06
+#define ADE7758_AVAHR     0x07
+#define ADE7758_BVAHR     0x08
+#define ADE7758_CVAHR     0x09
+#define ADE7758_AIRMS     0x0A
+#define ADE7758_BIRMS     0x0B
+#define ADE7758_CIRMS     0x0C
+#define ADE7758_AVRMS     0x0D
+#define ADE7758_BVRMS     0x0E
+#define ADE7758_CVRMS     0x0F
+#define ADE7758_FREQ      0x10
+#define ADE7758_TEMP      0x11
+#define ADE7758_WFORM     0x12
+#define ADE7758_OPMODE    0x13
+#define ADE7758_MMODE     0x14
+#define ADE7758_WAVMODE   0x15
+#define ADE7758_COMPMODE  0x16
+#define ADE7758_LCYCMODE  0x17
+#define ADE7758_MASK      0x18
+#define ADE7758_STATUS    0x19
+#define ADE7758_RSTATUS   0x1A
+#define ADE7758_ZXTOUT    0x1B
+#define ADE7758_LINECYC   0x1C
+#define ADE7758_SAGCYC    0x1D
+#define ADE7758_SAGLVL    0x1E
+#define ADE7758_VPINTLVL  0x1F
+#define ADE7758_IPINTLVL  0x20
+#define ADE7758_VPEAK     0x21
+#define ADE7758_IPEAK     0x22
+#define ADE7758_GAIN      0x23
+#define ADE7758_AVRMSGAIN 0x24
+#define ADE7758_BVRMSGAIN 0x25
+#define ADE7758_CVRMSGAIN 0x26
+#define ADE7758_AIGAIN    0x27
+#define ADE7758_BIGAIN    0x28
+#define ADE7758_CIGAIN    0x29
+#define ADE7758_AWG       0x2A
+#define ADE7758_BWG       0x2B
+#define ADE7758_CWG       0x2C
+#define ADE7758_AVARG     0x2D
+#define ADE7758_BVARG     0x2E
+#define ADE7758_CVARG     0x2F
+#define ADE7758_AVAG      0x30
+#define ADE7758_BVAG      0x31
+#define ADE7758_CVAG      0x32
+#define ADE7758_AVRMSOS   0x33
+#define ADE7758_BVRMSOS   0x34
+#define ADE7758_CVRMSOS   0x35
+#define ADE7758_AIRMSOS   0x36
+#define ADE7758_BIRMSOS   0x37
+#define ADE7758_CIRMSOS   0x38
+#define ADE7758_AWAITOS   0x39
+#define ADE7758_BWAITOS   0x3A
+#define ADE7758_CWAITOS   0x3B
+#define ADE7758_AVAROS    0x3C
+#define ADE7758_BVAROS    0x3D
+#define ADE7758_CVAROS    0x3E
+#define ADE7758_APHCAL    0x3F
+#define ADE7758_BPHCAL    0x40
+#define ADE7758_CPHCAL    0x41
+#define ADE7758_WDIV      0x42
+#define ADE7758_VADIV     0x44
+#define ADE7758_VARDIV    0x43
+#define ADE7758_APCFNUM   0x45
+#define ADE7758_APCFDEN   0x46
+#define ADE7758_VARCFNUM  0x47
+#define ADE7758_VARCFDEN  0x48
+#define ADE7758_CHKSUM    0x7E
+#define ADE7758_VERSION   0x7F
+
+#define ADE7758_READ_REG(a)    a
+#define ADE7758_WRITE_REG(a) ((a) | 0x80)
+
+#define ADE7758_MAX_TX    8
+#define ADE7758_MAX_RX    4
+#define ADE7758_STARTUP_DELAY 1
+
+#define ADE7758_SPI_SLOW	(u32)(300 * 1000)
+#define ADE7758_SPI_BURST	(u32)(1000 * 1000)
+#define ADE7758_SPI_FAST	(u32)(2000 * 1000)
+
+#define DRIVER_NAME		"ade7758"
+
+/**
+ * struct ade7758_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct ade7758_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+#ifdef CONFIG_IIO_RING_BUFFER
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum ade7758_scan {
+	ADE7758_SCAN_WFORM,
+};
+
+void ade7758_remove_trigger(struct iio_dev *indio_dev);
+int ade7758_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t ade7758_read_data_from_ring(struct device *dev,
+		struct device_attribute *attr,
+		char *buf);
+
+
+int ade7758_configure_ring(struct iio_dev *indio_dev);
+void ade7758_unconfigure_ring(struct iio_dev *indio_dev);
+
+int ade7758_initialize_ring(struct iio_ring_buffer *ring);
+void ade7758_uninitialize_ring(struct iio_ring_buffer *ring);
+int ade7758_set_irq(struct device *dev, bool enable);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void ade7758_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7758_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+ade7758_read_data_from_ring(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return 0;
+}
+
+static int ade7758_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+static inline void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7758_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+static inline void ade7758_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+#endif /* CONFIG_IIO_RING_BUFFER */
+
+#endif
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
new file mode 100644
index 0000000..b7634cb
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -0,0 +1,866 @@
+/*
+ * ADE7758 Polyphase Multifunction Energy Metering IC Driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "meter.h"
+#include "ade7758.h"
+
+int ade7758_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7758_spi_write_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 3,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_WRITE_REG(reg_address);
+	st->tx[1] = (value >> 8) & 0xFF;
+	st->tx[2] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7758_spi_write_reg_24(struct device *dev,
+		u8 reg_address,
+		u32 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 4,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_WRITE_REG(reg_address);
+	st->tx[1] = (value >> 16) & 0xFF;
+	st->tx[2] = (value >> 8) & 0xFF;
+	st->tx[3] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7758_spi_read_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_READ_REG(reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7758_spi_read_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 3,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 8) | st->rx[2];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7758_spi_read_reg_24(struct device *dev,
+		u8 reg_address,
+		u32 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t ade7758_read_8bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u8 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7758_spi_read_reg_8(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7758_read_16bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7758_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7758_read_24bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u32 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7758_spi_read_reg_24(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val & 0xFFFFFF);
+}
+
+static ssize_t ade7758_write_8bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7758_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+int ade7758_reset(struct device *dev)
+{
+	int ret;
+	u8 val;
+	ade7758_spi_read_reg_8(dev,
+			ADE7758_OPMODE,
+			&val);
+	val |= 1 << 6; /* Software Chip Reset */
+	ret = ade7758_spi_write_reg_8(dev,
+			ADE7758_OPMODE,
+			val);
+
+	return ret;
+}
+
+static ssize_t ade7758_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -1;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return ade7758_reset(dev);
+	}
+	return -1;
+}
+
+static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_VPEAK);
+static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_VPEAK);
+static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_APHCAL);
+static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_BPHCAL);
+static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_CPHCAL);
+static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_WDIV);
+static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO,
+		ade7758_read_8bit,
+		ade7758_write_8bit,
+		ADE7758_VADIV);
+static IIO_DEV_ATTR_AIRMS(S_IRUGO,
+		ade7758_read_24bit,
+		NULL,
+		ADE7758_AIRMS);
+static IIO_DEV_ATTR_BIRMS(S_IRUGO,
+		ade7758_read_24bit,
+		NULL,
+		ADE7758_BIRMS);
+static IIO_DEV_ATTR_CIRMS(S_IRUGO,
+		ade7758_read_24bit,
+		NULL,
+		ADE7758_CIRMS);
+static IIO_DEV_ATTR_AVRMS(S_IRUGO,
+		ade7758_read_24bit,
+		NULL,
+		ADE7758_AVRMS);
+static IIO_DEV_ATTR_BVRMS(S_IRUGO,
+		ade7758_read_24bit,
+		NULL,
+		ADE7758_BVRMS);
+static IIO_DEV_ATTR_CVRMS(S_IRUGO,
+		ade7758_read_24bit,
+		NULL,
+		ADE7758_CVRMS);
+static IIO_DEV_ATTR_AIRMSOS(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_AIRMSOS);
+static IIO_DEV_ATTR_BIRMSOS(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_BIRMSOS);
+static IIO_DEV_ATTR_CIRMSOS(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_CIRMSOS);
+static IIO_DEV_ATTR_AVRMSOS(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_AVRMSOS);
+static IIO_DEV_ATTR_BVRMSOS(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_BVRMSOS);
+static IIO_DEV_ATTR_CVRMSOS(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_CVRMSOS);
+static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_AIGAIN);
+static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_BIGAIN);
+static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_CIGAIN);
+static IIO_DEV_ATTR_AVRMSGAIN(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_AVRMSGAIN);
+static IIO_DEV_ATTR_BVRMSGAIN(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_BVRMSGAIN);
+static IIO_DEV_ATTR_CVRMSGAIN(S_IWUSR | S_IRUGO,
+		ade7758_read_16bit,
+		ade7758_write_16bit,
+		ADE7758_CVRMSGAIN);
+
+int ade7758_set_irq(struct device *dev, bool enable)
+{
+	int ret;
+	u32 irqen;
+	ret = ade7758_spi_read_reg_24(dev, ADE7758_MASK, &irqen);
+	if (ret)
+		goto error_ret;
+
+	if (enable)
+		irqen |= 1 << 16; /* Enables an interrupt when a data is
+				     present in the waveform register */
+	else
+		irqen &= ~(1 << 16);
+
+	ret = ade7758_spi_write_reg_24(dev, ADE7758_MASK, irqen);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	return ret;
+}
+
+/* Power down the device */
+static int ade7758_stop_device(struct device *dev)
+{
+	int ret;
+	u8 val;
+	ade7758_spi_read_reg_8(dev,
+			ADE7758_OPMODE,
+			&val);
+	val |= 7 << 3;  /* ADE7758 powered down */
+	ret = ade7758_spi_write_reg_8(dev,
+			ADE7758_OPMODE,
+			val);
+
+	return ret;
+}
+
+static int ade7758_initial_setup(struct ade7758_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* use low spi speed for init */
+	st->us->mode = SPI_MODE_3;
+	spi_setup(st->us);
+
+	/* Disable IRQ */
+	ret = ade7758_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	ade7758_reset(dev);
+	msleep(ADE7758_STARTUP_DELAY);
+
+err_ret:
+	return ret;
+}
+
+static ssize_t ade7758_read_frequency(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret, len = 0;
+	u8 t;
+	int sps;
+	ret = ade7758_spi_read_reg_8(dev,
+			ADE7758_WAVMODE,
+			&t);
+	if (ret)
+		return ret;
+
+	t = (t >> 5) & 0x3;
+	sps = 26040 / (1 << t);
+
+	len = sprintf(buf, "%d SPS\n", sps);
+	return len;
+}
+
+static ssize_t ade7758_write_frequency(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	unsigned long val;
+	int ret;
+	u8 reg, t;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	t = (26040 / val);
+	if (t > 0)
+		t >>= 1;
+
+	if (t > 1)
+		st->us->max_speed_hz = ADE7758_SPI_SLOW;
+	else
+		st->us->max_speed_hz = ADE7758_SPI_FAST;
+
+	ret = ade7758_spi_read_reg_8(dev,
+			ADE7758_WAVMODE,
+			&reg);
+	if (ret)
+		goto out;
+
+	reg &= ~(5 << 3);
+	reg |= t << 5;
+
+	ret = ade7758_spi_write_reg_8(dev,
+			ADE7758_WAVMODE,
+			reg);
+
+out:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ade7758_read_waveform_type(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret, len = 0;
+	u8 t;
+	ret = ade7758_spi_read_reg_8(dev,
+			ADE7758_WAVMODE,
+			&t);
+	if (ret)
+		return ret;
+
+	t = (t >> 2) & 0x7;
+
+	len = sprintf(buf, "%d\n", t);
+
+	return len;
+}
+
+static ssize_t ade7758_write_waveform_type(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	unsigned long val;
+	int ret;
+	u8 reg;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val > 4)
+		return -EINVAL;
+
+	mutex_lock(&indio_dev->mlock);
+
+	ret = ade7758_spi_read_reg_8(dev,
+			ADE7758_WAVMODE,
+			&reg);
+	if (ret)
+		goto out;
+
+	reg &= ~(7 << 2);
+	reg |= val << 2;
+
+	ret = ade7758_spi_write_reg_8(dev,
+			ADE7758_WAVMODE,
+			reg);
+
+out:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit);
+static IIO_CONST_ATTR(temp_offset, "129 C");
+static IIO_CONST_ATTR(temp_scale, "4 C");
+
+static IIO_DEV_ATTR_AWATTHR(ade7758_read_16bit,
+		ADE7758_AWATTHR);
+static IIO_DEV_ATTR_BWATTHR(ade7758_read_16bit,
+		ADE7758_BWATTHR);
+static IIO_DEV_ATTR_CWATTHR(ade7758_read_16bit,
+		ADE7758_CWATTHR);
+static IIO_DEV_ATTR_AVARHR(ade7758_read_16bit,
+		ADE7758_AVARHR);
+static IIO_DEV_ATTR_BVARHR(ade7758_read_16bit,
+		ADE7758_BVARHR);
+static IIO_DEV_ATTR_CVARHR(ade7758_read_16bit,
+		ADE7758_CVARHR);
+static IIO_DEV_ATTR_AVAHR(ade7758_read_16bit,
+		ADE7758_AVAHR);
+static IIO_DEV_ATTR_BVAHR(ade7758_read_16bit,
+		ADE7758_BVAHR);
+static IIO_DEV_ATTR_CVAHR(ade7758_read_16bit,
+		ADE7758_CVAHR);
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+		ade7758_read_frequency,
+		ade7758_write_frequency);
+
+/**
+ * IIO_DEV_ATTR_WAVEFORM_TYPE - set the type of waveform.
+ * @_mode: sysfs file mode/permissions
+ * @_show: output method for the attribute
+ * @_store: input method for the attribute
+ **/
+#define IIO_DEV_ATTR_WAVEFORM_TYPE(_mode, _show, _store)			\
+	IIO_DEVICE_ATTR(waveform_type, _mode, _show, _store, 0)
+
+static IIO_DEV_ATTR_WAVEFORM_TYPE(S_IWUSR | S_IRUGO,
+		ade7758_read_waveform_type,
+		ade7758_write_waveform_type);
+
+static IIO_DEV_ATTR_RESET(ade7758_write_reset);
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
+
+static IIO_CONST_ATTR(name, "ade7758");
+
+static struct attribute *ade7758_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group ade7758_event_attribute_group = {
+	.attrs = ade7758_event_attributes,
+};
+
+static struct attribute *ade7758_attributes[] = {
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_waveform_type.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_awatthr.dev_attr.attr,
+	&iio_dev_attr_bwatthr.dev_attr.attr,
+	&iio_dev_attr_cwatthr.dev_attr.attr,
+	&iio_dev_attr_avarhr.dev_attr.attr,
+	&iio_dev_attr_bvarhr.dev_attr.attr,
+	&iio_dev_attr_cvarhr.dev_attr.attr,
+	&iio_dev_attr_avahr.dev_attr.attr,
+	&iio_dev_attr_bvahr.dev_attr.attr,
+	&iio_dev_attr_cvahr.dev_attr.attr,
+	&iio_dev_attr_vpeak.dev_attr.attr,
+	&iio_dev_attr_ipeak.dev_attr.attr,
+	&iio_dev_attr_aphcal.dev_attr.attr,
+	&iio_dev_attr_bphcal.dev_attr.attr,
+	&iio_dev_attr_cphcal.dev_attr.attr,
+	&iio_dev_attr_wdiv.dev_attr.attr,
+	&iio_dev_attr_vadiv.dev_attr.attr,
+	&iio_dev_attr_airms.dev_attr.attr,
+	&iio_dev_attr_birms.dev_attr.attr,
+	&iio_dev_attr_cirms.dev_attr.attr,
+	&iio_dev_attr_avrms.dev_attr.attr,
+	&iio_dev_attr_bvrms.dev_attr.attr,
+	&iio_dev_attr_cvrms.dev_attr.attr,
+	&iio_dev_attr_aigain.dev_attr.attr,
+	&iio_dev_attr_bigain.dev_attr.attr,
+	&iio_dev_attr_cigain.dev_attr.attr,
+	&iio_dev_attr_avrmsgain.dev_attr.attr,
+	&iio_dev_attr_bvrmsgain.dev_attr.attr,
+	&iio_dev_attr_cvrmsgain.dev_attr.attr,
+	&iio_dev_attr_airmsos.dev_attr.attr,
+	&iio_dev_attr_birmsos.dev_attr.attr,
+	&iio_dev_attr_cirmsos.dev_attr.attr,
+	&iio_dev_attr_avrmsos.dev_attr.attr,
+	&iio_dev_attr_bvrmsos.dev_attr.attr,
+	&iio_dev_attr_cvrmsos.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ade7758_attribute_group = {
+	.attrs = ade7758_attributes,
+};
+
+
+
+static int __devinit ade7758_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct ade7758_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADE7758_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADE7758_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &ade7758_event_attribute_group;
+	st->indio_dev->attrs = &ade7758_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = ade7758_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = ade7758_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_FALLING,
+				"ade7758");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = ade7758_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = ade7758_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7758_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	ade7758_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	ade7758_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int ade7758_remove(struct spi_device *spi)
+{
+	int ret;
+	struct ade7758_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	ret = ade7758_stop_device(&(indio_dev->dev));
+	if (ret)
+		goto err_ret;
+
+	flush_scheduled_work();
+
+	ade7758_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	ade7758_uninitialize_ring(indio_dev->ring);
+	iio_device_unregister(indio_dev);
+	ade7758_unconfigure_ring(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+
+err_ret:
+	return ret;
+}
+
+static struct spi_driver ade7758_driver = {
+	.driver = {
+		.name = "ade7758",
+		.owner = THIS_MODULE,
+	},
+	.probe = ade7758_probe,
+	.remove = __devexit_p(ade7758_remove),
+};
+
+static __init int ade7758_init(void)
+{
+	return spi_register_driver(&ade7758_driver);
+}
+module_init(ade7758_init);
+
+static __exit void ade7758_exit(void)
+{
+	spi_unregister_driver(&ade7758_driver);
+}
+module_exit(ade7758_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
new file mode 100644
index 0000000..274b4a0
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -0,0 +1,212 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_sw.h"
+#include "../accel/accel.h"
+#include "../trigger.h"
+#include "ade7758.h"
+
+/**
+ * combine_8_to_32() utility function to munge to u8s into u32
+ **/
+static inline u32 combine_8_to_32(u8 lower, u8 mid, u8 upper)
+{
+	u32 _lower = lower;
+	u32 _mid = mid;
+	u32 _upper = upper;
+
+	return _lower | (_mid << 8) | (_upper << 16);
+}
+
+static IIO_SCAN_EL_C(wform, ADE7758_SCAN_WFORM, ADE7758_WFORM, NULL);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(wform, s, 24, 32);
+static IIO_SCAN_EL_TIMESTAMP(1);
+static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
+
+static struct attribute *ade7758_scan_el_attrs[] = {
+	&iio_scan_el_wform.dev_attr.attr,
+	&iio_const_attr_wform_index.dev_attr.attr,
+	&iio_const_attr_wform_type.dev_attr.attr,
+	&iio_scan_el_timestamp.dev_attr.attr,
+	&iio_const_attr_timestamp_index.dev_attr.attr,
+	&iio_const_attr_timestamp_type.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ade7758_scan_el_group = {
+	.attrs = ade7758_scan_el_attrs,
+	.name = "scan_elements",
+};
+
+/**
+ * ade7758_poll_func_th() top half interrupt handler called by trigger
+ * @private_data:	iio_dev
+ **/
+static void ade7758_poll_func_th(struct iio_dev *indio_dev, s64 time)
+{
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	st->last_timestamp = time;
+	schedule_work(&st->work_trigger_to_ring);
+	/* Indicate that this interrupt is being handled */
+
+	/* Technically this is trigger related, but without this
+	 * handler running there is currently no way for the interrupt
+	 * to clear.
+	 */
+}
+
+/**
+ * ade7758_spi_read_burst() - read all data registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @rx: somewhere to pass back the value read (min size is 24 bytes)
+ **/
+static int ade7758_spi_read_burst(struct device *dev, u8 *rx)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = rx,
+			.bits_per_word = 8,
+			.len = 4,
+		}, {
+			.tx_buf = st->tx + 4,
+			.rx_buf = rx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+	st->tx[4] = ADE7758_READ_REG(ADE7758_WFORM);
+	st->tx[5] = 0;
+	st->tx[6] = 0;
+	st->tx[7] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when reading WFORM value\n");
+
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+ * specific to be rolled into the core.
+ */
+static void ade7758_trigger_bh_to_ring(struct work_struct *work_s)
+{
+	struct ade7758_state *st
+		= container_of(work_s, struct ade7758_state,
+			       work_trigger_to_ring);
+	struct iio_ring_buffer *ring = st->indio_dev->ring;
+
+	int i = 0;
+	s32 *data;
+	size_t datasize = ring->access.get_bytes_per_datum(ring);
+
+	data = kmalloc(datasize, GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed in ring bh");
+		return;
+	}
+
+	if (ring->scan_count)
+		if (ade7758_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
+			for (; i < ring->scan_count; i++)
+				data[i] = combine_8_to_32(st->rx[i*2+2],
+						st->rx[i*2+1],
+						st->rx[i*2]);
+
+	/* Guaranteed to be aligned with 8 byte boundary */
+	if (ring->scan_timestamp)
+		*((s64 *)
+		(((u32)data + 4 * ring->scan_count + 4) & ~0x7)) =
+			st->last_timestamp;
+
+	ring->access.store_to(ring,
+			      (u8 *)data,
+			      st->last_timestamp);
+
+	iio_trigger_notify_done(st->indio_dev->trig);
+	kfree(data);
+
+	return;
+}
+
+void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
+{
+	kfree(indio_dev->pollfunc);
+	iio_sw_rb_free(indio_dev->ring);
+}
+
+int ade7758_configure_ring(struct iio_dev *indio_dev)
+{
+	int ret = 0;
+	struct ade7758_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring;
+	INIT_WORK(&st->work_trigger_to_ring, ade7758_trigger_bh_to_ring);
+
+	ring = iio_sw_rb_allocate(indio_dev);
+	if (!ring) {
+		ret = -ENOMEM;
+		return ret;
+	}
+	indio_dev->ring = ring;
+	/* Effectively select the ring buffer implementation */
+	iio_ring_sw_register_funcs(&ring->access);
+	ring->bpe = 4;
+	ring->scan_el_attrs = &ade7758_scan_el_group;
+	ring->scan_timestamp = true;
+	ring->preenable = &iio_sw_ring_preenable;
+	ring->postenable = &iio_triggered_ring_postenable;
+	ring->predisable = &iio_triggered_ring_predisable;
+	ring->owner = THIS_MODULE;
+
+	/* Set default scan mode */
+	iio_scan_mask_set(ring, iio_scan_el_wform.number);
+
+	ret = iio_alloc_pollfunc(indio_dev, NULL, &ade7758_poll_func_th);
+	if (ret)
+		goto error_iio_sw_rb_free;
+
+	indio_dev->modes |= INDIO_RING_TRIGGERED;
+	return 0;
+
+error_iio_sw_rb_free:
+	iio_sw_rb_free(indio_dev->ring);
+	return ret;
+}
+
+int ade7758_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return iio_ring_buffer_register(ring, 0);
+}
+
+void ade7758_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+	iio_ring_buffer_unregister(ring);
+}
diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c
new file mode 100644
index 0000000..60abca0
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7758_trigger.c
@@ -0,0 +1,125 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../trigger.h"
+#include "ade7758.h"
+
+/**
+ * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig
+ **/
+static int ade7758_data_rdy_trig_poll(struct iio_dev *dev_info,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
+{
+	struct ade7758_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_trigger *trig = st->trig;
+
+	iio_trigger_poll(trig, timestamp);
+
+	return IRQ_HANDLED;
+}
+
+IIO_EVENT_SH(data_rdy_trig, &ade7758_data_rdy_trig_poll);
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static struct attribute *ade7758_trigger_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group ade7758_trigger_attr_group = {
+	.attrs = ade7758_trigger_attrs,
+};
+
+/**
+ * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
+ **/
+static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
+						bool state)
+{
+	struct ade7758_state *st = trig->private_data;
+	struct iio_dev *indio_dev = st->indio_dev;
+	int ret = 0;
+
+	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
+	ret = ade7758_set_irq(&st->indio_dev->dev, state);
+	if (state == false) {
+		iio_remove_event_from_list(&iio_event_data_rdy_trig,
+					   &indio_dev->interrupts[0]
+					   ->ev_list);
+		/* possible quirk with handler currently worked around
+		   by ensuring the work queue is empty */
+		flush_scheduled_work();
+	} else {
+		iio_add_event_to_list(&iio_event_data_rdy_trig,
+				      &indio_dev->interrupts[0]->ev_list);
+	}
+	return ret;
+}
+
+/**
+ * ade7758_trig_try_reen() try renabling irq for data rdy trigger
+ * @trig:	the datardy trigger
+ **/
+static int ade7758_trig_try_reen(struct iio_trigger *trig)
+{
+	struct ade7758_state *st = trig->private_data;
+	enable_irq(st->us->irq);
+	/* irq reenabled so success! */
+	return 0;
+}
+
+int ade7758_probe_trigger(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct ade7758_state *st = indio_dev->dev_data;
+
+	st->trig = iio_allocate_trigger();
+	st->trig->name = kasprintf(GFP_KERNEL,
+				"ade7758-dev%d",
+				indio_dev->id);
+	if (!st->trig->name) {
+		ret = -ENOMEM;
+		goto error_free_trig;
+	}
+	st->trig->dev.parent = &st->us->dev;
+	st->trig->owner = THIS_MODULE;
+	st->trig->private_data = st;
+	st->trig->set_trigger_state = &ade7758_data_rdy_trigger_set_state;
+	st->trig->try_reenable = &ade7758_trig_try_reen;
+	st->trig->control_attrs = &ade7758_trigger_attr_group;
+	ret = iio_trigger_register(st->trig);
+
+	/* select default trigger */
+	indio_dev->trig = st->trig;
+	if (ret)
+		goto error_free_trig_name;
+
+	return 0;
+
+error_free_trig_name:
+	kfree(st->trig->name);
+error_free_trig:
+	iio_free_trigger(st->trig);
+
+	return ret;
+}
+
+void ade7758_remove_trigger(struct iio_dev *indio_dev)
+{
+	struct ade7758_state *state = indio_dev->dev_data;
+
+	iio_trigger_unregister(state->trig);
+	kfree(state->trig->name);
+	iio_free_trigger(state->trig);
+}
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
new file mode 100644
index 0000000..fafc3c1
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -0,0 +1,670 @@
+/*
+ * ADE7759 Active Energy Metering IC with di/dt Sensor Interface Driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "meter.h"
+#include "ade7759.h"
+
+int ade7759_spi_write_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 val)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7759_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7759_WRITE_REG(reg_address);
+	st->tx[1] = val;
+
+	ret = spi_write(st->us, st->tx, 2);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7759_spi_write_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7759_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 3,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7759_WRITE_REG(reg_address);
+	st->tx[1] = (value >> 8) & 0xFF;
+	st->tx[2] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7759_spi_read_reg_8(struct device *dev,
+		u8 reg_address,
+		u8 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7759_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7759_READ_REG(reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = st->rx[1];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7759_spi_read_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7759_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 3,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7759_READ_REG(reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[1] << 8) | st->rx[2];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7759_spi_read_reg_40(struct device *dev,
+		u8 reg_address,
+		u64 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7759_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 6,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7759_READ_REG(reg_address);
+	memset(&st->tx[1], 0 , 5);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 40 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = ((u64)st->rx[1] << 32) | (st->rx[2] << 24) |
+		(st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t ade7759_read_8bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u8 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7759_spi_read_reg_8(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7759_read_16bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7759_spi_read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7759_read_40bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u64 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = ade7759_spi_read_reg_40(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%llu\n", val);
+}
+
+static ssize_t ade7759_write_8bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7759_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int ade7759_reset(struct device *dev)
+{
+	int ret;
+	u16 val;
+	ade7759_spi_read_reg_16(dev,
+			ADE7759_MODE,
+			&val);
+	val |= 1 << 6; /* Software Chip Reset */
+	ret = ade7759_spi_write_reg_16(dev,
+			ADE7759_MODE,
+			val);
+
+	return ret;
+}
+
+static ssize_t ade7759_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -1;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return ade7759_reset(dev);
+	}
+	return -1;
+}
+
+static IIO_DEV_ATTR_AENERGY(ade7759_read_40bit, ADE7759_AENERGY);
+static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
+		ade7759_read_16bit,
+		ade7759_write_16bit,
+		ADE7759_CFDEN);
+static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_CFNUM);
+static IIO_DEV_ATTR_CHKSUM(ade7759_read_8bit, ADE7759_CHKSUM);
+static IIO_DEV_ATTR_PHCAL(S_IWUSR | S_IRUGO,
+		ade7759_read_16bit,
+		ade7759_write_16bit,
+		ADE7759_PHCAL);
+static IIO_DEV_ATTR_APOS(S_IWUSR | S_IRUGO,
+		ade7759_read_16bit,
+		ade7759_write_16bit,
+		ADE7759_APOS);
+static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_SAGCYC);
+static IIO_DEV_ATTR_SAGLVL(S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_SAGLVL);
+static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_LINECYC);
+static IIO_DEV_ATTR_LENERGY(ade7759_read_40bit, ADE7759_LENERGY);
+static IIO_DEV_ATTR_PGA_GAIN(S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_GAIN);
+static IIO_DEV_ATTR_ACTIVE_POWER_GAIN(S_IWUSR | S_IRUGO,
+		ade7759_read_16bit,
+		ade7759_write_16bit,
+		ADE7759_APGAIN);
+static IIO_DEV_ATTR_CH_OFF(1, S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_CH1OS);
+static IIO_DEV_ATTR_CH_OFF(2, S_IWUSR | S_IRUGO,
+		ade7759_read_8bit,
+		ade7759_write_8bit,
+		ADE7759_CH2OS);
+
+static int ade7759_set_irq(struct device *dev, bool enable)
+{
+	int ret;
+	u8 irqen;
+	ret = ade7759_spi_read_reg_8(dev, ADE7759_IRQEN, &irqen);
+	if (ret)
+		goto error_ret;
+
+	if (enable)
+		irqen |= 1 << 3; /* Enables an interrupt when a data is
+				    present in the waveform register */
+	else
+		irqen &= ~(1 << 3);
+
+	ret = ade7759_spi_write_reg_8(dev, ADE7759_IRQEN, irqen);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	return ret;
+}
+
+/* Power down the device */
+int ade7759_stop_device(struct device *dev)
+{
+	int ret;
+	u16 val;
+	ade7759_spi_read_reg_16(dev,
+			ADE7759_MODE,
+			&val);
+	val |= 1 << 4;  /* AD converters can be turned off */
+	ret = ade7759_spi_write_reg_16(dev,
+			ADE7759_MODE,
+			val);
+
+	return ret;
+}
+
+static int ade7759_initial_setup(struct ade7759_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* use low spi speed for init */
+	st->us->mode = SPI_MODE_3;
+	spi_setup(st->us);
+
+	/* Disable IRQ */
+	ret = ade7759_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	ade7759_reset(dev);
+	msleep(ADE7759_STARTUP_DELAY);
+
+err_ret:
+	return ret;
+}
+
+static ssize_t ade7759_read_frequency(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret, len = 0;
+	u16 t;
+	int sps;
+	ret = ade7759_spi_read_reg_16(dev,
+			ADE7759_MODE,
+			&t);
+	if (ret)
+		return ret;
+
+	t = (t >> 3) & 0x3;
+	sps = 27900 / (1 + t);
+
+	len = sprintf(buf, "%d SPS\n", sps);
+	return len;
+}
+
+static ssize_t ade7759_write_frequency(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7759_state *st = iio_dev_get_devdata(indio_dev);
+	unsigned long val;
+	int ret;
+	u16 reg, t;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	t = (27900 / val);
+	if (t > 0)
+		t--;
+
+	if (t > 1)
+		st->us->max_speed_hz = ADE7759_SPI_SLOW;
+	else
+		st->us->max_speed_hz = ADE7759_SPI_FAST;
+
+	ret = ade7759_spi_read_reg_16(dev,
+			ADE7759_MODE,
+			&reg);
+	if (ret)
+		goto out;
+
+	reg &= ~(3 << 13);
+	reg |= t << 13;
+
+	ret = ade7759_spi_write_reg_16(dev,
+			ADE7759_MODE,
+			reg);
+
+out:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+static IIO_DEV_ATTR_TEMP_RAW(ade7759_read_8bit);
+static IIO_CONST_ATTR(temp_offset, "70 C");
+static IIO_CONST_ATTR(temp_scale, "1 C");
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+		ade7759_read_frequency,
+		ade7759_write_frequency);
+
+static IIO_DEV_ATTR_RESET(ade7759_write_reset);
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
+
+static IIO_CONST_ATTR(name, "ade7759");
+
+static struct attribute *ade7759_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group ade7759_event_attribute_group = {
+	.attrs = ade7759_event_attributes,
+};
+
+static struct attribute *ade7759_attributes[] = {
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_const_attr_temp_offset.dev_attr.attr,
+	&iio_const_attr_temp_scale.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_phcal.dev_attr.attr,
+	&iio_dev_attr_cfden.dev_attr.attr,
+	&iio_dev_attr_aenergy.dev_attr.attr,
+	&iio_dev_attr_cfnum.dev_attr.attr,
+	&iio_dev_attr_apos.dev_attr.attr,
+	&iio_dev_attr_sagcyc.dev_attr.attr,
+	&iio_dev_attr_saglvl.dev_attr.attr,
+	&iio_dev_attr_linecyc.dev_attr.attr,
+	&iio_dev_attr_lenergy.dev_attr.attr,
+	&iio_dev_attr_chksum.dev_attr.attr,
+	&iio_dev_attr_pga_gain.dev_attr.attr,
+	&iio_dev_attr_active_power_gain.dev_attr.attr,
+	&iio_dev_attr_choff_1.dev_attr.attr,
+	&iio_dev_attr_choff_2.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ade7759_attribute_group = {
+	.attrs = ade7759_attributes,
+};
+
+static int __devinit ade7759_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct ade7759_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADE7759_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADE7759_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &ade7759_event_attribute_group;
+	st->indio_dev->attrs = &ade7759_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = ade7759_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = ade7759_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq) {
+		ret = iio_register_interrupt_line(spi->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_FALLING,
+				"ade7759");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = ade7759_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = ade7759_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7759_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	ade7759_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	ade7759_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int ade7759_remove(struct spi_device *spi)
+{
+	int ret;
+	struct ade7759_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	ret = ade7759_stop_device(&(indio_dev->dev));
+	if (ret)
+		goto err_ret;
+
+	flush_scheduled_work();
+
+	ade7759_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	ade7759_uninitialize_ring(indio_dev->ring);
+	ade7759_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+
+err_ret:
+	return ret;
+}
+
+static struct spi_driver ade7759_driver = {
+	.driver = {
+		.name = "ade7759",
+		.owner = THIS_MODULE,
+	},
+	.probe = ade7759_probe,
+	.remove = __devexit_p(ade7759_remove),
+};
+
+static __init int ade7759_init(void)
+{
+	return spi_register_driver(&ade7759_driver);
+}
+module_init(ade7759_init);
+
+static __exit void ade7759_exit(void)
+{
+	spi_unregister_driver(&ade7759_driver);
+}
+module_exit(ade7759_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7759 Active Energy Metering IC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h
new file mode 100644
index 0000000..813dea2
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7759.h
@@ -0,0 +1,122 @@
+#ifndef _ADE7759_H
+#define _ADE7759_H
+
+#define ADE7759_WAVEFORM  0x01
+#define ADE7759_AENERGY   0x02
+#define ADE7759_RSTENERGY 0x03
+#define ADE7759_STATUS    0x04
+#define ADE7759_RSTSTATUS 0x05
+#define ADE7759_MODE      0x06
+#define ADE7759_CFDEN     0x07
+#define ADE7759_CH1OS     0x08
+#define ADE7759_CH2OS     0x09
+#define ADE7759_GAIN      0x0A
+#define ADE7759_APGAIN    0x0B
+#define ADE7759_PHCAL     0x0C
+#define ADE7759_APOS      0x0D
+#define ADE7759_ZXTOUT    0x0E
+#define ADE7759_SAGCYC    0x0F
+#define ADE7759_IRQEN     0x10
+#define ADE7759_SAGLVL    0x11
+#define ADE7759_TEMP      0x12
+#define ADE7759_LINECYC   0x13
+#define ADE7759_LENERGY   0x14
+#define ADE7759_CFNUM     0x15
+#define ADE7759_CHKSUM    0x1E
+#define ADE7759_DIEREV    0x1F
+
+#define ADE7759_READ_REG(a)    a
+#define ADE7759_WRITE_REG(a) ((a) | 0x80)
+
+#define ADE7759_MAX_TX    6
+#define ADE7759_MAX_RX    6
+#define ADE7759_STARTUP_DELAY 1
+
+#define ADE7759_SPI_SLOW	(u32)(300 * 1000)
+#define ADE7759_SPI_BURST	(u32)(1000 * 1000)
+#define ADE7759_SPI_FAST	(u32)(2000 * 1000)
+
+#define DRIVER_NAME		"ade7759"
+
+/**
+ * struct ade7759_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct ade7759_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum ade7759_scan {
+	ADE7759_SCAN_ACTIVE_POWER,
+	ADE7759_SCAN_CH1_CH2,
+	ADE7759_SCAN_CH1,
+	ADE7759_SCAN_CH2,
+};
+
+void ade7759_remove_trigger(struct iio_dev *indio_dev);
+int ade7759_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t ade7759_read_data_from_ring(struct device *dev,
+		struct device_attribute *attr,
+		char *buf);
+
+
+int ade7759_configure_ring(struct iio_dev *indio_dev);
+void ade7759_unconfigure_ring(struct iio_dev *indio_dev);
+
+int ade7759_initialize_ring(struct iio_ring_buffer *ring);
+void ade7759_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void ade7759_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7759_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+ade7759_read_data_from_ring(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return 0;
+}
+
+static int ade7759_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+static inline void ade7759_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7759_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+static inline void ade7759_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+#endif /* CONFIG_IIO_RING_BUFFER */
+
+#endif
diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c
new file mode 100644
index 0000000..4578e7b
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7854-i2c.c
@@ -0,0 +1,272 @@
+/*
+ * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (I2C Bus)
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "../iio.h"
+#include "ade7854.h"
+
+static int ade7854_i2c_write_reg_8(struct device *dev,
+		u16 reg_address,
+		u8 value)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+	st->tx[2] = value;
+
+	ret = i2c_master_send(st->i2c, st->tx, 3);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_i2c_write_reg_16(struct device *dev,
+		u16 reg_address,
+		u16 value)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+	st->tx[2] = (value >> 8) & 0xFF;
+	st->tx[3] = value & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 4);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_i2c_write_reg_24(struct device *dev,
+		u16 reg_address,
+		u32 value)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+	st->tx[2] = (value >> 16) & 0xFF;
+	st->tx[3] = (value >> 8) & 0xFF;
+	st->tx[4] = value & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 5);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_i2c_write_reg_32(struct device *dev,
+		u16 reg_address,
+		u32 value)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+	st->tx[2] = (value >> 24) & 0xFF;
+	st->tx[3] = (value >> 16) & 0xFF;
+	st->tx[4] = (value >> 8) & 0xFF;
+	st->tx[5] = value & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 6);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_i2c_read_reg_8(struct device *dev,
+		u16 reg_address,
+		u8 *val)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 2);
+	if (ret)
+		goto out;
+
+	ret = i2c_master_recv(st->i2c, st->rx, 1);
+	if (ret)
+		goto out;
+
+	*val = st->rx[0];
+out:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7854_i2c_read_reg_16(struct device *dev,
+		u16 reg_address,
+		u16 *val)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 2);
+	if (ret)
+		goto out;
+
+	ret = i2c_master_recv(st->i2c, st->rx, 2);
+	if (ret)
+		goto out;
+
+	*val = (st->rx[0] << 8) | st->rx[1];
+out:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7854_i2c_read_reg_24(struct device *dev,
+		u16 reg_address,
+		u32 *val)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 2);
+	if (ret)
+		goto out;
+
+	ret = i2c_master_recv(st->i2c, st->rx, 3);
+	if (ret)
+		goto out;
+
+	*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
+out:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7854_i2c_read_reg_32(struct device *dev,
+		u16 reg_address,
+		u32 *val)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = (reg_address >> 8) & 0xFF;
+	st->tx[1] = reg_address & 0xFF;
+
+	ret = i2c_master_send(st->i2c, st->tx, 2);
+	if (ret)
+		goto out;
+
+	ret = i2c_master_recv(st->i2c, st->rx, 3);
+	if (ret)
+		goto out;
+
+	*val = (st->rx[0] << 24) | (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+out:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int __devinit ade7854_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int ret;
+	struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		return ret;
+	}
+
+	i2c_set_clientdata(client, st);
+	st->read_reg_8 = ade7854_i2c_read_reg_8;
+	st->read_reg_16 = ade7854_i2c_read_reg_16;
+	st->read_reg_24 = ade7854_i2c_read_reg_24;
+	st->read_reg_32 = ade7854_i2c_read_reg_32;
+	st->write_reg_8 = ade7854_i2c_write_reg_8;
+	st->write_reg_16 = ade7854_i2c_write_reg_16;
+	st->write_reg_24 = ade7854_i2c_write_reg_24;
+	st->write_reg_32 = ade7854_i2c_write_reg_32;
+	st->i2c = client;
+	st->irq = client->irq;
+
+	ret = ade7854_probe(st, &client->dev);
+	if (ret) {
+		kfree(st);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int __devexit ade7854_i2c_remove(struct i2c_client *client)
+{
+	return ade7854_remove(i2c_get_clientdata(client));
+}
+
+static const struct i2c_device_id ade7854_id[] = {
+	{ "ade7854", 0 },
+	{ "ade7858", 0 },
+	{ "ade7868", 0 },
+	{ "ade7878", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ade7854_id);
+
+static struct i2c_driver ade7854_i2c_driver = {
+	.driver = {
+		.name = "ade7854",
+	},
+	.probe    = ade7854_i2c_probe,
+	.remove   = __devexit_p(ade7854_i2c_remove),
+	.id_table = ade7854_id,
+};
+
+static __init int ade7854_i2c_init(void)
+{
+	return i2c_add_driver(&ade7854_i2c_driver);
+}
+module_init(ade7854_i2c_init);
+
+static __exit void ade7854_i2c_exit(void)
+{
+	i2c_del_driver(&ade7854_i2c_driver);
+}
+module_exit(ade7854_i2c_exit);
+
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC I2C Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
new file mode 100644
index 0000000..fe58103e
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -0,0 +1,360 @@
+/*
+ * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (SPI Bus)
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+
+#include "../iio.h"
+#include "ade7854.h"
+
+static int ade7854_spi_write_reg_8(struct device *dev,
+		u16 reg_address,
+		u8 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 4,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7854_WRITE_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_spi_write_reg_16(struct device *dev,
+		u16 reg_address,
+		u16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 5,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7854_WRITE_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = (value >> 8) & 0xFF;
+	st->tx[4] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_spi_write_reg_24(struct device *dev,
+		u16 reg_address,
+		u32 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 6,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7854_WRITE_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = (value >> 16) & 0xFF;
+	st->tx[4] = (value >> 8) & 0xFF;
+	st->tx[5] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_spi_write_reg_32(struct device *dev,
+		u16 reg_address,
+		u32 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 7,
+		}
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7854_WRITE_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = (value >> 24) & 0xFF;
+	st->tx[4] = (value >> 16) & 0xFF;
+	st->tx[5] = (value >> 8) & 0xFF;
+	st->tx[6] = value & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int ade7854_spi_read_reg_8(struct device *dev,
+		u16 reg_address,
+		u8 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+
+	st->tx[0] = ADE7854_READ_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	if (ret) {
+		dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = st->rx[3];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7854_spi_read_reg_16(struct device *dev,
+		u16 reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 5,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADE7854_READ_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = 0;
+	st->tx[4] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	if (ret) {
+		dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[3] << 8) | st->rx[4];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7854_spi_read_reg_24(struct device *dev,
+		u16 reg_address,
+		u32 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 6,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+
+	st->tx[0] = ADE7854_READ_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = 0;
+	st->tx[4] = 0;
+	st->tx[5] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	if (ret) {
+		dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int ade7854_spi_read_reg_32(struct device *dev,
+		u16 reg_address,
+		u32 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 7,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+
+	st->tx[0] = ADE7854_READ_REG;
+	st->tx[1] = (reg_address >> 8) & 0xFF;
+	st->tx[2] = reg_address & 0xFF;
+	st->tx[3] = 0;
+	st->tx[4] = 0;
+	st->tx[5] = 0;
+	st->tx[6] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(xfers, &msg);
+	ret = spi_sync(st->spi, &msg);
+	if (ret) {
+		dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X",
+				reg_address);
+		goto error_ret;
+	}
+	*val = (st->rx[3] << 24) | (st->rx[4] << 16) | (st->rx[5] << 8) | st->rx[6];
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static int __devinit ade7854_spi_probe(struct spi_device *spi)
+{
+	int ret;
+	struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		return ret;
+	}
+
+	spi_set_drvdata(spi, st);
+	st->read_reg_8 = ade7854_spi_read_reg_8;
+	st->read_reg_16 = ade7854_spi_read_reg_16;
+	st->read_reg_24 = ade7854_spi_read_reg_24;
+	st->read_reg_32 = ade7854_spi_read_reg_32;
+	st->write_reg_8 = ade7854_spi_write_reg_8;
+	st->write_reg_16 = ade7854_spi_write_reg_16;
+	st->write_reg_24 = ade7854_spi_write_reg_24;
+	st->write_reg_32 = ade7854_spi_write_reg_32;
+	st->irq = spi->irq;
+	st->spi = spi;
+
+	ret = ade7854_probe(st, &spi->dev);
+	if (ret) {
+		kfree(st);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ade7854_spi_remove(struct spi_device *spi)
+{
+	ade7854_remove(spi_get_drvdata(spi));
+
+	return 0;
+}
+
+static struct spi_driver ade7854_driver = {
+	.driver = {
+		.name = "ade7854",
+		.owner = THIS_MODULE,
+	},
+	.probe = ade7854_spi_probe,
+	.remove = __devexit_p(ade7854_spi_remove),
+};
+
+static __init int ade7854_init(void)
+{
+	return spi_register_driver(&ade7854_driver);
+}
+module_init(ade7854_init);
+
+static __exit void ade7854_exit(void)
+{
+	spi_unregister_driver(&ade7854_driver);
+}
+module_exit(ade7854_exit);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC SPI Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
new file mode 100644
index 0000000..a13d504
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -0,0 +1,680 @@
+/*
+ * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "meter.h"
+#include "ade7854.h"
+
+static ssize_t ade7854_read_8bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u8 val = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = st->read_reg_8(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7854_read_16bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 val = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = st->read_reg_16(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7854_read_24bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u32 val = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = st->read_reg_24(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val & 0xFFFFFF);
+}
+
+static ssize_t ade7854_read_32bit(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u32 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	ret = st->read_reg_32(dev, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ade7854_write_8bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = st->write_reg_8(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7854_write_16bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = st->write_reg_16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7854_write_24bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = st->write_reg_24(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t ade7854_write_32bit(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = st->write_reg_32(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static int ade7854_reset(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	int ret;
+	u16 val;
+
+	st->read_reg_16(dev, ADE7854_CONFIG, &val);
+	val |= 1 << 7; /* Software Chip Reset */
+	ret = st->write_reg_16(dev, ADE7854_CONFIG, val);
+
+	return ret;
+}
+
+
+static ssize_t ade7854_write_reset(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	if (len < 1)
+		return -1;
+	switch (buf[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		return ade7854_reset(dev);
+	}
+	return -1;
+}
+
+static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_AIGAIN);
+static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_BIGAIN);
+static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_CIGAIN);
+static IIO_DEV_ATTR_NIGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_NIGAIN);
+static IIO_DEV_ATTR_AVGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_AVGAIN);
+static IIO_DEV_ATTR_BVGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_BVGAIN);
+static IIO_DEV_ATTR_CVGAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_CVGAIN);
+static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_AVAGAIN);
+static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_BVAGAIN);
+static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_CVAGAIN);
+static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_AWATTOS);
+static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_BWATTOS);
+static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_CWATTOS);
+static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_AVARGAIN);
+static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_BVARGAIN);
+static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_CVARGAIN);
+static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_AVAROS);
+static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_BVAROS);
+static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO,
+		ade7854_read_24bit,
+		ade7854_write_24bit,
+		ADE7854_CVAROS);
+static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
+		ade7854_read_32bit,
+		ade7854_write_32bit,
+		ADE7854_VPEAK);
+static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
+		ade7854_read_32bit,
+		ade7854_write_32bit,
+		ADE7854_VPEAK);
+static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_APHCAL);
+static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_BPHCAL);
+static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_CPHCAL);
+static IIO_DEV_ATTR_CF1DEN(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_CF1DEN);
+static IIO_DEV_ATTR_CF2DEN(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_CF2DEN);
+static IIO_DEV_ATTR_CF3DEN(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_CF3DEN);
+static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_LINECYC);
+static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO,
+		ade7854_read_8bit,
+		ade7854_write_8bit,
+		ADE7854_SAGCYC);
+static IIO_DEV_ATTR_CFCYC(S_IWUSR | S_IRUGO,
+		ade7854_read_8bit,
+		ade7854_write_8bit,
+		ADE7854_CFCYC);
+static IIO_DEV_ATTR_PEAKCYC(S_IWUSR | S_IRUGO,
+		ade7854_read_8bit,
+		ade7854_write_8bit,
+		ADE7854_PEAKCYC);
+static IIO_DEV_ATTR_CHKSUM(ade7854_read_24bit,
+		ADE7854_CHECKSUM);
+static IIO_DEV_ATTR_ANGLE0(ade7854_read_24bit,
+		ADE7854_ANGLE0);
+static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit,
+		ADE7854_ANGLE1);
+static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit,
+		ADE7854_ANGLE2);
+static IIO_DEV_ATTR_AIRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_AIRMS);
+static IIO_DEV_ATTR_BIRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_BIRMS);
+static IIO_DEV_ATTR_CIRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_CIRMS);
+static IIO_DEV_ATTR_NIRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_NIRMS);
+static IIO_DEV_ATTR_AVRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_AVRMS);
+static IIO_DEV_ATTR_BVRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_BVRMS);
+static IIO_DEV_ATTR_CVRMS(S_IRUGO,
+		ade7854_read_24bit,
+		NULL,
+		ADE7854_CVRMS);
+static IIO_DEV_ATTR_AIRMSOS(S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_AIRMSOS);
+static IIO_DEV_ATTR_BIRMSOS(S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_BIRMSOS);
+static IIO_DEV_ATTR_CIRMSOS(S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_CIRMSOS);
+static IIO_DEV_ATTR_AVRMSOS(S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_AVRMSOS);
+static IIO_DEV_ATTR_BVRMSOS(S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_BVRMSOS);
+static IIO_DEV_ATTR_CVRMSOS(S_IRUGO,
+		ade7854_read_16bit,
+		ade7854_write_16bit,
+		ADE7854_CVRMSOS);
+static IIO_DEV_ATTR_VOLT_A(ade7854_read_24bit,
+		ADE7854_VAWV);
+static IIO_DEV_ATTR_VOLT_B(ade7854_read_24bit,
+		ADE7854_VBWV);
+static IIO_DEV_ATTR_VOLT_C(ade7854_read_24bit,
+		ADE7854_VCWV);
+static IIO_DEV_ATTR_CURRENT_A(ade7854_read_24bit,
+		ADE7854_IAWV);
+static IIO_DEV_ATTR_CURRENT_B(ade7854_read_24bit,
+		ADE7854_IBWV);
+static IIO_DEV_ATTR_CURRENT_C(ade7854_read_24bit,
+		ADE7854_ICWV);
+static IIO_DEV_ATTR_AWATTHR(ade7854_read_32bit,
+		ADE7854_AWATTHR);
+static IIO_DEV_ATTR_BWATTHR(ade7854_read_32bit,
+		ADE7854_BWATTHR);
+static IIO_DEV_ATTR_CWATTHR(ade7854_read_32bit,
+		ADE7854_CWATTHR);
+static IIO_DEV_ATTR_AFWATTHR(ade7854_read_32bit,
+		ADE7854_AFWATTHR);
+static IIO_DEV_ATTR_BFWATTHR(ade7854_read_32bit,
+		ADE7854_BFWATTHR);
+static IIO_DEV_ATTR_CFWATTHR(ade7854_read_32bit,
+		ADE7854_CFWATTHR);
+static IIO_DEV_ATTR_AVARHR(ade7854_read_32bit,
+		ADE7854_AVARHR);
+static IIO_DEV_ATTR_BVARHR(ade7854_read_32bit,
+		ADE7854_BVARHR);
+static IIO_DEV_ATTR_CVARHR(ade7854_read_32bit,
+		ADE7854_CVARHR);
+static IIO_DEV_ATTR_AVAHR(ade7854_read_32bit,
+		ADE7854_AVAHR);
+static IIO_DEV_ATTR_BVAHR(ade7854_read_32bit,
+		ADE7854_BVAHR);
+static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit,
+		ADE7854_CVAHR);
+
+static int ade7854_set_irq(struct device *dev, bool enable)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
+
+	int ret;
+	u32 irqen;
+
+	ret = st->read_reg_32(dev, ADE7854_MASK0, &irqen);
+	if (ret)
+		goto error_ret;
+
+	if (enable)
+		irqen |= 1 << 17; /* 1: interrupt enabled when all periodical
+				     (at 8 kHz rate) DSP computations finish. */
+	else
+		irqen &= ~(1 << 17);
+
+	ret = st->write_reg_32(dev, ADE7854_MASK0, irqen);
+	if (ret)
+		goto error_ret;
+
+error_ret:
+	return ret;
+}
+
+static int ade7854_initial_setup(struct ade7854_state *st)
+{
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	/* Disable IRQ */
+	ret = ade7854_set_irq(dev, false);
+	if (ret) {
+		dev_err(dev, "disable irq failed");
+		goto err_ret;
+	}
+
+	ade7854_reset(dev);
+	msleep(ADE7854_STARTUP_DELAY);
+
+err_ret:
+	return ret;
+}
+
+static IIO_DEV_ATTR_RESET(ade7854_write_reset);
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
+
+static IIO_CONST_ATTR(name, "ade7854");
+
+static struct attribute *ade7854_event_attributes[] = {
+	NULL
+};
+
+static struct attribute_group ade7854_event_attribute_group = {
+	.attrs = ade7854_event_attributes,
+};
+
+static struct attribute *ade7854_attributes[] = {
+	&iio_dev_attr_aigain.dev_attr.attr,
+	&iio_dev_attr_bigain.dev_attr.attr,
+	&iio_dev_attr_cigain.dev_attr.attr,
+	&iio_dev_attr_nigain.dev_attr.attr,
+	&iio_dev_attr_avgain.dev_attr.attr,
+	&iio_dev_attr_bvgain.dev_attr.attr,
+	&iio_dev_attr_cvgain.dev_attr.attr,
+	&iio_dev_attr_linecyc.dev_attr.attr,
+	&iio_dev_attr_sagcyc.dev_attr.attr,
+	&iio_dev_attr_cfcyc.dev_attr.attr,
+	&iio_dev_attr_peakcyc.dev_attr.attr,
+	&iio_dev_attr_chksum.dev_attr.attr,
+	&iio_dev_attr_apparent_power_a_gain.dev_attr.attr,
+	&iio_dev_attr_apparent_power_b_gain.dev_attr.attr,
+	&iio_dev_attr_apparent_power_c_gain.dev_attr.attr,
+	&iio_dev_attr_active_power_a_offset.dev_attr.attr,
+	&iio_dev_attr_active_power_b_offset.dev_attr.attr,
+	&iio_dev_attr_active_power_c_offset.dev_attr.attr,
+	&iio_dev_attr_reactive_power_a_gain.dev_attr.attr,
+	&iio_dev_attr_reactive_power_b_gain.dev_attr.attr,
+	&iio_dev_attr_reactive_power_c_gain.dev_attr.attr,
+	&iio_dev_attr_reactive_power_a_offset.dev_attr.attr,
+	&iio_dev_attr_reactive_power_b_offset.dev_attr.attr,
+	&iio_dev_attr_reactive_power_c_offset.dev_attr.attr,
+	&iio_dev_attr_awatthr.dev_attr.attr,
+	&iio_dev_attr_bwatthr.dev_attr.attr,
+	&iio_dev_attr_cwatthr.dev_attr.attr,
+	&iio_dev_attr_afwatthr.dev_attr.attr,
+	&iio_dev_attr_bfwatthr.dev_attr.attr,
+	&iio_dev_attr_cfwatthr.dev_attr.attr,
+	&iio_dev_attr_avarhr.dev_attr.attr,
+	&iio_dev_attr_bvarhr.dev_attr.attr,
+	&iio_dev_attr_cvarhr.dev_attr.attr,
+	&iio_dev_attr_angle0.dev_attr.attr,
+	&iio_dev_attr_angle1.dev_attr.attr,
+	&iio_dev_attr_angle2.dev_attr.attr,
+	&iio_dev_attr_avahr.dev_attr.attr,
+	&iio_dev_attr_bvahr.dev_attr.attr,
+	&iio_dev_attr_cvahr.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	&iio_dev_attr_vpeak.dev_attr.attr,
+	&iio_dev_attr_ipeak.dev_attr.attr,
+	&iio_dev_attr_aphcal.dev_attr.attr,
+	&iio_dev_attr_bphcal.dev_attr.attr,
+	&iio_dev_attr_cphcal.dev_attr.attr,
+	&iio_dev_attr_cf1den.dev_attr.attr,
+	&iio_dev_attr_cf2den.dev_attr.attr,
+	&iio_dev_attr_cf3den.dev_attr.attr,
+	&iio_dev_attr_airms.dev_attr.attr,
+	&iio_dev_attr_birms.dev_attr.attr,
+	&iio_dev_attr_cirms.dev_attr.attr,
+	&iio_dev_attr_nirms.dev_attr.attr,
+	&iio_dev_attr_avrms.dev_attr.attr,
+	&iio_dev_attr_bvrms.dev_attr.attr,
+	&iio_dev_attr_cvrms.dev_attr.attr,
+	&iio_dev_attr_airmsos.dev_attr.attr,
+	&iio_dev_attr_birmsos.dev_attr.attr,
+	&iio_dev_attr_cirmsos.dev_attr.attr,
+	&iio_dev_attr_avrmsos.dev_attr.attr,
+	&iio_dev_attr_bvrmsos.dev_attr.attr,
+	&iio_dev_attr_cvrmsos.dev_attr.attr,
+	&iio_dev_attr_volt_a.dev_attr.attr,
+	&iio_dev_attr_volt_b.dev_attr.attr,
+	&iio_dev_attr_volt_c.dev_attr.attr,
+	&iio_dev_attr_current_a.dev_attr.attr,
+	&iio_dev_attr_current_b.dev_attr.attr,
+	&iio_dev_attr_current_c.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ade7854_attribute_group = {
+	.attrs = ade7854_attributes,
+};
+
+int ade7854_probe(struct ade7854_state *st, struct device *dev)
+{
+	int ret, regdone = 0;
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADE7854_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADE7854_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &ade7854_event_attribute_group;
+	st->indio_dev->attrs = &ade7854_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = ade7854_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = ade7854_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (st->irq) {
+		ret = iio_register_interrupt_line(st->irq,
+				st->indio_dev,
+				0,
+				IRQF_TRIGGER_FALLING,
+				"ade7854");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = ade7854_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+	/* Get the device into a sane initial state */
+	ret = ade7854_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7854_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	ade7854_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	ade7854_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+	return ret;
+
+}
+EXPORT_SYMBOL(ade7854_probe);
+
+int ade7854_remove(struct ade7854_state *st)
+{
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	flush_scheduled_work();
+
+	ade7854_remove_trigger(indio_dev);
+	if (st->irq)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	ade7854_uninitialize_ring(indio_dev->ring);
+	ade7854_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+EXPORT_SYMBOL(ade7854_remove);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h
new file mode 100644
index 0000000..47690e5
--- /dev/null
+++ b/drivers/staging/iio/meter/ade7854.h
@@ -0,0 +1,245 @@
+#ifndef _ADE7854_H
+#define _ADE7854_H
+
+#define ADE7854_AIGAIN    0x4380
+#define ADE7854_AVGAIN    0x4381
+#define ADE7854_BIGAIN    0x4382
+#define ADE7854_BVGAIN    0x4383
+#define ADE7854_CIGAIN    0x4384
+#define ADE7854_CVGAIN    0x4385
+#define ADE7854_NIGAIN    0x4386
+#define ADE7854_AIRMSOS   0x4387
+#define ADE7854_AVRMSOS   0x4388
+#define ADE7854_BIRMSOS   0x4389
+#define ADE7854_BVRMSOS   0x438A
+#define ADE7854_CIRMSOS   0x438B
+#define ADE7854_CVRMSOS   0x438C
+#define ADE7854_NIRMSOS   0x438D
+#define ADE7854_AVAGAIN   0x438E
+#define ADE7854_BVAGAIN   0x438F
+#define ADE7854_CVAGAIN   0x4390
+#define ADE7854_AWGAIN    0x4391
+#define ADE7854_AWATTOS   0x4392
+#define ADE7854_BWGAIN    0x4393
+#define ADE7854_BWATTOS   0x4394
+#define ADE7854_CWGAIN    0x4395
+#define ADE7854_CWATTOS   0x4396
+#define ADE7854_AVARGAIN  0x4397
+#define ADE7854_AVAROS    0x4398
+#define ADE7854_BVARGAIN  0x4399
+#define ADE7854_BVAROS    0x439A
+#define ADE7854_CVARGAIN  0x439B
+#define ADE7854_CVAROS    0x439C
+#define ADE7854_AFWGAIN   0x439D
+#define ADE7854_AFWATTOS  0x439E
+#define ADE7854_BFWGAIN   0x439F
+#define ADE7854_BFWATTOS  0x43A0
+#define ADE7854_CFWGAIN   0x43A1
+#define ADE7854_CFWATTOS  0x43A2
+#define ADE7854_AFVARGAIN 0x43A3
+#define ADE7854_AFVAROS   0x43A4
+#define ADE7854_BFVARGAIN 0x43A5
+#define ADE7854_BFVAROS   0x43A6
+#define ADE7854_CFVARGAIN 0x43A7
+#define ADE7854_CFVAROS   0x43A8
+#define ADE7854_VATHR1    0x43A9
+#define ADE7854_VATHR0    0x43AA
+#define ADE7854_WTHR1     0x43AB
+#define ADE7854_WTHR0     0x43AC
+#define ADE7854_VARTHR1   0x43AD
+#define ADE7854_VARTHR0   0x43AE
+#define ADE7854_RSV       0x43AF
+#define ADE7854_VANOLOAD  0x43B0
+#define ADE7854_APNOLOAD  0x43B1
+#define ADE7854_VARNOLOAD 0x43B2
+#define ADE7854_VLEVEL    0x43B3
+#define ADE7854_DICOEFF   0x43B5
+#define ADE7854_HPFDIS    0x43B6
+#define ADE7854_ISUMLVL   0x43B8
+#define ADE7854_ISUM      0x43BF
+#define ADE7854_AIRMS     0x43C0
+#define ADE7854_AVRMS     0x43C1
+#define ADE7854_BIRMS     0x43C2
+#define ADE7854_BVRMS     0x43C3
+#define ADE7854_CIRMS     0x43C4
+#define ADE7854_CVRMS     0x43C5
+#define ADE7854_NIRMS     0x43C6
+#define ADE7854_RUN       0xE228
+#define ADE7854_AWATTHR   0xE400
+#define ADE7854_BWATTHR   0xE401
+#define ADE7854_CWATTHR   0xE402
+#define ADE7854_AFWATTHR  0xE403
+#define ADE7854_BFWATTHR  0xE404
+#define ADE7854_CFWATTHR  0xE405
+#define ADE7854_AVARHR    0xE406
+#define ADE7854_BVARHR    0xE407
+#define ADE7854_CVARHR    0xE408
+#define ADE7854_AFVARHR   0xE409
+#define ADE7854_BFVARHR   0xE40A
+#define ADE7854_CFVARHR   0xE40B
+#define ADE7854_AVAHR     0xE40C
+#define ADE7854_BVAHR     0xE40D
+#define ADE7854_CVAHR     0xE40E
+#define ADE7854_IPEAK     0xE500
+#define ADE7854_VPEAK     0xE501
+#define ADE7854_STATUS0   0xE502
+#define ADE7854_STATUS1   0xE503
+#define ADE7854_OILVL     0xE507
+#define ADE7854_OVLVL     0xE508
+#define ADE7854_SAGLVL    0xE509
+#define ADE7854_MASK0     0xE50A
+#define ADE7854_MASK1     0xE50B
+#define ADE7854_IAWV      0xE50C
+#define ADE7854_IBWV      0xE50D
+#define ADE7854_ICWV      0xE50E
+#define ADE7854_VAWV      0xE510
+#define ADE7854_VBWV      0xE511
+#define ADE7854_VCWV      0xE512
+#define ADE7854_AWATT     0xE513
+#define ADE7854_BWATT     0xE514
+#define ADE7854_CWATT     0xE515
+#define ADE7854_AVA       0xE519
+#define ADE7854_BVA       0xE51A
+#define ADE7854_CVA       0xE51B
+#define ADE7854_CHECKSUM  0xE51F
+#define ADE7854_VNOM      0xE520
+#define ADE7854_PHSTATUS  0xE600
+#define ADE7854_ANGLE0    0xE601
+#define ADE7854_ANGLE1    0xE602
+#define ADE7854_ANGLE2    0xE603
+#define ADE7854_PERIOD    0xE607
+#define ADE7854_PHNOLOAD  0xE608
+#define ADE7854_LINECYC   0xE60C
+#define ADE7854_ZXTOUT    0xE60D
+#define ADE7854_COMPMODE  0xE60E
+#define ADE7854_GAIN      0xE60F
+#define ADE7854_CFMODE    0xE610
+#define ADE7854_CF1DEN    0xE611
+#define ADE7854_CF2DEN    0xE612
+#define ADE7854_CF3DEN    0xE613
+#define ADE7854_APHCAL    0xE614
+#define ADE7854_BPHCAL    0xE615
+#define ADE7854_CPHCAL    0xE616
+#define ADE7854_PHSIGN    0xE617
+#define ADE7854_CONFIG    0xE618
+#define ADE7854_MMODE     0xE700
+#define ADE7854_ACCMODE   0xE701
+#define ADE7854_LCYCMODE  0xE702
+#define ADE7854_PEAKCYC   0xE703
+#define ADE7854_SAGCYC    0xE704
+#define ADE7854_CFCYC     0xE705
+#define ADE7854_HSDC_CFG  0xE706
+#define ADE7854_CONFIG2   0xEC01
+
+#define ADE7854_READ_REG   0x1
+#define ADE7854_WRITE_REG  0x0
+
+#define ADE7854_MAX_TX    7
+#define ADE7854_MAX_RX    7
+#define ADE7854_STARTUP_DELAY 1
+
+#define ADE7854_SPI_SLOW	(u32)(300 * 1000)
+#define ADE7854_SPI_BURST	(u32)(1000 * 1000)
+#define ADE7854_SPI_FAST	(u32)(2000 * 1000)
+
+#define DRIVER_NAME		"ade7854"
+
+/**
+ * struct ade7854_state - device instance specific data
+ * @spi:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct ade7854_state {
+	struct spi_device		*spi;
+	struct i2c_client               *i2c;
+	struct work_struct		work_trigger_to_ring;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	int				(*read_reg_8) (struct device *, u16, u8 *);
+	int				(*read_reg_16) (struct device *, u16, u16 *);
+	int				(*read_reg_24) (struct device *, u16, u32 *);
+	int				(*read_reg_32) (struct device *, u16, u32 *);
+	int				(*write_reg_8) (struct device *, u16, u8);
+	int				(*write_reg_16) (struct device *, u16, u16);
+	int				(*write_reg_24) (struct device *, u16, u32);
+	int				(*write_reg_32) (struct device *, u16, u32);
+	int                             irq;
+	struct mutex			buf_lock;
+};
+
+extern int ade7854_probe(struct ade7854_state *st, struct device *dev);
+extern int ade7854_remove(struct ade7854_state *st);
+
+#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT)
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+
+enum ade7854_scan {
+	ADE7854_SCAN_PHA_V,
+	ADE7854_SCAN_PHB_V,
+	ADE7854_SCAN_PHC_V,
+	ADE7854_SCAN_PHA_I,
+	ADE7854_SCAN_PHB_I,
+	ADE7854_SCAN_PHC_I,
+};
+
+void ade7854_remove_trigger(struct iio_dev *indio_dev);
+int ade7854_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t ade7854_read_data_from_ring(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf);
+
+
+int ade7854_configure_ring(struct iio_dev *indio_dev);
+void ade7854_unconfigure_ring(struct iio_dev *indio_dev);
+
+int ade7854_initialize_ring(struct iio_ring_buffer *ring);
+void ade7854_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void ade7854_remove_trigger(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7854_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline ssize_t
+ade7854_read_data_from_ring(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return 0;
+}
+
+static inline int ade7854_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void ade7854_unconfigure_ring(struct iio_dev *indio_dev)
+{
+}
+static inline int ade7854_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+}
+static inline void ade7854_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+}
+#endif /* CONFIG_IIO_RING_BUFFER */
+
+#endif
diff --git a/drivers/staging/iio/meter/meter.h b/drivers/staging/iio/meter/meter.h
new file mode 100644
index 0000000..142c50d
--- /dev/null
+++ b/drivers/staging/iio/meter/meter.h
@@ -0,0 +1,396 @@
+#include "../sysfs.h"
+
+/* metering ic types of attribute */
+
+#define IIO_DEV_ATTR_CURRENT_A_OFFSET(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(current_a_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_B_OFFSET(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(current_b_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_C_OFFSET(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(current_c_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VOLT_A_OFFSET(_mode, _show, _store, _addr)      \
+	IIO_DEVICE_ATTR(volt_a_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VOLT_B_OFFSET(_mode, _show, _store, _addr)      \
+	IIO_DEVICE_ATTR(volt_b_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VOLT_C_OFFSET(_mode, _show, _store, _addr)      \
+	IIO_DEVICE_ATTR(volt_c_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(reactive_power_a_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(reactive_power_b_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(reactive_power_c_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_a_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_b_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_c_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_A_GAIN(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(current_a_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_B_GAIN(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(current_b_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_C_GAIN(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(current_c_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(apparent_power_a_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(apparent_power_b_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(apparent_power_c_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_a_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_b_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(active_power_c_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(reactive_power_a_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(reactive_power_b_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(reactive_power_c_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_A(_show, _addr)			\
+	IIO_DEVICE_ATTR(current_a, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_B(_show, _addr)			\
+	IIO_DEVICE_ATTR(current_b, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CURRENT_C(_show, _addr)			\
+	IIO_DEVICE_ATTR(current_c, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_VOLT_A(_show, _addr)			\
+	IIO_DEVICE_ATTR(volt_a, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_VOLT_B(_show, _addr)			\
+	IIO_DEVICE_ATTR(volt_b, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_VOLT_C(_show, _addr)			\
+	IIO_DEVICE_ATTR(volt_c, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_AENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(aenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_LENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(lenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_RAENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(raenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_LAENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(laenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_VAENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(vaenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_LVAENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(lvaenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_RVAENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(rvaenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_LVARENERGY(_show, _addr)			\
+	IIO_DEVICE_ATTR(lvarenergy, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CHKSUM(_show, _addr)                       \
+	IIO_DEVICE_ATTR(chksum, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ANGLE0(_show, _addr)                       \
+	IIO_DEVICE_ATTR(angle0, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ANGLE1(_show, _addr)                       \
+	IIO_DEVICE_ATTR(angle1, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ANGLE2(_show, _addr)                       \
+	IIO_DEVICE_ATTR(angle2, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_AWATTHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(awatthr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_BWATTHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(bwatthr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CWATTHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(cwatthr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_AFWATTHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(afwatthr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_BFWATTHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(bfwatthr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CFWATTHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(cfwatthr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_AVARHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(avarhr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_BVARHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(bvarhr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CVARHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(cvarhr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_AVAHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(avahr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_BVAHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(bvahr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_CVAHR(_show, _addr)			\
+	IIO_DEVICE_ATTR(cvahr, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_IOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(ios, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(vos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_PHCAL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(phcal, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_APHCAL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(aphcal, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BPHCAL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bphcal, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CPHCAL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cphcal, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_APOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(apos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AAPOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(aapos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BAPOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bapos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CAPOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(capos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AVRMSGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(avrmsgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BVRMSGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bvrmsgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CVRMSGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cvrmsgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AIGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(aigain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BIGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bigain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CIGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cigain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_NIGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(nigain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AVGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(avgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BVGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bvgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CVGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cvgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_WGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(wgain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_WDIV(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(wdiv, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CFNUM(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cfnum, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CFDEN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cfden, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CF1DEN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cf1den, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CF2DEN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cf2den, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CF3DEN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cf3den, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_IRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(irms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(vrms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AIRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(airms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BIRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(birms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CIRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cirms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_NIRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(nirms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AVRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(avrms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BVRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bvrms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CVRMS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cvrms, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_IRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(irmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(vrmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AIRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(airmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BIRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(birmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CIRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cirmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_AVRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(avrmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_BVRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(bvrmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CVRMSOS(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cvrmsos, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VAGAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(vagain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_PGA_GAIN(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(pga_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VADIV(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(vadiv, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_LINECYC(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(linecyc, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_SAGCYC(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(sagcyc, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CFCYC(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(cfcyc, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_PEAKCYC(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(peakcyc, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_SAGLVL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(saglvl, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_IPKLVL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(ipklvl, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VPKLVL(_mode, _show, _store, _addr)                \
+	IIO_DEVICE_ATTR(vpklvl, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_IPEAK(_mode, _show, _store, _addr)			\
+	IIO_DEVICE_ATTR(ipeak, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_RIPEAK(_mode, _show, _store, _addr)			\
+	IIO_DEVICE_ATTR(ripeak, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VPEAK(_mode, _show, _store, _addr)			\
+	IIO_DEVICE_ATTR(vpeak, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_RVPEAK(_mode, _show, _store, _addr)			\
+	IIO_DEVICE_ATTR(rvpeak, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_VPERIOD(_mode, _show, _store, _addr)			\
+	IIO_DEVICE_ATTR(vperiod, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_CH_OFF(_num, _mode, _show, _store, _addr)			\
+  IIO_DEVICE_ATTR(choff_##_num, _mode, _show, _store, _addr)
+
+/* active energy register, AENERGY, is more than half full */
+#define IIO_EVENT_ATTR_AENERGY_HALF_FULL(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(aenergy_half_full, _evlist, _show, _store, _mask)
+
+/* a SAG on the line voltage */
+#define IIO_EVENT_ATTR_LINE_VOLT_SAG(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(line_volt_sag, _evlist, _show, _store, _mask)
+
+/*
+ * Indicates the end of energy accumulation over an integer number
+ * of half line cycles
+ */
+#define IIO_EVENT_ATTR_CYCEND(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(cycend, _evlist, _show, _store, _mask)
+
+/* on the rising and falling edge of the the voltage waveform */
+#define IIO_EVENT_ATTR_ZERO_CROSS(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(zero_cross, _evlist, _show, _store, _mask)
+
+/* the active energy register has overflowed */
+#define IIO_EVENT_ATTR_AENERGY_OVERFLOW(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(aenergy_overflow, _evlist, _show, _store, _mask)
+
+/* the apparent energy register has overflowed */
+#define IIO_EVENT_ATTR_VAENERGY_OVERFLOW(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(vaenergy_overflow, _evlist, _show, _store, _mask)
+
+/* the active energy register, VAENERGY, is more than half full */
+#define IIO_EVENT_ATTR_VAENERGY_HALF_FULL(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(vaenergy_half_full, _evlist, _show, _store, _mask)
+
+/* the power has gone from negative to positive */
+#define IIO_EVENT_ATTR_PPOS(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(ppos, _evlist, _show, _store, _mask)
+
+/* the power has gone from positive to negative */
+#define IIO_EVENT_ATTR_PNEG(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(pneg, _evlist, _show, _store, _mask)
+
+/* waveform sample from Channel 1 has exceeded the IPKLVL value */
+#define IIO_EVENT_ATTR_IPKLVL_EXC(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(ipklvl_exc, _evlist, _show, _store, _mask)
+
+/* waveform sample from Channel 2 has exceeded the VPKLVL value */
+#define IIO_EVENT_ATTR_VPKLVL_EXC(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(vpklvl_exc, _evlist, _show, _store, _mask)
+
diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig
new file mode 100644
index 0000000..a4a3634
--- /dev/null
+++ b/drivers/staging/iio/resolver/Kconfig
@@ -0,0 +1,54 @@
+#
+# Resolver/Synchro drivers
+#
+comment "Resolver to digital converters"
+
+config AD2S90
+	tristate "Analog Devices ad2s90 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices spi resolver
+	  to digital converters, ad2s90, provides direct access via sysfs.
+
+config AD2S120X
+	tristate "Analog Devices ad2s120x driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices spi resolver
+	  to digital converters, ad2s1200 and ad2s1205, provides direct access
+	  via sysfs.
+
+config AD2S1210
+	tristate "Analog Devices ad2s1210 driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices spi resolver
+	  to digital converters, ad2s1210, provides direct access via sysfs.
+
+choice
+	prompt "Resolution Control"
+	depends on AD2S1210
+	default AD2S1210_GPIO_NONE
+	help
+	  In normal mode, the resolution of the digital output is selected
+	  using the RES0 and RES1 input pins. In configuration mode, the
+	  resolution is selected by setting the RES0 and RES1 bits in the
+	  control regsiter. When switching between normal mode and configuration
+	  mode, there are some schemes to keep them matchs.
+
+config AD2S1210_GPIO_INPUT
+	bool "read resolution from gpio pins"
+	help
+	  GPIO pins are sampling RES0 and RES1 pins, read the resolution
+	  settings from the GPIO pins.
+
+config AD2S1210_GPIO_OUTPUT
+	bool "set gpio pins to set resolution"
+	help
+	  RES0 and RES1 pins are controlled by GPIOs, setting GPIO pins to
+	  set the resolution.
+
+config AD2S1210_GPIO_NONE
+	bool "take the responsibility by user"
+
+endchoice
diff --git a/drivers/staging/iio/resolver/Makefile b/drivers/staging/iio/resolver/Makefile
new file mode 100644
index 0000000..0b84a89
--- /dev/null
+++ b/drivers/staging/iio/resolver/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for Resolver/Synchro drivers
+#
+
+obj-$(CONFIG_AD2S90) += ad2s90.o
+obj-$(CONFIG_AD2S120X) += ad2s120x.o
+obj-$(CONFIG_AD2S1210) += ad2s1210.o
diff --git a/drivers/staging/iio/resolver/ad2s120x.c b/drivers/staging/iio/resolver/ad2s120x.c
new file mode 100644
index 0000000..8f497a2
--- /dev/null
+++ b/drivers/staging/iio/resolver/ad2s120x.c
@@ -0,0 +1,310 @@
+/*
+ * ad2s120x.c simple support for the ADI Resolver to Digital Converters: AD2S1200/1205
+ *
+ * Copyright (c) 2010-2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad2s120x"
+
+/* input pin sample and rdvel is controlled by driver */
+#define AD2S120X_PN	2
+
+/* input clock on serial interface */
+#define AD2S120X_HZ	8192000
+/* clock period in nano second */
+#define AD2S120X_TSCLK	(1000000000/AD2S120X_HZ)
+
+struct ad2s120x_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+	unsigned short sample;
+	unsigned short rdvel;
+	u8 rx[2];
+	u8 tx[2];
+};
+
+static ssize_t ad2s120x_show_pos_vel(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret = 0;
+	ssize_t len = 0;
+	u16 pos;
+	s16 vel;
+	u8 status;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s120x_state *st = idev->dev_data;
+
+	xfer.len = 1;
+	xfer.tx_buf = st->tx;
+	xfer.rx_buf = st->rx;
+	mutex_lock(&st->lock);
+
+	gpio_set_value(st->sample, 0);
+	/* delay (6 * AD2S120X_TSCLK + 20) nano seconds */
+	udelay(1);
+	gpio_set_value(st->sample, 1);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	status = st->rx[1];
+	pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
+	len = sprintf(buf, "%d %c%c%c%c ", pos,
+				(status & 0x8) ? 'P' : 'V',
+				(status & 0x4) ? 'd' : '_',
+				(status & 0x2) ? 'l' : '_',
+				(status & 0x1) ? '1' : '0');
+
+	/* delay 18 ns */
+	/* ndelay(18); */
+
+	gpio_set_value(st->rdvel, 0);
+	/* ndelay(5);*/
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	status = st->rx[1];
+	vel = (st->rx[0] & 0x80) ? 0xf000 : 0;
+	vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
+	len += sprintf(buf + len, "%d %c%c%c%c\n", vel,
+				(status & 0x8) ? 'P' : 'V',
+				(status & 0x4) ? 'd' : '_',
+				(status & 0x2) ? 'l' : '_',
+				(status & 0x1) ? '1' : '0');
+error_ret:
+	gpio_set_value(st->rdvel, 1);
+	/* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */
+	udelay(1);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad2s120x_show_pos(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret = 0;
+	ssize_t len = 0;
+	u16 pos;
+	u8 status;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s120x_state *st = idev->dev_data;
+
+	xfer.len = 1;
+	xfer.tx_buf = st->tx;
+	xfer.rx_buf = st->rx;
+	mutex_lock(&st->lock);
+
+	gpio_set_value(st->sample, 0);
+	/* delay (6 * AD2S120X_TSCLK + 20) nano seconds */
+	udelay(1);
+	gpio_set_value(st->sample, 1);
+	gpio_set_value(st->rdvel, 1);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	status = st->rx[1];
+	pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
+	len = sprintf(buf, "%d %c%c%c%c ", pos,
+				(status & 0x8) ? 'P' : 'V',
+				(status & 0x4) ? 'd' : '_',
+				(status & 0x2) ? 'l' : '_',
+				(status & 0x1) ? '1' : '0');
+error_ret:
+	/* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */
+	udelay(1);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad2s120x_show_vel(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret = 0;
+	ssize_t len = 0;
+	s16 vel;
+	u8 status;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s120x_state *st = idev->dev_data;
+
+	xfer.len = 1;
+	xfer.tx_buf = st->tx;
+	xfer.rx_buf = st->rx;
+	mutex_lock(&st->lock);
+
+	gpio_set_value(st->sample, 0);
+	/* delay (6 * AD2S120X_TSCLK + 20) nano seconds */
+	udelay(1);
+	gpio_set_value(st->sample, 1);
+
+	gpio_set_value(st->rdvel, 0);
+	/* ndelay(5);*/
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	status = st->rx[1];
+	vel = (st->rx[0] & 0x80) ? 0xf000 : 0;
+	vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
+	len += sprintf(buf + len, "%d %c%c%c%c\n", vel,
+				(status & 0x8) ? 'P' : 'V',
+				(status & 0x4) ? 'd' : '_',
+				(status & 0x2) ? 'l' : '_',
+				(status & 0x1) ? '1' : '0');
+error_ret:
+	gpio_set_value(st->rdvel, 1);
+	/* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */
+	udelay(1);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_CONST_ATTR(description,
+	"12-Bit R/D Converter with Reference Oscillator");
+static IIO_DEVICE_ATTR(pos_vel, S_IRUGO, ad2s120x_show_pos_vel, NULL, 0);
+static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s120x_show_pos, NULL, 0);
+static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s120x_show_vel, NULL, 0);
+
+static struct attribute *ad2s120x_attributes[] = {
+	&iio_const_attr_description.dev_attr.attr,
+	&iio_dev_attr_pos_vel.dev_attr.attr,
+	&iio_dev_attr_pos.dev_attr.attr,
+	&iio_dev_attr_vel.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad2s120x_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad2s120x_attributes,
+};
+
+static int __devinit ad2s120x_probe(struct spi_device *spi)
+{
+	struct ad2s120x_state *st;
+	int pn, ret = 0;
+	unsigned short *pins = spi->dev.platform_data;
+
+	for (pn = 0; pn < AD2S120X_PN; pn++) {
+		if (gpio_request(pins[pn], DRV_NAME)) {
+			pr_err("%s: request gpio pin %d failed\n",
+						DRV_NAME, pins[pn]);
+			goto error_ret;
+		}
+		gpio_direction_output(pins[pn], 1);
+	}
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+	st->sample = pins[0];
+	st->rdvel = pins[1];
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad2s120x_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+
+	spi->max_speed_hz = AD2S120X_HZ;
+	spi->mode = SPI_MODE_3;
+	spi_setup(spi);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	for (--pn; pn >= 0; pn--)
+		gpio_free(pins[pn]);
+	return ret;
+}
+
+static int __devexit ad2s120x_remove(struct spi_device *spi)
+{
+	struct ad2s120x_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad2s120x_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad2s120x_probe,
+	.remove = __devexit_p(ad2s120x_remove),
+};
+
+static __init int ad2s120x_spi_init(void)
+{
+	return spi_register_driver(&ad2s120x_driver);
+}
+module_init(ad2s120x_spi_init);
+
+static __exit void ad2s120x_spi_exit(void)
+{
+	spi_unregister_driver(&ad2s120x_driver);
+}
+module_exit(ad2s120x_spi_exit);
+
+MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
new file mode 100644
index 0000000..34fb21a
--- /dev/null
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -0,0 +1,872 @@
+/*
+ * ad2s1210.c support for the ADI Resolver to Digital Converters: AD2S1210
+ *
+ * Copyright (c) 2010-2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad2s1210"
+
+#define DEF_CONTROL		0x7E
+
+#define MSB_IS_HIGH		0x80
+#define MSB_IS_LOW		0x7F
+#define PHASE_LOCK_RANGE_44	0x20
+#define ENABLE_HYSTERESIS	0x10
+#define SET_ENRES1		0x08
+#define SET_ENRES0		0x04
+#define SET_RES1		0x02
+#define SET_RES0		0x01
+
+#define SET_ENRESOLUTION	(SET_ENRES1 | SET_ENRES0)
+#define SET_RESOLUTION		(SET_RES1 | SET_RES0)
+
+#define REG_POSITION		0x80
+#define REG_VELOCITY		0x82
+#define REG_LOS_THRD		0x88
+#define REG_DOS_OVR_THRD	0x89
+#define REG_DOS_MIS_THRD	0x8A
+#define REG_DOS_RST_MAX_THRD	0x8B
+#define REG_DOS_RST_MIN_THRD	0x8C
+#define REG_LOT_HIGH_THRD	0x8D
+#define REG_LOT_LOW_THRD	0x8E
+#define REG_EXCIT_FREQ		0x91
+#define REG_CONTROL		0x92
+#define REG_SOFT_RESET		0xF0
+#define REG_FAULT		0xFF
+
+/* pin SAMPLE, A0, A1, RES0, RES1, is controlled by driver */
+#define AD2S1210_SAA		3
+#if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+# define AD2S1210_RES		2
+#else
+# define AD2S1210_RES		0
+#endif
+#define AD2S1210_PN		(AD2S1210_SAA + AD2S1210_RES)
+
+#define AD2S1210_MIN_CLKIN	6144000
+#define AD2S1210_MAX_CLKIN	10240000
+#define AD2S1210_MIN_EXCIT	2000
+#define AD2S1210_MAX_EXCIT	20000
+#define AD2S1210_MIN_FCW	0x4
+#define AD2S1210_MAX_FCW	0x50
+
+/* default input clock on serial interface */
+#define AD2S1210_DEF_CLKIN	8192000
+/* clock period in nano second */
+#define AD2S1210_DEF_TCK	(1000000000/AD2S1210_DEF_CLKIN)
+#define AD2S1210_DEF_EXCIT	10000
+
+enum ad2s1210_mode {
+	MOD_POS = 0,
+	MOD_VEL,
+	MOD_RESERVED,
+	MOD_CONFIG,
+};
+
+enum ad2s1210_res {
+	RES_10 = 10,
+	RES_12 = 12,
+	RES_14 = 14,
+	RES_16 = 16,
+};
+
+static unsigned int resolution_value[] = {
+		RES_10, RES_12, RES_14, RES_16};
+
+struct ad2s1210_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+	struct spi_transfer xfer;
+	unsigned int hysteresis;
+	unsigned int old_data;
+	enum ad2s1210_mode mode;
+	enum ad2s1210_res resolution;
+	unsigned int fclkin;
+	unsigned int fexcit;
+	unsigned short sample;
+	unsigned short a0;
+	unsigned short a1;
+	unsigned short res0;
+	unsigned short res1;
+	u8 rx[3];
+	u8 tx[3];
+};
+
+static inline void start_sample(struct ad2s1210_state *st)
+{
+	gpio_set_value(st->sample, 0);
+}
+
+static inline void stop_sample(struct ad2s1210_state *st)
+{
+	gpio_set_value(st->sample, 1);
+}
+
+static inline void set_mode(enum ad2s1210_mode mode, struct ad2s1210_state *st)
+{
+	switch (mode) {
+	case MOD_POS:
+		gpio_set_value(st->a0, 0);
+		gpio_set_value(st->a1, 0);
+		break;
+	case MOD_VEL:
+		gpio_set_value(st->a0, 0);
+		gpio_set_value(st->a1, 1);
+		break;
+	case MOD_CONFIG:
+		gpio_set_value(st->a0, 1);
+		gpio_set_value(st->a1, 1);
+		break;
+	default:
+		/* set to reserved mode */
+		gpio_set_value(st->a0, 1);
+		gpio_set_value(st->a1, 0);
+	}
+	st->mode = mode;
+}
+
+/* write 1 bytes (address or data) to the chip */
+static int config_write(struct ad2s1210_state *st,
+					unsigned char data)
+{
+	struct spi_message msg;
+	int ret = 0;
+
+	st->xfer.len = 1;
+	set_mode(MOD_CONFIG, st);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&st->xfer, &msg);
+	st->tx[0] = data;
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		return ret;
+	st->old_data = 1;
+	return ret;
+}
+
+/* read value from one of the registers */
+static int config_read(struct ad2s1210_state *st,
+				unsigned char address,
+					unsigned char *data)
+{
+	struct spi_message msg;
+	int ret = 0;
+
+	st->xfer.len = 2;
+	set_mode(MOD_CONFIG, st);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&st->xfer, &msg);
+	st->tx[0] = address | MSB_IS_HIGH;
+	st->tx[1] = REG_FAULT;
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		return ret;
+	*data = st->rx[1];
+	st->old_data = 1;
+	return ret;
+}
+
+static inline void update_frequency_control_word(struct ad2s1210_state *st)
+{
+	unsigned char fcw;
+	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->fclkin);
+	if (fcw >= AD2S1210_MIN_FCW && fcw <= AD2S1210_MAX_FCW) {
+		config_write(st, REG_EXCIT_FREQ);
+		config_write(st, fcw);
+	} else
+		pr_err("ad2s1210: FCW out of range\n");
+}
+
+#if defined(CONFIG_AD2S1210_GPIO_INPUT)
+static inline unsigned char read_resolution_pin(struct ad2s1210_state *st)
+{
+	unsigned int data;
+	data = (gpio_get_value(st->res0) << 1)  |
+			gpio_get_value(st->res1);
+	return resolution_value[data];
+}
+#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+static inline void set_resolution_pin(struct ad2s1210_state *st)
+{
+	switch (st->resolution) {
+	case RES_10:
+		gpio_set_value(st->res0, 0);
+		gpio_set_value(st->res1, 0);
+		break;
+	case RES_12:
+		gpio_set_value(st->res0, 0);
+		gpio_set_value(st->res1, 1);
+		break;
+	case RES_14:
+		gpio_set_value(st->res0, 1);
+		gpio_set_value(st->res1, 0);
+		break;
+	case RES_16:
+		gpio_set_value(st->res0, 1);
+		gpio_set_value(st->res1, 1);
+		break;
+	}
+}
+#endif
+
+static inline void soft_reset(struct ad2s1210_state *st)
+{
+	config_write(st, REG_SOFT_RESET);
+	config_write(st, 0x0);
+}
+
+
+/* return the OLD DATA since last spi bus write */
+static ssize_t ad2s1210_show_raw(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	int ret;
+
+	mutex_lock(&st->lock);
+	if (st->old_data) {
+		ret = sprintf(buf, "0x%x\n", st->rx[0]);
+		st->old_data = 0;
+	} else
+		ret = 0;
+	mutex_unlock(&st->lock);
+	return ret;
+}
+
+static ssize_t ad2s1210_store_raw(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned long udata;
+	unsigned char data;
+	int ret;
+
+	ret = strict_strtoul(buf, 16, &udata);
+	if (ret)
+		return -EINVAL;
+	data = udata & 0xff;
+	mutex_lock(&st->lock);
+	config_write(st, data);
+	mutex_unlock(&st->lock);
+	return 1;
+}
+
+static ssize_t ad2s1210_store_softreset(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	mutex_lock(&st->lock);
+	soft_reset(st);
+	mutex_unlock(&st->lock);
+	return len;
+}
+
+static ssize_t ad2s1210_show_fclkin(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	return sprintf(buf, "%d\n", st->fclkin);
+}
+
+static ssize_t ad2s1210_store_fclkin(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned long fclkin;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &fclkin);
+	if (!ret && fclkin >= AD2S1210_MIN_CLKIN &&
+				fclkin <= AD2S1210_MAX_CLKIN) {
+		mutex_lock(&st->lock);
+		st->fclkin = fclkin;
+	} else {
+		pr_err("ad2s1210: fclkin out of range\n");
+		return -EINVAL;
+	}
+	update_frequency_control_word(st);
+	soft_reset(st);
+	mutex_unlock(&st->lock);
+	return len;
+}
+
+static ssize_t ad2s1210_show_fexcit(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	return sprintf(buf, "%d\n", st->fexcit);
+}
+
+static ssize_t ad2s1210_store_fexcit(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned long fexcit;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &fexcit);
+	if (!ret && fexcit >= AD2S1210_MIN_EXCIT &&
+				fexcit <= AD2S1210_MAX_EXCIT) {
+		mutex_lock(&st->lock);
+		st->fexcit = fexcit;
+	} else {
+		pr_err("ad2s1210: excitation frequency out of range\n");
+		return -EINVAL;
+	}
+	update_frequency_control_word(st);
+	soft_reset(st);
+	mutex_unlock(&st->lock);
+	return len;
+}
+
+static ssize_t ad2s1210_show_control(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned char data;
+	mutex_lock(&st->lock);
+	config_read(st, REG_CONTROL, &data);
+	mutex_unlock(&st->lock);
+	return sprintf(buf, "0x%x\n", data);
+}
+
+static ssize_t ad2s1210_store_control(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned long udata;
+	unsigned char data;
+	int ret;
+
+	ret = strict_strtoul(buf, 16, &udata);
+	if (ret) {
+		ret = -EINVAL;
+		goto error_ret;
+	}
+	mutex_lock(&st->lock);
+	config_write(st, REG_CONTROL);
+	data = udata & MSB_IS_LOW;
+	config_write(st, data);
+	config_read(st, REG_CONTROL, &data);
+	if (data & MSB_IS_HIGH) {
+		ret = -EIO;
+		pr_err("ad2s1210: write control register fail\n");
+		goto error_ret;
+	}
+	st->resolution = resolution_value[data & SET_RESOLUTION];
+#if defined(CONFIG_AD2S1210_GPIO_INPUT)
+	data = read_resolution_pin(st);
+	if (data != st->resolution)
+		pr_warning("ad2s1210: resolution settings not match\n");
+#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+	set_resolution_pin(st);
+#endif
+	ret = len;
+	if (data & ENABLE_HYSTERESIS)
+		st->hysteresis = 1;
+	else
+		st->hysteresis = 0;
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
+}
+
+static ssize_t ad2s1210_show_resolution(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	return sprintf(buf, "%d\n", st->resolution);
+}
+
+static ssize_t ad2s1210_store_resolution(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned char data;
+	unsigned long udata;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &udata);
+	if (ret || udata < RES_10 || udata > RES_16) {
+		pr_err("ad2s1210: resolution out of range\n");
+		return -EINVAL;
+	}
+	mutex_lock(&st->lock);
+	config_read(st, REG_CONTROL, &data);
+	data &= ~SET_RESOLUTION;
+	data |= (udata - RES_10) >> 1;
+	config_write(st, REG_CONTROL);
+	config_write(st, data & MSB_IS_LOW);
+	config_read(st, REG_CONTROL, &data);
+	if (data & MSB_IS_HIGH) {
+		ret = -EIO;
+		pr_err("ad2s1210: setting resolution fail\n");
+		goto error_ret;
+	}
+	st->resolution = resolution_value[data & SET_RESOLUTION];
+#if defined(CONFIG_AD2S1210_GPIO_INPUT)
+	data = read_resolution_pin(st);
+	if (data != st->resolution)
+		pr_warning("ad2s1210: resolution settings not match\n");
+#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+	set_resolution_pin(st);
+#endif
+	ret = len;
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
+}
+/* read the fault register since last sample */
+static ssize_t ad2s1210_show_fault(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	int ret = 0;
+	ssize_t len = 0;
+	unsigned char data;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = config_read(st, REG_FAULT, &data);
+
+	if (ret)
+		goto error_ret;
+	len = sprintf(buf, "0x%x\n", data);
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret ? ret : len;
+}
+
+static ssize_t ad2s1210_clear_fault(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned char data;
+
+	mutex_lock(&st->lock);
+	start_sample(st);
+	/* delay (2 * tck + 20) nano seconds */
+	udelay(1);
+	stop_sample(st);
+	config_read(st, REG_FAULT, &data);
+	start_sample(st);
+	stop_sample(st);
+	mutex_unlock(&st->lock);
+
+	return 0;
+}
+
+static ssize_t ad2s1210_show_reg(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned char data;
+	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
+
+	mutex_lock(&st->lock);
+	config_read(st, iattr->address, &data);
+	mutex_unlock(&st->lock);
+	return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t ad2s1210_store_reg(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+	unsigned long data;
+	int ret;
+	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
+
+	ret = strict_strtoul(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+	mutex_lock(&st->lock);
+	config_write(st, iattr->address);
+	config_write(st, data & MSB_IS_LOW);
+	mutex_unlock(&st->lock);
+	return len;
+}
+
+static ssize_t ad2s1210_show_pos(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	int ret = 0;
+	ssize_t len = 0;
+	u16 pos;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+
+	st->xfer.len = 2;
+	mutex_lock(&st->lock);
+	start_sample(st);
+	/* delay (6 * tck + 20) nano seconds */
+	udelay(1);
+
+	set_mode(MOD_POS, st);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&st->xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	pos = ((((u16)(st->rx[0])) << 8) | (st->rx[1]));
+	if (st->hysteresis)
+		pos >>= 16 - st->resolution;
+	len = sprintf(buf, "%d\n", pos);
+error_ret:
+	stop_sample(st);
+	/* delay (2 * tck + 20) nano seconds */
+	udelay(1);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad2s1210_show_vel(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	unsigned short negative;
+	int ret = 0;
+	ssize_t len = 0;
+	s16 vel;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+
+	st->xfer.len = 2;
+	mutex_lock(&st->lock);
+	start_sample(st);
+	/* delay (6 * tck + 20) nano seconds */
+	udelay(1);
+
+	set_mode(MOD_VEL, st);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&st->xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	negative = st->rx[0] & 0x80;
+	vel = ((((s16)(st->rx[0])) << 8) | (st->rx[1]));
+	vel >>= 16 - st->resolution;
+	if (negative) {
+		negative = (0xffff >> st->resolution) << st->resolution;
+		vel |= negative;
+	}
+	len = sprintf(buf, "%d\n", vel);
+error_ret:
+	stop_sample(st);
+	/* delay (2 * tck + 20) nano seconds */
+	udelay(1);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad2s1210_show_pos_vel(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	unsigned short negative;
+	int ret = 0;
+	ssize_t len = 0;
+	u16 pos;
+	s16 vel;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s1210_state *st = idev->dev_data;
+
+	st->xfer.len = 2;
+	mutex_lock(&st->lock);
+	start_sample(st);
+	/* delay (6 * tck + 20) nano seconds */
+	udelay(1);
+
+	set_mode(MOD_POS, st);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&st->xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	pos = ((((u16)(st->rx[0])) << 8) | (st->rx[1]));
+	if (st->hysteresis)
+		pos >>= 16 - st->resolution;
+	len = sprintf(buf, "%d ", pos);
+
+	st->xfer.len = 2;
+	set_mode(MOD_VEL, st);
+	spi_message_init(&msg);
+	spi_message_add_tail(&st->xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	negative = st->rx[0] & 0x80;
+	vel = ((((s16)(st->rx[0])) << 8) | (st->rx[1]));
+	vel >>= 16 - st->resolution;
+	if (negative) {
+		negative = (0xffff >> st->resolution) << st->resolution;
+		vel |= negative;
+	}
+	len += sprintf(buf + len, "%d\n", vel);
+error_ret:
+	stop_sample(st);
+	/* delay (2 * tck + 20) nano seconds */
+	udelay(1);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_CONST_ATTR(description,
+	"Variable Resolution, 10-Bit to 16Bit R/D\n\
+Converter with Reference Oscillator");
+static IIO_DEVICE_ATTR(raw_io, S_IRUGO | S_IWUGO,
+		ad2s1210_show_raw, ad2s1210_store_raw, 0);
+static IIO_DEVICE_ATTR(reset, S_IWUGO,
+		NULL, ad2s1210_store_softreset, 0);
+static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUGO,
+		ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
+static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUGO,
+		ad2s1210_show_fexcit,	ad2s1210_store_fexcit, 0);
+static IIO_DEVICE_ATTR(control, S_IRUGO | S_IWUGO,
+		ad2s1210_show_control, ad2s1210_store_control, 0);
+static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUGO,
+		ad2s1210_show_resolution, ad2s1210_store_resolution, 0);
+static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUGO,
+		ad2s1210_show_fault, ad2s1210_clear_fault, 0);
+static IIO_DEVICE_ATTR(pos, S_IRUGO,
+		ad2s1210_show_pos, NULL, 0);
+static IIO_DEVICE_ATTR(vel, S_IRUGO,
+		ad2s1210_show_vel, NULL, 0);
+static IIO_DEVICE_ATTR(pos_vel, S_IRUGO,
+		ad2s1210_show_pos_vel, NULL, 0);
+static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_LOS_THRD);
+static IIO_DEVICE_ATTR(dos_ovr_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_OVR_THRD);
+static IIO_DEVICE_ATTR(dos_mis_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_MIS_THRD);
+static IIO_DEVICE_ATTR(dos_rst_max_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MAX_THRD);
+static IIO_DEVICE_ATTR(dos_rst_min_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MIN_THRD);
+static IIO_DEVICE_ATTR(lot_high_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_HIGH_THRD);
+static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUGO,
+		ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_LOW_THRD);
+
+static struct attribute *ad2s1210_attributes[] = {
+	&iio_const_attr_description.dev_attr.attr,
+	&iio_dev_attr_raw_io.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_dev_attr_fclkin.dev_attr.attr,
+	&iio_dev_attr_fexcit.dev_attr.attr,
+	&iio_dev_attr_control.dev_attr.attr,
+	&iio_dev_attr_bits.dev_attr.attr,
+	&iio_dev_attr_fault.dev_attr.attr,
+	&iio_dev_attr_pos.dev_attr.attr,
+	&iio_dev_attr_vel.dev_attr.attr,
+	&iio_dev_attr_pos_vel.dev_attr.attr,
+	&iio_dev_attr_los_thrd.dev_attr.attr,
+	&iio_dev_attr_dos_ovr_thrd.dev_attr.attr,
+	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
+	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
+	&iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
+	&iio_dev_attr_lot_high_thrd.dev_attr.attr,
+	&iio_dev_attr_lot_low_thrd.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad2s1210_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad2s1210_attributes,
+};
+
+static int __devinit ad2s1210_initial(struct ad2s1210_state *st)
+{
+	unsigned char data;
+	int ret;
+
+	mutex_lock(&st->lock);
+#if defined(CONFIG_AD2S1210_GPIO_INPUT)
+	st->resolution = read_resolution_pin(st);
+#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+	set_resolution_pin(st);
+#endif
+
+	config_write(st, REG_CONTROL);
+	data = DEF_CONTROL & ~(SET_RESOLUTION);
+	data |= (st->resolution - RES_10) >> 1;
+	config_write(st, data);
+	ret = config_read(st, REG_CONTROL, &data);
+	if (ret)
+		goto error_ret;
+
+	if (data & MSB_IS_HIGH) {
+		ret = -EIO;
+		goto error_ret;
+	}
+
+	update_frequency_control_word(st);
+	soft_reset(st);
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
+}
+
+static int __devinit ad2s1210_probe(struct spi_device *spi)
+{
+	struct ad2s1210_state *st;
+	int pn, ret = 0;
+	unsigned short *pins = spi->dev.platform_data;
+
+	for (pn = 0; pn < AD2S1210_PN; pn++) {
+		if (gpio_request(pins[pn], DRV_NAME)) {
+			pr_err("%s: request gpio pin %d failed\n",
+						DRV_NAME, pins[pn]);
+			goto error_ret;
+		}
+		if (pn < AD2S1210_SAA)
+			gpio_direction_output(pins[pn], 1);
+		else {
+#if defined(CONFIG_AD2S1210_GPIO_INPUT)
+			gpio_direction_input(pins[pn]);
+#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+			gpio_direction_output(pins[pn], 1);
+#endif
+		}
+	}
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+	st->xfer.tx_buf = st->tx;
+	st->xfer.rx_buf = st->rx;
+	st->hysteresis = 1;
+	st->mode = MOD_CONFIG;
+	st->resolution = RES_12;
+	st->fclkin = AD2S1210_DEF_CLKIN;
+	st->fexcit = AD2S1210_DEF_EXCIT;
+	st->sample = pins[0];
+	st->a0 = pins[1];
+	st->a1 = pins[2];
+	st->res0 = pins[3];
+	st->res1 = pins[4];
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad2s1210_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+
+	if (spi->max_speed_hz != AD2S1210_DEF_CLKIN)
+		st->fclkin = spi->max_speed_hz;
+	spi->mode = SPI_MODE_3;
+	spi_setup(spi);
+
+	ad2s1210_initial(st);
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	for (--pn; pn >= 0; pn--)
+		gpio_free(pins[pn]);
+	return ret;
+}
+
+static int __devexit ad2s1210_remove(struct spi_device *spi)
+{
+	struct ad2s1210_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad2s1210_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad2s1210_probe,
+	.remove = __devexit_p(ad2s1210_remove),
+};
+
+static __init int ad2s1210_spi_init(void)
+{
+	return spi_register_driver(&ad2s1210_driver);
+}
+module_init(ad2s1210_spi_init);
+
+static __exit void ad2s1210_spi_exit(void)
+{
+	spi_unregister_driver(&ad2s1210_driver);
+}
+module_exit(ad2s1210_spi_exit);
+
+MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices AD2S1210 Resolver to Digital SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c
new file mode 100644
index 0000000..4143535
--- /dev/null
+++ b/drivers/staging/iio/resolver/ad2s90.c
@@ -0,0 +1,159 @@
+/*
+ * ad2s90.c simple support for the ADI Resolver to Digital Converters: AD2S90
+ *
+ * Copyright (c) 2010-2010 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#define DRV_NAME "ad2s90"
+
+struct ad2s90_state {
+	struct mutex lock;
+	struct iio_dev *idev;
+	struct spi_device *sdev;
+	u8 rx[2];
+	u8 tx[2];
+};
+
+static ssize_t ad2s90_show_angular(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer;
+	int ret;
+	ssize_t len = 0;
+	u16 val;
+	struct iio_dev *idev = dev_get_drvdata(dev);
+	struct ad2s90_state *st = idev->dev_data;
+
+	xfer.len = 1;
+	xfer.tx_buf = st->tx;
+	xfer.rx_buf = st->rx;
+	mutex_lock(&st->lock);
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->sdev, &msg);
+	if (ret)
+		goto error_ret;
+	val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
+	len = sprintf(buf, "%d\n", val);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+#define IIO_DEV_ATTR_SIMPLE_RESOLVER(_show) \
+	IIO_DEVICE_ATTR(angular, S_IRUGO, _show, NULL, 0)
+
+static IIO_CONST_ATTR(description,
+	"Low Cost, Complete 12-Bit Resolver-to-Digital Converter");
+static IIO_DEV_ATTR_SIMPLE_RESOLVER(ad2s90_show_angular);
+
+static struct attribute *ad2s90_attributes[] = {
+	&iio_const_attr_description.dev_attr.attr,
+	&iio_dev_attr_angular.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad2s90_attribute_group = {
+	.name = DRV_NAME,
+	.attrs = ad2s90_attributes,
+};
+
+static int __devinit ad2s90_probe(struct spi_device *spi)
+{
+	struct ad2s90_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	mutex_init(&st->lock);
+	st->sdev = spi;
+
+	st->idev = iio_allocate_device();
+	if (st->idev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->idev->dev.parent = &spi->dev;
+	st->idev->num_interrupt_lines = 0;
+	st->idev->event_attrs = NULL;
+
+	st->idev->attrs = &ad2s90_attribute_group;
+	st->idev->dev_data = (void *)(st);
+	st->idev->driver_module = THIS_MODULE;
+	st->idev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->idev);
+	if (ret)
+		goto error_free_dev;
+
+	/* need 600ns between CS and the first falling edge of SCLK */
+	spi->max_speed_hz = 830000;
+	spi->mode = SPI_MODE_3;
+	spi_setup(spi);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->idev);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad2s90_remove(struct spi_device *spi)
+{
+	struct ad2s90_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->idev);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver ad2s90_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = ad2s90_probe,
+	.remove = __devexit_p(ad2s90_remove),
+};
+
+static __init int ad2s90_spi_init(void)
+{
+	return spi_register_driver(&ad2s90_driver);
+}
+module_init(ad2s90_spi_init);
+
+static __exit void ad2s90_spi_exit(void)
+{
+	spi_unregister_driver(&ad2s90_driver);
+}
+module_exit(ad2s90_spi_exit);
+
+MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices AD2S90 Resolver to Digital SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index ee91a95..18bdaac 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -108,6 +108,12 @@
 	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
 
 /**
+ * IIO_DEV_ATTR_RESET: resets the device
+ **/
+#define IIO_DEV_ATTR_RESET(_store)			\
+	IIO_DEVICE_ATTR(reset, S_IWUGO, NULL, _store, 0)
+
+/**
  * IIO_CONST_ATTR_NAME - constant identifier
  * @_string: the name
  **/
diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c
index 24d3928..0ba6742 100644
--- a/drivers/staging/intel_sst/intel_sst.c
+++ b/drivers/staging/intel_sst/intel_sst.c
@@ -29,6 +29,8 @@
  *  This file contains all init functions
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
@@ -169,17 +171,17 @@
 {
 	int i, ret = 0;
 
-	pr_debug("sst: Probe for DID %x\n", pci->device);
+	pr_debug("Probe for DID %x\n", pci->device);
 	mutex_lock(&drv_ctx_lock);
 	if (sst_drv_ctx) {
-		pr_err("sst: Only one sst handle is supported\n");
+		pr_err("Only one sst handle is supported\n");
 		mutex_unlock(&drv_ctx_lock);
 		return -EBUSY;
 	}
 
 	sst_drv_ctx = kzalloc(sizeof(*sst_drv_ctx), GFP_KERNEL);
 	if (!sst_drv_ctx) {
-		pr_err("sst: intel_sst malloc fail\n");
+		pr_err("malloc fail\n");
 		mutex_unlock(&drv_ctx_lock);
 		return -ENOMEM;
 	}
@@ -226,7 +228,7 @@
 	spin_lock_init(&sst_drv_ctx->list_spin_lock);
 
 	sst_drv_ctx->max_streams = pci_id->driver_data;
-	pr_debug("sst: Got drv data max stream %d\n",
+	pr_debug("Got drv data max stream %d\n",
 				sst_drv_ctx->max_streams);
 	for (i = 1; i <= sst_drv_ctx->max_streams; i++) {
 		struct stream_info *stream = &sst_drv_ctx->streams[i];
@@ -241,18 +243,18 @@
 			sst_drv_ctx->mmap_mem =
 				kzalloc(sst_drv_ctx->mmap_len, GFP_KERNEL);
 			if (sst_drv_ctx->mmap_mem) {
-				pr_debug("sst: Got memory %p size 0x%x\n",
+				pr_debug("Got memory %p size 0x%x\n",
 					sst_drv_ctx->mmap_mem,
 					sst_drv_ctx->mmap_len);
 				break;
 			}
 			if (sst_drv_ctx->mmap_len < (SST_MMAP_STEP*PAGE_SIZE)) {
-				pr_err("sst: mem alloc fail...abort!!\n");
+				pr_err("mem alloc fail...abort!!\n");
 				ret = -ENOMEM;
 				goto free_process_reply_wq;
 			}
 			sst_drv_ctx->mmap_len -= (SST_MMAP_STEP * PAGE_SIZE);
-			pr_debug("sst:mem alloc failed...trying %d\n",
+			pr_debug("mem alloc failed...trying %d\n",
 						sst_drv_ctx->mmap_len);
 		}
 	}
@@ -260,7 +262,7 @@
 	/* Init the device */
 	ret = pci_enable_device(pci);
 	if (ret) {
-		pr_err("sst: device cant be enabled\n");
+		pr_err("device cant be enabled\n");
 		goto do_free_mem;
 	}
 	sst_drv_ctx->pci = pci_dev_get(pci);
@@ -273,25 +275,25 @@
 	sst_drv_ctx->shim = pci_ioremap_bar(pci, 1);
 	if (!sst_drv_ctx->shim)
 		goto do_release_regions;
-	pr_debug("sst: SST Shim Ptr %p\n", sst_drv_ctx->shim);
+	pr_debug("SST Shim Ptr %p\n", sst_drv_ctx->shim);
 
 	/* Shared SRAM */
 	sst_drv_ctx->mailbox = pci_ioremap_bar(pci, 2);
 	if (!sst_drv_ctx->mailbox)
 		goto do_unmap_shim;
-	pr_debug("sst: SRAM Ptr %p\n", sst_drv_ctx->mailbox);
+	pr_debug("SRAM Ptr %p\n", sst_drv_ctx->mailbox);
 
 	/* IRAM */
 	sst_drv_ctx->iram = pci_ioremap_bar(pci, 3);
 	if (!sst_drv_ctx->iram)
 		goto do_unmap_sram;
-	pr_debug("sst:IRAM Ptr %p\n", sst_drv_ctx->iram);
+	pr_debug("IRAM Ptr %p\n", sst_drv_ctx->iram);
 
 	/* DRAM */
 	sst_drv_ctx->dram = pci_ioremap_bar(pci, 4);
 	if (!sst_drv_ctx->dram)
 		goto do_unmap_iram;
-	pr_debug("sst: DRAM Ptr %p\n", sst_drv_ctx->dram);
+	pr_debug("DRAM Ptr %p\n", sst_drv_ctx->dram);
 
 	mutex_lock(&sst_drv_ctx->sst_lock);
 	sst_drv_ctx->sst_state = SST_UN_INIT;
@@ -301,24 +303,24 @@
 		IRQF_SHARED, SST_DRV_NAME, sst_drv_ctx);
 	if (ret)
 		goto do_unmap_dram;
-	pr_debug("sst: Registered IRQ 0x%x\n", pci->irq);
+	pr_debug("Registered IRQ 0x%x\n", pci->irq);
 
 	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
 		ret = misc_register(&lpe_dev);
 		if (ret) {
-			pr_err("sst: couldn't register LPE device\n");
+			pr_err("couldn't register LPE device\n");
 			goto do_free_irq;
 		}
 
 		/*Register LPE Control as misc driver*/
 		ret = misc_register(&lpe_ctrl);
 		if (ret) {
-			pr_err("sst: couldn't register misc driver\n");
+			pr_err("couldn't register misc driver\n");
 			goto do_free_irq;
 		}
 	}
 	sst_drv_ctx->lpe_stalled = 0;
-	pr_debug("sst: ...successfully done!!!\n");
+	pr_debug("...successfully done!!!\n");
 	return ret;
 
 do_free_irq:
@@ -347,7 +349,7 @@
 	destroy_workqueue(sst_drv_ctx->mad_wq);
 do_free_drv_ctx:
 	kfree(sst_drv_ctx);
-	pr_err("sst: Probe failed with 0x%x\n", ret);
+	pr_err("Probe failed with 0x%x\n", ret);
 	return ret;
 }
 
@@ -404,7 +406,7 @@
 {
 	union config_status_reg csr;
 
-	pr_debug("sst: intel_sst_suspend called\n");
+	pr_debug("intel_sst_suspend called\n");
 
 	if (sst_drv_ctx->pb_streams != 0 || sst_drv_ctx->cp_streams != 0)
 		return -EPERM;
@@ -434,9 +436,9 @@
 {
 	int ret = 0;
 
-	pr_debug("sst: intel_sst_resume called\n");
+	pr_debug("intel_sst_resume called\n");
 	if (sst_drv_ctx->sst_state != SST_SUSPENDED) {
-		pr_err("sst: SST is not in suspended state\n");
+		pr_err("SST is not in suspended state\n");
 		return -EPERM;
 	}
 	sst_drv_ctx = pci_get_drvdata(pci);
@@ -444,7 +446,7 @@
 	pci_restore_state(pci);
 	ret = pci_enable_device(pci);
 	if (ret)
-		pr_err("sst: device cant be enabled\n");
+		pr_err("device cant be enabled\n");
 
 	mutex_lock(&sst_drv_ctx->sst_lock);
 	sst_drv_ctx->sst_state = SST_UN_INIT;
@@ -482,14 +484,14 @@
 {
 	/* Init all variables, data structure etc....*/
 	int ret = 0;
-	pr_debug("sst: INFO: ******** SST DRIVER loading.. Ver: %s\n",
+	pr_debug("INFO: ******** SST DRIVER loading.. Ver: %s\n",
 				       SST_DRIVER_VERSION);
 
 	mutex_init(&drv_ctx_lock);
 	/* Register with PCI */
 	ret = pci_register_driver(&driver);
 	if (ret)
-		pr_err("sst: PCI register failed\n");
+		pr_err("PCI register failed\n");
 	return ret;
 }
 
@@ -504,7 +506,7 @@
 {
 	pci_unregister_driver(&driver);
 
-	pr_debug("sst: driver unloaded\n");
+	pr_debug("driver unloaded\n");
 	return;
 }
 
diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c
index 9618c79..0990955 100644
--- a/drivers/staging/intel_sst/intel_sst_app_interface.c
+++ b/drivers/staging/intel_sst/intel_sst_app_interface.c
@@ -27,6 +27,8 @@
  *  Upper layer interfaces (MAD driver, MMF) to SST driver
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/uio.h>
@@ -59,14 +61,14 @@
 {
 	int retval = 0;
 	if (sst_drv_ctx->pmic_state != SND_MAD_INIT_DONE) {
-		pr_warn("sst: Sound card not availble\n ");
+		pr_warn("Sound card not available\n");
 		return -EIO;
 	}
 	if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
-		pr_debug("sst: Resuming from Suspended state\n");
+		pr_debug("Resuming from Suspended state\n");
 		retval = intel_sst_resume(sst_drv_ctx->pci);
 		if (retval) {
-			pr_debug("sst: Resume Failed= %#x,abort\n", retval);
+			pr_debug("Resume Failed= %#x,abort\n", retval);
 			return retval;
 		}
 	}
@@ -116,7 +118,7 @@
 		data->pvt_id = sst_assign_pvt_id(sst_drv_ctx);
 		data->str_id = 0;
 		file_ptr->private_data = (void *)data;
-		pr_debug("sst: pvt_id handle = %d!\n", data->pvt_id);
+		pr_debug("pvt_id handle = %d!\n", data->pvt_id);
 	} else {
 		retval = -EUSERS;
 		mutex_unlock(&sst_drv_ctx->stream_lock);
@@ -145,7 +147,7 @@
 	mutex_lock(&sst_drv_ctx->stream_lock);
 	if (sst_drv_ctx->am_cnt < MAX_AM_HANDLES) {
 		sst_drv_ctx->am_cnt++;
-		pr_debug("sst: AM handle opened...\n");
+		pr_debug("AM handle opened...\n");
 		file_ptr->private_data = NULL;
 	} else
 		retval = -EACCES;
@@ -167,7 +169,7 @@
 {
 	struct ioctl_pvt_data *data = file_ptr->private_data;
 
-	pr_debug("sst: Release called, closing app handle\n");
+	pr_debug("Release called, closing app handle\n");
 	mutex_lock(&sst_drv_ctx->stream_lock);
 	sst_drv_ctx->encoded_cnt--;
 	sst_drv_ctx->stream_cnt--;
@@ -183,7 +185,7 @@
 	mutex_lock(&sst_drv_ctx->stream_lock);
 	sst_drv_ctx->am_cnt--;
 	mutex_unlock(&sst_drv_ctx->stream_lock);
-	pr_debug("sst: AM handle closed\n");
+	pr_debug("AM handle closed\n");
 	return 0;
 }
 
@@ -209,7 +211,7 @@
 		return -EINVAL;
 
 	length = vma->vm_end - vma->vm_start;
-	pr_debug("sst: called for stream %d length 0x%x\n", str_id, length);
+	pr_debug("called for stream %d length 0x%x\n", str_id, length);
 
 	if (length > sst_drv_ctx->mmap_len)
 		return -ENOMEM;
@@ -232,7 +234,7 @@
 	else
 		sst_drv_ctx->streams[str_id].mmapped = true;
 
-	pr_debug("sst: mmap ret 0x%x\n", retval);
+	pr_debug("mmap ret 0x%x\n", retval);
 	return retval;
 }
 
@@ -246,7 +248,7 @@
 	struct snd_sst_mmap_buff_entry *buf_entry;
 	struct snd_sst_mmap_buff_entry *tmp_buf;
 
-	pr_debug("sst:called for str_id %d\n", str_id);
+	pr_debug("called for str_id %d\n", str_id);
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return -EINVAL;
@@ -271,7 +273,7 @@
 		goto out_free;
 	}
 
-	pr_debug("sst:new buffers count %d status %d\n",
+	pr_debug("new buffers count %d status %d\n",
 			mmap_buf->entries, stream->status);
 	buf_entry = tmp_buf;
 	for (i = 0; i < mmap_buf->entries; i++) {
@@ -301,14 +303,14 @@
 		stream->status = STREAM_RUNNING;
 		if (stream->ops == STREAM_OPS_PLAYBACK) {
 			if (sst_play_frame(str_id) < 0) {
-				pr_warn("sst: play frames fail\n");
+				pr_warn("play frames fail\n");
 				mutex_unlock(&stream->lock);
 				retval = -EIO;
 				goto out_free;
 			}
 		} else if (stream->ops == STREAM_OPS_CAPTURE) {
 			if (sst_capture_frame(str_id) < 0) {
-				pr_warn("sst: capture frame fail\n");
+				pr_warn("capture frame fail\n");
 				mutex_unlock(&stream->lock);
 				retval = -EIO;
 				goto out_free;
@@ -325,7 +327,7 @@
 
 	if (retval >= 0)
 		retval = stream->cumm_bytes;
-	pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval);
+	pr_debug("end of play/rec ioctl bytes = %d!!\n", retval);
 
 out_free:
 	kfree(tmp_buf);
@@ -350,7 +352,7 @@
 
 	if (stream->status == STREAM_INIT && stream->prev == STREAM_UN_INIT) {
 		/* stream is not started yet */
-		pr_debug("sst: Stream isn't in started state %d, prev %d\n",
+		pr_debug("Stream isn't in started state %d, prev %d\n",
 			stream->status, stream->prev);
 	} else if ((stream->status == STREAM_RUNNING ||
 			stream->status == STREAM_PAUSED) &&
@@ -359,13 +361,13 @@
 		if (stream->ops == STREAM_OPS_PLAYBACK ||
 				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
 			if (sst_play_frame(str_id) < 0) {
-				pr_warn("sst: play frames failed\n");
+				pr_warn("play frames failed\n");
 				mutex_unlock(&stream->lock);
 				return -EIO;
 			}
 		} else if (stream->ops == STREAM_OPS_CAPTURE) {
 			if (sst_capture_frame(str_id) < 0) {
-				pr_warn("sst: capture frames failed\n ");
+				pr_warn("capture frames failed\n");
 				mutex_unlock(&stream->lock);
 				return -EIO;
 			}
@@ -380,7 +382,7 @@
 	retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk);
 	if (retval) {
 		stream->status = STREAM_INIT;
-		pr_debug("sst: wait returned error...\n");
+		pr_debug("wait returned error...\n");
 	}
 	return retval;
 }
@@ -478,7 +480,7 @@
 		if (((unsigned long)iovec[index].iov_base
 				+ iovec[index].iov_len) <
 				((unsigned long)iovec[index].iov_base)) {
-			pr_debug("sst: Buffer overflows");
+			pr_debug("Buffer overflows\n");
 			kfree(stream_bufs);
 			return -EINVAL;
 		}
@@ -491,7 +493,7 @@
 		}
 
 		copied_size += size;
-		pr_debug("sst: copied_size - %lx\n", copied_size);
+		pr_debug("copied_size - %lx\n", copied_size);
 		if ((copied_size >= mmap_len) ||
 				(stream->sg_index == nr_segs)) {
 			add_to_list = 1;
@@ -521,7 +523,7 @@
 	int retval = 0;
 
 	/* copy sent buffers */
-	pr_debug("sst: capture stream copying to user now...\n");
+	pr_debug("capture stream copying to user now...\n");
 	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
 		if (kbufs->in_use == true) {
 			/* copy to user */
@@ -539,7 +541,7 @@
 			}
 		}
 	}
-	pr_debug("sst: end of cap copy\n");
+	pr_debug("end of cap copy\n");
 	return retval;
 }
 
@@ -591,7 +593,7 @@
 		return -EINVAL;
 	stream = &sst_drv_ctx->streams[str_id];
 	if (stream->mmapped == true) {
-		pr_warn("sst: user write and stream is mapped");
+		pr_warn("user write and stream is mapped\n");
 		return -EIO;
 	}
 	if (!count)
@@ -599,7 +601,7 @@
 	stream->curr_bytes = 0;
 	stream->cumm_bytes = 0;
 	/* copy user buf details */
-	pr_debug("sst: new buffers %p, copy size %d, status %d\n" ,
+	pr_debug("new buffers %p, copy size %d, status %d\n" ,
 			buf, (int) count, (int) stream->status);
 
 	stream->buf_type = SST_BUF_USER_STATIC;
@@ -619,7 +621,7 @@
 	stream->cur_ptr = NULL;
 	if (retval >= 0)
 		retval = stream->cumm_bytes;
-	pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
+	pr_debug("end of play/rec bytes = %d!!\n", retval);
 	return retval;
 }
 
@@ -640,7 +642,7 @@
 	int str_id = data->str_id;
 	struct stream_info *stream = &sst_drv_ctx->streams[str_id];
 
-	pr_debug("sst: called for %d\n", str_id);
+	pr_debug("called for %d\n", str_id);
 	if (stream->status == STREAM_UN_INIT ||
 		stream->status == STREAM_DECODE) {
 		return -EBADRQC;
@@ -666,12 +668,12 @@
 	int str_id = data->str_id;
 	struct stream_info *stream;
 
-	pr_debug("sst: entry - %ld\n", nr_segs);
+	pr_debug("entry - %ld\n", nr_segs);
 
 	if (is_sync_kiocb(kiocb) == false)
 		return -EINVAL;
 
-	pr_debug("sst: called for str_id %d\n", str_id);
+	pr_debug("called for str_id %d\n", str_id);
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return -EINVAL;
@@ -684,7 +686,7 @@
 	}
 	stream->curr_bytes = 0;
 	stream->cumm_bytes = 0;
-	pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
+	pr_debug("new segs %ld, offset %d, status %d\n" ,
 			nr_segs, (int) offset, (int) stream->status);
 	stream->buf_type = SST_BUF_USER_STATIC;
 	do {
@@ -699,7 +701,7 @@
 	stream->cur_ptr = NULL;
 	if (retval >= 0)
 		retval = stream->cumm_bytes;
-	pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
+	pr_debug("end of play/rec bytes = %d!!\n", retval);
 	return retval;
 }
 
@@ -720,7 +722,7 @@
 	int str_id = data->str_id;
 	struct stream_info *stream = &sst_drv_ctx->streams[str_id];
 
-	pr_debug("sst: called for %d\n", str_id);
+	pr_debug("called for %d\n", str_id);
 	if (stream->status == STREAM_UN_INIT ||
 			stream->status == STREAM_DECODE)
 		return -EBADRQC;
@@ -745,14 +747,14 @@
 	int str_id = data->str_id;
 	struct stream_info *stream;
 
-	pr_debug("sst: entry - %ld\n", nr_segs);
+	pr_debug("entry - %ld\n", nr_segs);
 
 	if (is_sync_kiocb(kiocb) == false) {
-		pr_debug("sst: aio_read from user space is not allowed\n");
+		pr_debug("aio_read from user space is not allowed\n");
 		return -EINVAL;
 	}
 
-	pr_debug("sst: called for str_id %d\n", str_id);
+	pr_debug("called for str_id %d\n", str_id);
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return -EINVAL;
@@ -765,7 +767,7 @@
 	stream->curr_bytes = 0;
 	stream->cumm_bytes = 0;
 
-	pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
+	pr_debug("new segs %ld, offset %d, status %d\n" ,
 			nr_segs, (int) offset, (int) stream->status);
 	stream->buf_type = SST_BUF_USER_STATIC;
 	do {
@@ -780,34 +782,34 @@
 	stream->cur_ptr = NULL;
 	if (retval >= 0)
 		retval = stream->cumm_bytes;
-	pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
+	pr_debug("end of play/rec bytes = %d!!\n", retval);
 	return retval;
 }
 
 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
 static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm)
 {
-	pr_debug("sst: codec params:result =%d\n",
+	pr_debug("codec params:result = %d\n",
 				get_prm->codec_params.result);
-	pr_debug("sst: codec params:stream = %d\n",
+	pr_debug("codec params:stream = %d\n",
 				get_prm->codec_params.stream_id);
-	pr_debug("sst: codec params:codec = %d\n",
+	pr_debug("codec params:codec = %d\n",
 				get_prm->codec_params.codec);
-	pr_debug("sst: codec params:ops = %d\n",
+	pr_debug("codec params:ops = %d\n",
 				get_prm->codec_params.ops);
-	pr_debug("sst: codec params:stream_type= %d\n",
+	pr_debug("codec params:stream_type = %d\n",
 				get_prm->codec_params.stream_type);
-	pr_debug("sst: pcmparams:sfreq= %d\n",
+	pr_debug("pcmparams:sfreq = %d\n",
 				get_prm->pcm_params.sfreq);
-	pr_debug("sst: pcmparams:num_chan= %d\n",
+	pr_debug("pcmparams:num_chan = %d\n",
 				get_prm->pcm_params.num_chan);
-	pr_debug("sst: pcmparams:pcm_wd_sz= %d\n",
+	pr_debug("pcmparams:pcm_wd_sz = %d\n",
 				get_prm->pcm_params.pcm_wd_sz);
 	return;
 }
 
 /**
- * intel_sst_ioctl - recieves the device ioctl's
+ * intel_sst_ioctl - receives the device ioctl's
  * @file_ptr:pointer to file
  * @cmd:Ioctl cmd
  * @arg:data
@@ -833,7 +835,7 @@
 
 	switch (_IOC_NR(cmd)) {
 	case _IOC_NR(SNDRV_SST_STREAM_PAUSE):
-		pr_debug("sst: IOCTL_PAUSE recieved for %d!\n", str_id);
+		pr_debug("IOCTL_PAUSE received for %d!\n", str_id);
 		if (minor != STREAM_MODULE) {
 			retval = -EBADRQC;
 			break;
@@ -842,7 +844,7 @@
 		break;
 
 	case _IOC_NR(SNDRV_SST_STREAM_RESUME):
-		pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n");
+		pr_debug("SNDRV_SST_IOCTL_RESUME received!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EBADRQC;
 			break;
@@ -853,7 +855,7 @@
 	case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
 		struct snd_sst_params str_param;
 
-		pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
+		pr_debug("IOCTL_SET_PARAMS received!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EBADRQC;
 			break;
@@ -885,7 +887,7 @@
 					retval = -EINVAL;
 			}
 		} else {
-			pr_debug("sst: SET_STREAM_PARAMS recieved!\n");
+			pr_debug("SET_STREAM_PARAMS received!\n");
 			/* allocated set params only */
 			retval = sst_set_stream_param(str_id, &str_param);
 			/* Block the call for reply */
@@ -908,14 +910,14 @@
 
 		if (copy_from_user(&set_vol, (void __user *)arg,
 				sizeof(set_vol))) {
-			pr_debug("sst: copy failed\n");
+			pr_debug("copy failed\n");
 			retval = -EFAULT;
 			break;
 		}
-		pr_debug("sst: SET_VOLUME recieved for %d!\n",
+		pr_debug("SET_VOLUME recieved for %d!\n",
 				set_vol.stream_id);
 		if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
-			pr_debug("sst: invalid operation!\n");
+			pr_debug("invalid operation!\n");
 			retval = -EPERM;
 			break;
 		}
@@ -930,10 +932,10 @@
 			retval = -EFAULT;
 			break;
 		}
-		pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
+		pr_debug("IOCTL_GET_VOLUME recieved for stream = %d!\n",
 				get_vol.stream_id);
 		if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
-			pr_debug("sst: invalid operation!\n");
+			pr_debug("invalid operation!\n");
 			retval = -EPERM;
 			break;
 		}
@@ -942,7 +944,7 @@
 			retval = -EIO;
 			break;
 		}
-		pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
+		pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
 				get_vol.stream_id, get_vol.volume,
 				get_vol.ramp_duration, get_vol.ramp_type);
 		if (copy_to_user((struct snd_sst_vol __user *)arg,
@@ -962,7 +964,7 @@
 			retval = -EFAULT;
 			break;
 		}
-		pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
+		pr_debug("SNDRV_SST_SET_VOLUME recieved for %d!\n",
 			set_mute.stream_id);
 		if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
 			retval = -EPERM;
@@ -974,7 +976,7 @@
 	case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
 		struct snd_sst_get_stream_params get_params;
 
-		pr_debug("sst: IOCTL_GET_PARAMS recieved!\n");
+		pr_debug("IOCTL_GET_PARAMS received!\n");
 		if (minor != 0) {
 			retval = -EBADRQC;
 			break;
@@ -998,7 +1000,7 @@
 	case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): {
 		struct snd_sst_mmap_buffs mmap_buf;
 
-		pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
+		pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EBADRQC;
 			break;
@@ -1012,7 +1014,7 @@
 		break;
 	}
 	case _IOC_NR(SNDRV_SST_STREAM_DROP):
-		pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
+		pr_debug("SNDRV_SST_IOCTL_DROP received!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EINVAL;
 			break;
@@ -1024,7 +1026,7 @@
 		struct snd_sst_tstamp tstamp = {0};
 		unsigned long long time, freq, mod;
 
-		pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n");
+		pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EBADRQC;
 			break;
@@ -1045,7 +1047,7 @@
 	case _IOC_NR(SNDRV_SST_STREAM_START):{
 		struct stream_info *stream;
 
-		pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n");
+		pr_debug("SNDRV_SST_STREAM_START received!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EINVAL;
 			break;
@@ -1084,7 +1086,7 @@
 	case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
 		struct snd_sst_target_device target_device;
 
-		pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
+		pr_debug("SET_TARGET_DEVICE recieved!\n");
 		if (copy_from_user(&target_device, (void __user *)arg,
 				sizeof(target_device))) {
 			retval = -EFAULT;
@@ -1101,7 +1103,7 @@
 	case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
 		struct snd_sst_driver_info info;
 
-		pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n");
+		pr_debug("SNDRV_SST_DRIVER_INFO recived\n");
 		info.version = SST_VERSION_NUM;
 		/* hard coding, shud get sumhow later */
 		info.active_pcm_streams = sst_drv_ctx->stream_cnt -
@@ -1123,7 +1125,7 @@
 		struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp;
 		char __user *dest;
 
-		pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
+		pr_debug("SNDRV_SST_STREAM_DECODE received\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EBADRQC;
 			break;
@@ -1198,7 +1200,7 @@
 	}
 
 	case _IOC_NR(SNDRV_SST_STREAM_DRAIN):
-		pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n");
+		pr_debug("SNDRV_SST_STREAM_DRAIN received\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EINVAL;
 			break;
@@ -1210,7 +1212,7 @@
 		unsigned long long __user *bytes = (unsigned long long __user *)arg;
 		struct snd_sst_tstamp tstamp = {0};
 
-		pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
+		pr_debug("STREAM_BYTES_DECODED received!\n");
 		if (minor != STREAM_MODULE) {
 			retval = -EINVAL;
 			break;
@@ -1226,7 +1228,7 @@
 	case _IOC_NR(SNDRV_SST_FW_INFO): {
 		struct snd_sst_fw_info *fw_info;
 
-		pr_debug("sst: SNDRV_SST_FW_INFO recived\n");
+		pr_debug("SNDRV_SST_FW_INFO received\n");
 
 		fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC);
 		if (!fw_info) {
@@ -1252,7 +1254,7 @@
 	default:
 		retval = -EINVAL;
 	}
-	pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval);
+	pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval);
 	return retval;
 }
 
diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c
index 669e298..5b10ddf 100644
--- a/drivers/staging/intel_sst/intel_sst_drv_interface.c
+++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c
@@ -26,6 +26,8 @@
  *  Upper layer interfaces (MAD driver, MMF) to SST driver
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/fs.h>
@@ -52,10 +54,10 @@
 		name = SST_FW_FILENAME_MRST;
 	else
 		name = SST_FW_FILENAME_MFLD;
-	pr_debug("sst: Downloading %s FW now...\n", name);
+	pr_debug("Downloading %s FW now...\n", name);
 	retval = request_firmware(&fw_sst, name, &sst_drv_ctx->pci->dev);
 	if (retval) {
-		pr_err("sst: request fw failed %d\n", retval);
+		pr_err("request fw failed %d\n", retval);
 		return retval;
 	}
 	sst_drv_ctx->alloc_block[0].sst_id = FW_DWNL_ID;
@@ -66,7 +68,7 @@
 
 	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[0]);
 	if (retval)
-		pr_err("sst: fw download failed %d\n" , retval);
+		pr_err("fw download failed %d\n" , retval);
 end_restore:
 	release_firmware(fw_sst);
 	sst_drv_ctx->alloc_block[0].sst_id = BLOCK_UNINIT;
@@ -90,7 +92,7 @@
 
 		retry--;
 	}
-	pr_debug("sst: in Stalled State\n");
+	pr_debug("in Stalled State\n");
 	return retval;
 }
 
@@ -138,23 +140,23 @@
 	retval = sst_alloc_stream((char *) &str_param->sparams, str_param->ops,
 				str_param->codec, str_param->device_type);
 	if (retval < 0) {
-		pr_err("sst: sst_alloc_stream failed %d\n", retval);
+		pr_err("sst_alloc_stream failed %d\n", retval);
 		return retval;
 	}
-	pr_debug("sst: Stream allocated %d\n", retval);
+	pr_debug("Stream allocated %d\n", retval);
 	str_id = retval;
 	str_info = &sst_drv_ctx->streams[str_id];
 	/* Block the call for reply */
 	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 			&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
 	if ((retval != 0) || (str_info->ctrl_blk.ret_code != 0)) {
-		pr_debug("sst: FW alloc failed retval %d, ret_code %d\n",
+		pr_debug("FW alloc failed retval %d, ret_code %d\n",
 				retval, str_info->ctrl_blk.ret_code);
 		str_id = -str_info->ctrl_blk.ret_code; /*return error*/
 		*lib_dnld = str_info->ctrl_blk.data;
 		sst_clean_stream(str_info);
 	} else
-		pr_debug("sst: FW Stream allocated sucess\n");
+		pr_debug("FW Stream allocated success\n");
 	return str_id; /*will ret either error (in above if) or correct str id*/
 }
 
@@ -196,14 +198,14 @@
 		/* codec download is required */
 		struct snd_sst_alloc_response *response;
 
-		pr_debug("sst: Codec is required.... trying that\n");
+		pr_debug("Codec is required.... trying that\n");
 		if (lib_dnld == NULL) {
-			pr_err("sst: lib download null!!! abort\n");
+			pr_err("lib download null!!! abort\n");
 			return -EIO;
 		}
 		i = sst_get_block_stream(sst_drv_ctx);
 		response = sst_drv_ctx->alloc_block[i].ops_block.data;
-		pr_debug("sst: alloc block allocated = %d\n", i);
+		pr_debug("alloc block allocated = %d\n", i);
 		if (i < 0) {
 			kfree(lib_dnld);
 			return -ENOMEM;
@@ -213,15 +215,15 @@
 
 		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
 		if (!retval) {
-			pr_debug("sst: codec was downloaded sucesfully\n");
+			pr_debug("codec was downloaded successfully\n");
 
 			retval = sst_get_stream_allocated(str_param, &lib_dnld);
 			if (retval <= 0)
 				goto err;
 
-			pr_debug("sst: Alloc done stream id %d\n", retval);
+			pr_debug("Alloc done stream id %d\n", retval);
 		} else {
-			pr_debug("sst: codec download failed\n");
+			pr_debug("codec download failed\n");
 			retval = -EIO;
 			goto err;
 		}
@@ -279,10 +281,10 @@
 		retval = sst_start_stream(mad_ops->stream_id);
 		break;
 	case SST_SND_STREAM_PROCESS:
-		pr_debug("sst: play/capt frames...\n");
+		pr_debug("play/capt frames...\n");
 		break;
 	default:
-		pr_err("sst:  wrong control_ops reported\n");
+		pr_err(" wrong control_ops reported\n");
 	}
 	return;
 }
@@ -301,19 +303,19 @@
 
 	if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
 		/*LPE is suspended, resume it before proceding*/
-		pr_debug("sst: Resuming from Suspended state\n");
+		pr_debug("Resuming from Suspended state\n");
 		retval = intel_sst_resume(sst_drv_ctx->pci);
 		if (retval) {
-			pr_err("sst: Resume Failed = %#x, abort\n", retval);
+			pr_err("Resume Failed = %#x, abort\n", retval);
 			return retval;
 		}
 	}
 	if (sst_drv_ctx->sst_state == SST_UN_INIT) {
 		/* FW is not downloaded */
-		pr_debug("sst: DSP Downloading FW now...\n");
+		pr_debug("DSP Downloading FW now...\n");
 		retval = sst_download_fw();
 		if (retval) {
-			pr_err("sst: FW download fail %x, abort\n", retval);
+			pr_err("FW download fail %x, abort\n", retval);
 			return retval;
 		}
 		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID &&
@@ -361,7 +363,7 @@
 		struct pcm_stream_info *str_info;
 		struct stream_info *stream;
 
-		pr_debug("sst: stream init called\n");
+		pr_debug("stream init called\n");
 		str_info = (struct pcm_stream_info *)value;
 		str_id = str_info->str_id;
 		retval = sst_validate_strid(str_id);
@@ -369,7 +371,7 @@
 			break;
 
 		stream = &sst_drv_ctx->streams[str_id];
-		pr_debug("sst: setting the period ptrs\n");
+		pr_debug("setting the period ptrs\n");
 		stream->pcm_substream = str_info->mad_substream;
 		stream->period_elapsed = str_info->period_elapsed;
 		stream->sfreq = str_info->sfreq;
@@ -398,14 +400,14 @@
 			+(str_id * sizeof(fw_tstamp))),
 			sizeof(fw_tstamp));
 
-		pr_debug("sst: Pointer Query on strid = %d ops %d\n",
+		pr_debug("Pointer Query on strid = %d ops %d\n",
 						str_id, stream->ops);
 
 		if (stream->ops == STREAM_OPS_PLAYBACK)
 			stream_info->buffer_ptr = fw_tstamp.samples_rendered;
 		else
 			stream_info->buffer_ptr = fw_tstamp.samples_processed;
-		pr_debug("sst: Samples rendered = %llu, buffer ptr %llu\n",
+		pr_debug("Samples rendered = %llu, buffer ptr %llu\n",
 			fw_tstamp.samples_rendered, stream_info->buffer_ptr);
 		break;
 	}
@@ -417,7 +419,7 @@
 	}
 	default:
 		/* Illegal case */
-		pr_warn("sst: illegal req\n");
+		pr_warn("illegal req\n");
 		return -EINVAL;
 	}
 
@@ -439,12 +441,12 @@
 int register_sst_card(struct intel_sst_card_ops *card)
 {
 	if (!sst_drv_ctx) {
-		pr_err("sst: No SST driver register card reject\n");
+		pr_err("No SST driver register card reject\n");
 		return -ENODEV;
 	}
 
 	if (!card || !card->module_name) {
-		pr_err("sst: Null Pointer Passed\n");
+		pr_err("Null Pointer Passed\n");
 		return -EINVAL;
 	}
 	if (sst_drv_ctx->pmic_state == SND_MAD_UN_INIT) {
@@ -460,13 +462,13 @@
 			sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
 			return 0;
 		} else {
-			pr_err("sst: strcmp fail %s\n", card->module_name);
+			pr_err("strcmp fail %s\n", card->module_name);
 			return -EINVAL;
 		}
 
 	} else {
 		/* already registered a driver */
-		pr_err("sst: Repeat for registeration..denied\n");
+		pr_err("Repeat for registration..denied\n");
 		return -EBADRQC;
 	}
 	return 0;
@@ -486,7 +488,7 @@
 		/* unreg */
 		sst_pmic_ops.module_name = "";
 		sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
-		pr_debug("sst: Unregistered %s\n", card->module_name);
+		pr_debug("Unregistered %s\n", card->module_name);
 	}
 	return;
 }
diff --git a/drivers/staging/intel_sst/intel_sst_dsp.c b/drivers/staging/intel_sst/intel_sst_dsp.c
index d80a6ee2..d1b0537 100644
--- a/drivers/staging/intel_sst/intel_sst_dsp.c
+++ b/drivers/staging/intel_sst/intel_sst_dsp.c
@@ -29,6 +29,9 @@
  *  This file contains all dsp controlling functions like firmware download,
  * setting/resetting dsp cores, etc
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/firmware.h>
@@ -47,7 +50,7 @@
 {
 	union config_status_reg csr;
 
-	pr_debug("sst: Resetting the DSP in mrst\n");
+	pr_debug("Resetting the DSP in mrst\n");
 	csr.full = 0x3a2;
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
 	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
@@ -68,7 +71,7 @@
 {
 	union config_status_reg csr;
 
-	pr_debug("sst: Resetting the DSP in medfield\n");
+	pr_debug("Resetting the DSP in medfield\n");
 	csr.full = 0x048303E2;
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
 
@@ -90,7 +93,7 @@
 	csr.part.run_stall = 0;
 	csr.part.sst_reset = 0;
 	csr.part.strb_cntr_rst = 1;
-	pr_debug("sst: Setting SST to execute_mrst 0x%x\n", csr.full);
+	pr_debug("Setting SST to execute_mrst 0x%x\n", csr.full);
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
 
 	return 0;
@@ -111,7 +114,7 @@
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
 	csr.full = 0x04830061;
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	pr_debug("sst: Starting the DSP_medfld\n");
+	pr_debug("Starting the DSP_medfld\n");
 
 	return 0;
 }
@@ -130,16 +133,16 @@
 	u32 count;
 	void __iomem *ram;
 
-	pr_debug("sst: module sign %s size %x blocks %x type %x\n",
+	pr_debug("module sign %s size %x blocks %x type %x\n",
 			module->signature, module->mod_size,
 			module->blocks, module->type);
-	pr_debug("sst: module entrypoint 0x%x\n", module->entry_point);
+	pr_debug("module entrypoint 0x%x\n", module->entry_point);
 
 	block = (void *)module + sizeof(*module);
 
 	for (count = 0; count < module->blocks; count++) {
 		if (block->size <= 0) {
-			pr_err("sst: block size invalid\n");
+			pr_err("block size invalid\n");
 			return -EINVAL;
 		}
 		switch (block->type) {
@@ -150,7 +153,7 @@
 			ram = sst_drv_ctx->dram;
 			break;
 		default:
-			pr_err("sst: wrong ram type0x%x in block0x%x\n",
+			pr_err("wrong ram type0x%x in block0x%x\n",
 					block->type, count);
 			return -EINVAL;
 		}
@@ -184,10 +187,10 @@
 	if ((strncmp(header->signature, SST_FW_SIGN, 4) != 0) ||
 			(sst_fw->size != header->file_size + sizeof(*header))) {
 		/* Invalid FW signature */
-		pr_err("sst: InvalidFW sign/filesize mismatch\n");
+		pr_err("Invalid FW sign/filesize mismatch\n");
 		return -EINVAL;
 	}
-	pr_debug("sst: header sign=%s size=%x modules=%x fmt=%x size=%x\n",
+	pr_debug("header sign=%s size=%x modules=%x fmt=%x size=%x\n",
 			header->signature, header->file_size, header->modules,
 			header->file_format, sizeof(*header));
 	module = (void *)sst_fw->data + sizeof(*header);
@@ -214,7 +217,7 @@
 {
 	int ret_val;
 
-	pr_debug("sst: load_fw called\n");
+	pr_debug("load_fw called\n");
 	BUG_ON(!fw);
 
 	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
@@ -239,7 +242,7 @@
 	if (ret_val)
 		return ret_val;
 
-	pr_debug("sst: fw loaded successful!!!\n");
+	pr_debug("fw loaded successful!!!\n");
 	return ret_val;
 }
 
@@ -261,7 +264,7 @@
 
 	pvt_id = sst_assign_pvt_id(sst_drv_ctx);
 	i = sst_get_block_stream(sst_drv_ctx);
-	pr_debug("sst: alloc block allocated = %d, pvt_id %d\n", i, pvt_id);
+	pr_debug("alloc block allocated = %d, pvt_id %d\n", i, pvt_id);
 	if (i < 0) {
 		kfree(msg);
 		return -ENOMEM;
@@ -281,11 +284,11 @@
 	if (retval) {
 		/* error */
 		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-		pr_err("sst: Prep codec downloaded failed %d\n",
+		pr_err("Prep codec downloaded failed %d\n",
 				retval);
 		return -EIO;
 	}
-	pr_debug("sst: FW responded, ready for download now...\n");
+	pr_debug("FW responded, ready for download now...\n");
 	/* downloading on success */
 	mutex_lock(&sst_drv_ctx->sst_lock);
 	sst_drv_ctx->sst_state = SST_FW_LOADED;
@@ -325,7 +328,7 @@
 	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 	spin_unlock(&sst_drv_ctx->list_spin_lock);
 	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	pr_debug("sst: Waiting for FW response Download complete\n");
+	pr_debug("Waiting for FW response Download complete\n");
 	sst_drv_ctx->alloc_block[i].ops_block.condition = false;
 	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]);
 	if (retval) {
@@ -337,7 +340,7 @@
 		return -EIO;
 	}
 
-	pr_debug("sst: FW sucess on Download complete\n");
+	pr_debug("FW success on Download complete\n");
 	sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
 	mutex_lock(&sst_drv_ctx->sst_lock);
 	sst_drv_ctx->sst_state = SST_FW_RUNNING;
@@ -360,14 +363,14 @@
 
 	header = (struct fw_header *)fw_lib->data;
 	if (header->modules != 1) {
-		pr_err("sst: Module no mismatch found\n ");
+		pr_err("Module no mismatch found\n");
 		err = -EINVAL;
 		goto exit;
 	}
 	module = (void *)fw_lib->data + sizeof(*header);
 	*entry_point = module->entry_point;
-	pr_debug("sst: Module entry point 0x%x\n", *entry_point);
-	pr_debug("sst: Module Sign %s, Size 0x%x, Blocks 0x%x Type 0x%x\n",
+	pr_debug("Module entry point 0x%x\n", *entry_point);
+	pr_debug("Module Sign %s, Size 0x%x, Blocks 0x%x Type 0x%x\n",
 			module->signature, module->mod_size,
 			module->blocks, module->type);
 
@@ -381,20 +384,20 @@
 			dsize += block->size;
 			break;
 		default:
-			pr_err("sst: Invalid block type for 0x%x\n", n_blk);
+			pr_err("Invalid block type for 0x%x\n", n_blk);
 			err = -EINVAL;
 			goto exit;
 		}
 		block = (void *)block + sizeof(*block) + block->size;
 	}
 	if (isize > slot->iram_size || dsize > slot->dram_size) {
-		pr_err("sst: library exceeds size allocated\n");
+		pr_err("library exceeds size allocated\n");
 		err = -EINVAL;
 		goto exit;
 	} else
-		pr_debug("sst: Library is safe for download...\n");
+		pr_debug("Library is safe for download...\n");
 
-	pr_debug("sst: iram 0x%x, dram 0x%x, iram 0x%x, dram 0x%x\n",
+	pr_debug("iram 0x%x, dram 0x%x, iram 0x%x, dram 0x%x\n",
 			isize, dsize, slot->iram_size, slot->dram_size);
 exit:
 	return err;
@@ -414,15 +417,15 @@
 
 	memset(buf, 0, sizeof(buf));
 
-	pr_debug("sst: Lib Type 0x%x, Slot 0x%x, ops 0x%x\n",
+	pr_debug("Lib Type 0x%x, Slot 0x%x, ops 0x%x\n",
 			lib->lib_info.lib_type, lib->slot_info.slot_num, ops);
-	pr_debug("sst: Version 0x%x, name %s, caps 0x%x media type 0x%x\n",
+	pr_debug("Version 0x%x, name %s, caps 0x%x media type 0x%x\n",
 		lib->lib_info.lib_version, lib->lib_info.lib_name,
 		lib->lib_info.lib_caps, lib->lib_info.media_type);
 
-	pr_debug("sst: IRAM Size 0x%x, offset 0x%x\n",
+	pr_debug("IRAM Size 0x%x, offset 0x%x\n",
 		lib->slot_info.iram_size, lib->slot_info.iram_offset);
-	pr_debug("sst: DRAM Size 0x%x, offset 0x%x\n",
+	pr_debug("DRAM Size 0x%x, offset 0x%x\n",
 		lib->slot_info.dram_size, lib->slot_info.dram_offset);
 
 	switch (lib->lib_info.lib_type) {
@@ -442,7 +445,7 @@
 		type = "wma9_";
 		break;
 	default:
-		pr_err("sst: Invalid codec type\n");
+		pr_err("Invalid codec type\n");
 		error = -EINVAL;
 		goto wake;
 	}
@@ -458,11 +461,11 @@
 			lib->slot_info.slot_num);
 	len += snprintf(buf + len, sizeof(buf) - len, ".bin");
 
-	pr_debug("sst: Requesting %s\n", buf);
+	pr_debug("Requesting %s\n", buf);
 
 	error = request_firmware(&fw_lib, buf, &sst_drv_ctx->pci->dev);
 	if (error) {
-		pr_err("sst: library load failed %d\n", error);
+		pr_err("library load failed %d\n", error);
 		goto wake;
 	}
 	error = sst_validate_library(fw_lib, &lib->slot_info, &entry_point);
@@ -476,7 +479,7 @@
 		goto wake_free;
 
 	/* lib is downloaded and init send alloc again */
-	pr_debug("sst: Library is downloaded now...\n");
+	pr_debug("Library is downloaded now...\n");
 wake_free:
 	/* sst_wake_up_alloc_block(sst_drv_ctx, pvt_id, error, NULL); */
 	release_firmware(fw_lib);
diff --git a/drivers/staging/intel_sst/intel_sst_ipc.c b/drivers/staging/intel_sst/intel_sst_ipc.c
index 39c67fa..993c533 100644
--- a/drivers/staging/intel_sst/intel_sst_ipc.c
+++ b/drivers/staging/intel_sst/intel_sst_ipc.c
@@ -26,6 +26,8 @@
  *  This file defines all ipc functions
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/firmware.h>
 #include <linux/sched.h>
@@ -75,16 +77,16 @@
 	/*To check if LPE is in stalled state.*/
 	retval = sst_stalled();
 	if (retval < 0) {
-		pr_err("sst: in stalled state\n");
+		pr_err("in stalled state\n");
 		return;
 	}
-	pr_debug("sst: post message called\n");
+	pr_debug("post message called\n");
 	spin_lock(&sst_drv_ctx->list_spin_lock);
 
 	/* check list */
 	if (list_empty(&sst_drv_ctx->ipc_dispatch_list)) {
 		/* list is empty, mask imr */
-		pr_debug("sst: Empty msg queue... masking\n");
+		pr_debug("Empty msg queue... masking\n");
 		imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
 		imr.part.done_interrupt = 1;
 		/* dummy register for shim workaround */
@@ -97,7 +99,7 @@
 	header.full = sst_shim_read(sst_drv_ctx->shim, SST_IPCX);
 	if (header.part.busy) {
 		/* busy, unmask */
-		pr_debug("sst: Busy not free... unmasking\n");
+		pr_debug("Busy not free... unmasking\n");
 		imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
 		imr.part.done_interrupt = 0;
 		/* dummy register for shim workaround */
@@ -109,8 +111,8 @@
 	msg = list_entry(sst_drv_ctx->ipc_dispatch_list.next,
 			struct ipc_post, node);
 	list_del(&msg->node);
-	pr_debug("sst: Post message: header = %x\n", msg->header.full);
-	pr_debug("sst: size: = %x\n", msg->header.part.data);
+	pr_debug("Post message: header = %x\n", msg->header.full);
+	pr_debug("size: = %x\n", msg->header.part.data);
 	if (msg->header.part.large)
 		memcpy_toio(sst_drv_ctx->mailbox + SST_MAILBOX_SEND,
 			msg->mailbox_data, msg->header.part.data);
@@ -166,13 +168,13 @@
 		(struct ipc_header_fw_init *)msg->mailbox;
 	int retval = 0;
 
-	pr_debug("sst: *** FW Init msg came***\n");
+	pr_debug("*** FW Init msg came***\n");
 	if (init->result) {
 		mutex_lock(&sst_drv_ctx->sst_lock);
 		sst_drv_ctx->sst_state = SST_ERROR;
 		mutex_unlock(&sst_drv_ctx->sst_lock);
-		pr_debug("sst: FW Init failed, Error %x\n", init->result);
-		pr_err("sst: FW Init failed, Error %x\n", init->result);
+		pr_debug("FW Init failed, Error %x\n", init->result);
+		pr_err("FW Init failed, Error %x\n", init->result);
 		retval = -init->result;
 		return retval;
 	}
@@ -181,11 +183,11 @@
 	mutex_lock(&sst_drv_ctx->sst_lock);
 	sst_drv_ctx->sst_state = SST_FW_RUNNING;
 	mutex_unlock(&sst_drv_ctx->sst_lock);
-	pr_debug("sst: FW Version %x.%x\n",
+	pr_debug("FW Version %x.%x\n",
 			init->fw_version.major, init->fw_version.minor);
-	pr_debug("sst: Build No %x Type %x\n",
+	pr_debug("Build No %x Type %x\n",
 			init->fw_version.build, init->fw_version.type);
-	pr_debug("sst:  Build date %s Time %s\n",
+	pr_debug(" Build date %s Time %s\n",
 			init->build_info.date, init->build_info.time);
 	sst_wake_up_alloc_block(sst_drv_ctx, FW_DWNL_ID, retval, NULL);
 	return retval;
@@ -204,19 +206,19 @@
 			container_of(work, struct sst_ipc_msg_wq, wq);
 	int str_id = msg->header.part.str_id;
 
-	pr_debug("sst: IPC process for %x\n", msg->header.full);
+	pr_debug("IPC process for %x\n", msg->header.full);
 
 	/* based on msg in list call respective handler */
 	switch (msg->header.part.msg_id) {
 	case IPC_SST_BUF_UNDER_RUN:
 	case IPC_SST_BUF_OVER_RUN:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst:  stream id %d invalid\n", str_id);
+			pr_err("stream id %d invalid\n", str_id);
 			break;
 		}
-		pr_err("sst: Buffer under/overrun for%d\n",
+		pr_err("Buffer under/overrun for %d\n",
 				msg->header.part.str_id);
-		pr_err("sst: Got Underrun & not to send data...ignore\n");
+		pr_err("Got Underrun & not to send data...ignore\n");
 		break;
 
 	case IPC_SST_GET_PLAY_FRAMES:
@@ -224,35 +226,35 @@
 			struct stream_info *stream ;
 
 			if (sst_validate_strid(str_id)) {
-				pr_err("sst: strid %d invalid\n", str_id);
+				pr_err("strid %d invalid\n", str_id);
 				break;
 			}
 			/* call sst_play_frame */
 			stream = &sst_drv_ctx->streams[str_id];
-			pr_debug("sst: sst_play_frames for %d\n",
+			pr_debug("sst_play_frames for %d\n",
 					msg->header.part.str_id);
 			mutex_lock(&sst_drv_ctx->streams[str_id].lock);
 			sst_play_frame(msg->header.part.str_id);
 			mutex_unlock(&sst_drv_ctx->streams[str_id].lock);
 			break;
 		} else
-			pr_err("sst: sst_play_frames for Penwell!!\n");
+			pr_err("sst_play_frames for Penwell!!\n");
 
 	case IPC_SST_GET_CAPT_FRAMES:
 		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
 			struct stream_info *stream;
 			/* call sst_capture_frame */
 			if (sst_validate_strid(str_id)) {
-				pr_err("sst: str id %d invalid\n", str_id);
+				pr_err("str id %d invalid\n", str_id);
 				break;
 			}
 			stream = &sst_drv_ctx->streams[str_id];
-			pr_debug("sst: sst_capture_frames for %d\n",
+			pr_debug("sst_capture_frames for %d\n",
 					msg->header.part.str_id);
 			mutex_lock(&stream->lock);
 			if (stream->mmapped == false &&
 					stream->src == SST_DRV) {
-				pr_debug("sst: waking up block for copy.\n");
+				pr_debug("waking up block for copy.\n");
 				stream->data_blk.ret_code = 0;
 				stream->data_blk.condition = true;
 				stream->data_blk.on = false;
@@ -261,11 +263,11 @@
 				sst_capture_frame(msg->header.part.str_id);
 			mutex_unlock(&stream->lock);
 		} else
-			pr_err("sst: sst_play_frames for Penwell!!\n");
+			pr_err("sst_play_frames for Penwell!!\n");
 		break;
 
 	case IPC_IA_PRINT_STRING:
-		pr_debug("sst: been asked to print something by fw\n");
+		pr_debug("been asked to print something by fw\n");
 		/* TBD */
 		break;
 
@@ -277,12 +279,12 @@
 
 	case IPC_SST_STREAM_PROCESS_FATAL_ERR:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst: stream id %d invalid\n", str_id);
+			pr_err("stream id %d invalid\n", str_id);
 			break;
 		}
-		pr_err("sst: codec fatal error %x stream %d...\n",
+		pr_err("codec fatal error %x stream %d...\n",
 				msg->header.full, msg->header.part.str_id);
-		pr_err("sst: Dropping the stream\n");
+		pr_err("Dropping the stream\n");
 		sst_drop_stream(msg->header.part.str_id);
 		break;
 	case IPC_IA_LPE_GETTING_STALLED:
@@ -293,7 +295,7 @@
 		break;
 	default:
 		/* Illegal case */
-		pr_err("sst: Unhandled msg %x header %x\n",
+		pr_err("Unhandled msg %x header %x\n",
 		msg->header.part.msg_id, msg->header.full);
 	}
 	sst_clear_interrupt();
@@ -322,7 +324,7 @@
 		if (!msg->header.part.data) {
 			sst_drv_ctx->tgt_dev_blk.ret_code = 0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 			msg->header.part.msg_id, msg->header.part.data);
 			sst_drv_ctx->tgt_dev_blk.ret_code =
 					-msg->header.part.data;
@@ -340,7 +342,7 @@
 			int major = fw_info->fw_version.major;
 			int minor = fw_info->fw_version.minor;
 			int build = fw_info->fw_version.build;
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Msg succeeded %x\n",
 				       msg->header.part.msg_id);
 			pr_debug("INFO: ***FW*** = %02d.%02d.%02d\n",
 					major, minor, build);
@@ -349,13 +351,13 @@
 				sizeof(struct snd_sst_fw_info));
 			sst_drv_ctx->fw_info_blk.ret_code = 0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 			msg->header.part.msg_id, msg->header.part.data);
 			sst_drv_ctx->fw_info_blk.ret_code =
 					-msg->header.part.data;
 		}
 		if (sst_drv_ctx->fw_info_blk.on == true) {
-			pr_debug("sst: Memcopy succedded\n");
+			pr_debug("Memcopy succeeded\n");
 			sst_drv_ctx->fw_info_blk.on = false;
 			sst_drv_ctx->fw_info_blk.condition = true;
 			wake_up(&sst_drv_ctx->wait_queue);
@@ -364,11 +366,11 @@
 	}
 	case IPC_IA_SET_STREAM_MUTE:
 		if (!msg->header.part.data) {
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Msg succeeded %x\n",
 				       msg->header.part.msg_id);
 			sst_drv_ctx->mute_info_blk.ret_code = 0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 			msg->header.part.msg_id, msg->header.part.data);
 			sst_drv_ctx->mute_info_blk.ret_code =
 					-msg->header.part.data;
@@ -382,11 +384,11 @@
 		break;
 	case IPC_IA_SET_STREAM_VOL:
 		if (!msg->header.part.data) {
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Msg succeeded %x\n",
 				       msg->header.part.msg_id);
 			sst_drv_ctx->vol_info_blk.ret_code = 0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 					msg->header.part.msg_id,
 			msg->header.part.data);
 			sst_drv_ctx->vol_info_blk.ret_code =
@@ -402,15 +404,15 @@
 		break;
 	case IPC_IA_GET_STREAM_VOL:
 		if (msg->header.part.large) {
-			pr_debug("sst: Large Msg Received Successfully\n");
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Large Msg Received Successfully\n");
+			pr_debug("Msg succeeded %x\n",
 				       msg->header.part.msg_id);
 			memcpy_fromio(sst_drv_ctx->vol_info_blk.data,
 				(void *) msg->mailbox,
 				sizeof(struct snd_sst_vol));
 			sst_drv_ctx->vol_info_blk.ret_code = 0;
 		} else {
-			pr_err("sst: Msg %x reply error %x\n",
+			pr_err("Msg %x reply error %x\n",
 			msg->header.part.msg_id, msg->header.part.data);
 			sst_drv_ctx->vol_info_blk.ret_code =
 					-msg->header.part.data;
@@ -424,18 +426,18 @@
 
 	case IPC_IA_GET_STREAM_PARAMS:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst: stream id %d invalid\n", str_id);
+			pr_err("stream id %d invalid\n", str_id);
 			break;
 		}
 		str_info = &sst_drv_ctx->streams[str_id];
 		if (msg->header.part.large) {
-			pr_debug("sst: Get stream large success\n");
+			pr_debug("Get stream large success\n");
 			memcpy_fromio(str_info->ctrl_blk.data,
 				((void *)(msg->mailbox)),
 				sizeof(struct snd_sst_fw_get_stream_params));
 			str_info->ctrl_blk.ret_code = 0;
 		} else {
-			pr_err("sst: Msg %x reply error %x\n",
+			pr_err("Msg %x reply error %x\n",
 				msg->header.part.msg_id, msg->header.part.data);
 			str_info->ctrl_blk.ret_code = -msg->header.part.data;
 		}
@@ -447,19 +449,19 @@
 		break;
 	case IPC_IA_DECODE_FRAMES:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst: stream id %d invalid\n", str_id);
+			pr_err("stream id %d invalid\n", str_id);
 			break;
 		}
 		str_info = &sst_drv_ctx->streams[str_id];
 		if (msg->header.part.large) {
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Msg succeeded %x\n",
 				       msg->header.part.msg_id);
 			memcpy_fromio(str_info->data_blk.data,
 					((void *)(msg->mailbox)),
 					sizeof(struct snd_sst_decode_info));
 			str_info->data_blk.ret_code = 0;
 		} else {
-			pr_err("sst: Msg %x reply error %x\n",
+			pr_err("Msg %x reply error %x\n",
 				msg->header.part.msg_id, msg->header.part.data);
 			str_info->data_blk.ret_code = -msg->header.part.data;
 		}
@@ -471,17 +473,17 @@
 		break;
 	case IPC_IA_DRAIN_STREAM:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst: stream id %d invalid\n", str_id);
+			pr_err("stream id %d invalid\n", str_id);
 			break;
 		}
 		str_info = &sst_drv_ctx->streams[str_id];
 		if (!msg->header.part.data) {
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Msg succeeded %x\n",
 					msg->header.part.msg_id);
 			str_info->ctrl_blk.ret_code = 0;
 
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 				msg->header.part.msg_id, msg->header.part.data);
 			str_info->ctrl_blk.ret_code = -msg->header.part.data;
 
@@ -496,7 +498,7 @@
 
 	case IPC_IA_DROP_STREAM:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst: str id %d invalid\n", str_id);
+			pr_err("str id %d invalid\n", str_id);
 			break;
 		}
 		str_info = &sst_drv_ctx->streams[str_id];
@@ -504,12 +506,12 @@
 			struct snd_sst_drop_response *drop_resp =
 				(struct snd_sst_drop_response *)msg->mailbox;
 
-			pr_debug("sst: Drop ret bytes %x\n", drop_resp->bytes);
+			pr_debug("Drop ret bytes %x\n", drop_resp->bytes);
 
 			str_info->curr_bytes = drop_resp->bytes;
 			str_info->ctrl_blk.ret_code =  0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 				msg->header.part.msg_id, msg->header.part.data);
 			str_info->ctrl_blk.ret_code = -msg->header.part.data;
 		}
@@ -521,10 +523,10 @@
 		break;
 	case IPC_IA_ENABLE_RX_TIME_SLOT:
 		if (!msg->header.part.data) {
-			pr_debug("sst: RX_TIME_SLOT success\n");
+			pr_debug("RX_TIME_SLOT success\n");
 			sst_drv_ctx->hs_info_blk.ret_code = 0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 				msg->header.part.msg_id,
 				msg->header.part.data);
 			sst_drv_ctx->hs_info_blk.ret_code =
@@ -541,17 +543,17 @@
 	case IPC_IA_SET_STREAM_PARAMS:
 		str_info = &sst_drv_ctx->streams[str_id];
 		if (!msg->header.part.data) {
-			pr_debug("sst: Msg succedded %x\n",
+			pr_debug("Msg succeeded %x\n",
 					msg->header.part.msg_id);
 			str_info->ctrl_blk.ret_code = 0;
 		} else {
-			pr_err("sst:  Msg %x reply error %x\n",
+			pr_err(" Msg %x reply error %x\n",
 					msg->header.part.msg_id,
 					msg->header.part.data);
 			str_info->ctrl_blk.ret_code = -msg->header.part.data;
 		}
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst:  stream id %d invalid\n", str_id);
+			pr_err(" stream id %d invalid\n", str_id);
 			break;
 		}
 
@@ -564,9 +566,9 @@
 
 	case IPC_IA_FREE_STREAM:
 		if (!msg->header.part.data) {
-			pr_debug("sst: Stream %d freed\n", str_id);
+			pr_debug("Stream %d freed\n", str_id);
 		} else {
-			pr_err("sst: Free for %d ret error %x\n",
+			pr_err("Free for %d ret error %x\n",
 				       str_id, msg->header.part.data);
 		}
 		break;
@@ -575,7 +577,7 @@
 		struct snd_sst_alloc_response *resp =
 				(struct snd_sst_alloc_response *)msg->mailbox;
 		if (resp->str_type.result)
-			pr_err("sst: error alloc stream = %x\n",
+			pr_err("error alloc stream = %x\n",
 				       resp->str_type.result);
 		sst_alloc_stream_response(str_id, resp);
 		break;
@@ -584,21 +586,21 @@
 	case IPC_IA_PLAY_FRAMES:
 	case IPC_IA_CAPT_FRAMES:
 		if (sst_validate_strid(str_id)) {
-			pr_err("sst: stream id %d invalid\n" , str_id);
+			pr_err("stream id %d invalid\n", str_id);
 			break;
 		}
-		pr_debug("sst: Ack for play/capt frames recived\n");
+		pr_debug("Ack for play/capt frames received\n");
 		break;
 
 	case IPC_IA_PREP_LIB_DNLD: {
 		struct snd_sst_str_type *str_type =
 			(struct snd_sst_str_type *)msg->mailbox;
-		pr_debug("sst: Prep Lib download %x\n",
+		pr_debug("Prep Lib download %x\n",
 				msg->header.part.msg_id);
 		if (str_type->result)
-			pr_err("sst: Prep lib download %x\n", str_type->result);
+			pr_err("Prep lib download %x\n", str_type->result);
 		else
-			pr_debug("sst: Can download codec now...\n");
+			pr_debug("Can download codec now...\n");
 		sst_wake_up_alloc_block(sst_drv_ctx, str_id,
 				str_type->result, NULL);
 		break;
@@ -609,12 +611,12 @@
 			(struct snd_sst_lib_download_info *)msg->mailbox;
 		int retval = resp->result;
 
-		pr_debug("sst: Lib downloaded %x\n", msg->header.part.msg_id);
+		pr_debug("Lib downloaded %x\n", msg->header.part.msg_id);
 		if (resp->result) {
-			pr_err("sst: err in lib dload %x\n", resp->result);
+			pr_err("err in lib dload %x\n", resp->result);
 		} else {
-			pr_debug("sst: Codec download complete...\n");
-			pr_debug("sst: codec Type %d Ver %d Built %s: %s\n",
+			pr_debug("Codec download complete...\n");
+			pr_debug("codec Type %d Ver %d Built %s: %s\n",
 				resp->dload_lib.lib_info.lib_type,
 				resp->dload_lib.lib_info.lib_version,
 				resp->dload_lib.lib_info.b_date,
@@ -639,17 +641,17 @@
 	case IPC_IA_GET_FW_BUILD_INF: {
 		struct sst_fw_build_info *build =
 			(struct sst_fw_build_info *)msg->mailbox;
-		pr_debug("sst: Build date:%sTime:%s", build->date, build->time);
+		pr_debug("Build date:%sTime:%s", build->date, build->time);
 		break;
 	}
 	case IPC_IA_SET_PMIC_TYPE:
 		break;
 	case IPC_IA_START_STREAM:
-		pr_debug("sst: reply for START STREAM %x\n", msg->header.full);
+		pr_debug("reply for START STREAM %x\n", msg->header.full);
 		break;
 	default:
 		/* Illegal case */
-		pr_err("sst: process reply:default = %x\n", msg->header.full);
+		pr_err("process reply:default = %x\n", msg->header.full);
 	}
 	sst_clear_interrupt();
 	return;
diff --git a/drivers/staging/intel_sst/intel_sst_pvt.c b/drivers/staging/intel_sst/intel_sst_pvt.c
index 6487e19..01f8c3b 100644
--- a/drivers/staging/intel_sst/intel_sst_pvt.c
+++ b/drivers/staging/intel_sst/intel_sst_pvt.c
@@ -29,6 +29,8 @@
  *  This file contains all private functions
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/firmware.h>
@@ -60,7 +62,7 @@
 		}
 	}
 	if (i == MAX_ACTIVE_STREAM) {
-		pr_err("sst: max alloc_stream reached");
+		pr_err("max alloc_stream reached\n");
 		i = -EBUSY; /* active stream limit reached */
 	}
 	return i;
@@ -84,14 +86,14 @@
 				block->condition)) {
 		/* event wake */
 		if (block->ret_code < 0) {
-			pr_err("sst: stream failed %d\n", block->ret_code);
+			pr_err("stream failed %d\n", block->ret_code);
 			retval = -EBUSY;
 		} else {
-			pr_debug("sst: event up\n");
+			pr_debug("event up\n");
 			retval = 0;
 		}
 	} else {
-		pr_err("sst: signal interrupted\n");
+		pr_err("signal interrupted\n");
 		retval = -EINTR;
 	}
 	return retval;
@@ -115,18 +117,18 @@
 {
 	int retval = 0;
 
-	pr_debug("sst: sst_wait_interruptible_timeout - waiting....\n");
+	pr_debug("sst_wait_interruptible_timeout - waiting....\n");
 	if (wait_event_interruptible_timeout(sst_drv_ctx->wait_queue,
 						block->condition,
 						msecs_to_jiffies(timeout))) {
 		if (block->ret_code < 0)
-			pr_err("sst: stream failed %d\n", block->ret_code);
+			pr_err("stream failed %d\n", block->ret_code);
 		else
-			pr_debug("sst: event up\n");
+			pr_debug("event up\n");
 		retval = block->ret_code;
 	} else {
 		block->on = false;
-		pr_err("sst: timeout occured...\n");
+		pr_err("timeout occurred...\n");
 		/*setting firmware state as uninit so that the
 		firmware will get re-downloaded on next request
 		this is because firmare not responding for 5 sec
@@ -156,18 +158,18 @@
 	/* NOTE:
 	Observed that FW processes the alloc msg and replies even
 	before the alloc thread has finished execution */
-	pr_debug("sst: waiting for %x, condition %x\n",
+	pr_debug("waiting for %x, condition %x\n",
 		       block->sst_id, block->ops_block.condition);
 	if (wait_event_interruptible_timeout(sst_drv_ctx->wait_queue,
 				block->ops_block.condition,
 				msecs_to_jiffies(SST_BLOCK_TIMEOUT))) {
 		/* event wake */
-		pr_debug("sst: Event wake %x\n", block->ops_block.condition);
-		pr_debug("sst: message ret: %d\n", block->ops_block.ret_code);
+		pr_debug("Event wake %x\n", block->ops_block.condition);
+		pr_debug("message ret: %d\n", block->ops_block.ret_code);
 		retval = block->ops_block.ret_code;
 	} else {
 		block->ops_block.on = false;
-		pr_err("sst: Wait timed-out %x\n", block->ops_block.condition);
+		pr_err("Wait timed-out %x\n", block->ops_block.condition);
 		/* settign firmware state as uninit so that the
 		firmware will get redownloaded on next request
 		this is because firmare not responding for 5 sec
@@ -192,14 +194,14 @@
 
 	msg = kzalloc(sizeof(struct ipc_post), GFP_ATOMIC);
 	if (!msg) {
-		pr_err("sst: kzalloc msg failed\n");
+		pr_err("kzalloc msg failed\n");
 		return -ENOMEM;
 	}
 
 	msg->mailbox_data = kzalloc(SST_MAILBOX_SIZE, GFP_ATOMIC);
 	if (!msg->mailbox_data) {
 		kfree(msg);
-		pr_err("sst: kzalloc mailbox_data failed");
+		pr_err("kzalloc mailbox_data failed");
 		return -ENOMEM;
 	};
 	*arg = msg;
@@ -219,7 +221,7 @@
 
 	msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
 	if (!msg) {
-		pr_err("sst: kzalloc msg failed\n");
+		pr_err("kzalloc msg failed\n");
 		return -ENOMEM;
 	}
 	msg->mailbox_data = NULL;
@@ -290,10 +292,10 @@
 	struct ipc_post *msg = NULL;
 
 	if (sst_create_short_msg(&msg)) {
-		pr_err("sst: mem allocation failed\n");
+		pr_err("mem allocation failed\n");
 			return -ENOMEM;
 	}
-	pr_debug("sst: ipc message sending: ENABLE_RX_TIME_SLOT\n");
+	pr_debug("ipc message sending: ENABLE_RX_TIME_SLOT\n");
 	sst_fill_header(&msg->header, IPC_IA_ENABLE_RX_TIME_SLOT, 0, 0);
 	msg->header.part.data = status;
 	sst_drv_ctx->hs_info_blk.condition = false;
diff --git a/drivers/staging/intel_sst/intel_sst_stream.c b/drivers/staging/intel_sst/intel_sst_stream.c
index b2c4b70..8f6e100 100644
--- a/drivers/staging/intel_sst/intel_sst_stream.c
+++ b/drivers/staging/intel_sst/intel_sst_stream.c
@@ -26,6 +26,8 @@
  *  This file contains the stream operations of SST driver
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/firmware.h>
 #include <linux/sched.h>
@@ -46,7 +48,7 @@
 int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot)
 {
 	if (device >= MAX_NUM_STREAMS) {
-		pr_debug("sst: device type invalid %d\n", device);
+		pr_debug("device type invalid %d\n", device);
 		return -EINVAL;
 	}
 	if (sst_drv_ctx->streams[device].status == STREAM_UN_INIT) {
@@ -71,15 +73,15 @@
 		else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 4)
 			*pcm_slot = 0x0F;
 		else {
-			pr_debug("sst: No condition satisfied.. ret err\n");
+			pr_debug("No condition satisfied.. ret err\n");
 			return -EINVAL;
 		}
 	} else {
-		pr_debug("sst: this stream state is not uni-init, is %d\n",
+		pr_debug("this stream state is not uni-init, is %d\n",
 				sst_drv_ctx->streams[device].status);
 		return -EBADRQC;
 	}
-	pr_debug("sst: returning slot %x\n", *pcm_slot);
+	pr_debug("returning slot %x\n", *pcm_slot);
 	return 0;
 }
 /**
@@ -96,7 +98,7 @@
 		if (sst_drv_ctx->streams[i].status == STREAM_UN_INIT)
 			return i;
 	}
-	pr_debug("sst: Didnt find empty stream for mrst\n");
+	pr_debug("Didnt find empty stream for mrst\n");
 	return -EBUSY;
 }
 
@@ -305,7 +307,7 @@
 		if (str_info->prev == STREAM_UN_INIT)
 			return -EBADRQC;
 		if (str_info->ctrl_blk.on == true) {
-			pr_err("SST ERR: control path is in use\n ");
+			pr_err("SST ERR: control path is in use\n");
 			return -EINVAL;
 		}
 		if (sst_create_short_msg(&msg))
@@ -333,7 +335,7 @@
 		}
 	} else {
 		retval = -EBADRQC;
-		pr_err("SST ERR:BADQRC for stream\n ");
+		pr_err("SST ERR: BADQRC for stream\n");
 	}
 
 	return retval;
@@ -468,7 +470,7 @@
 		}
 	} else {
 		retval = -EBADRQC;
-		pr_err("SST ERR:BADQRC for stream\n");
+		pr_err("SST ERR: BADQRC for stream\n");
 	}
 	return retval;
 }
diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
index fbae39f..d4e94f1 100644
--- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c
+++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
@@ -26,6 +26,8 @@
  *  This file contains the stream operations of SST driver
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/syscalls.h>
 #include <linux/firmware.h>
@@ -53,7 +55,7 @@
 	struct stream_info *str_info;
 	struct snd_sst_fw_get_stream_params *fw_params;
 
-	pr_debug("sst: get_stream for %d\n", str_id);
+	pr_debug("get_stream for %d\n", str_id);
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return retval;
@@ -61,16 +63,16 @@
 	str_info = &sst_drv_ctx->streams[str_id];
 	if (str_info->status != STREAM_UN_INIT) {
 		if (str_info->ctrl_blk.on == true) {
-			pr_err("sst: control path in use\n");
+			pr_err("control path in use\n");
 			return -EINVAL;
 		}
 		if (sst_create_short_msg(&msg)) {
-			pr_err("sst: message creation failed\n");
+			pr_err("message creation failed\n");
 			return -ENOMEM;
 		}
 		fw_params = kzalloc(sizeof(*fw_params), GFP_ATOMIC);
 		if (!fw_params) {
-			pr_err("sst: mem allcoation failed\n ");
+			pr_err("mem allocation failed\n");
 			kfree(msg);
 			return -ENOMEM;
 		}
@@ -104,7 +106,7 @@
 		get_params->codec_params.stream_type = str_info->str_type;
 		kfree(fw_params);
 	} else {
-		pr_debug("sst: Stream is not in the init state\n");
+		pr_debug("Stream is not in the init state\n");
 	}
 	return retval;
 }
@@ -125,17 +127,17 @@
 
 	BUG_ON(!str_param);
 	if (sst_drv_ctx->streams[str_id].ops != str_param->ops) {
-		pr_err("sst: Invalid operation\n");
+		pr_err("Invalid operation\n");
 		return -EINVAL;
 	}
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return retval;
-	pr_debug("sst: set_stream for %d\n", str_id);
+	pr_debug("set_stream for %d\n", str_id);
 	str_info =  &sst_drv_ctx->streams[str_id];
 	if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) {
 		if (str_info->ctrl_blk.on == true) {
-			pr_err("sst: control path in use\n");
+			pr_err("control path in use\n");
 			return -EAGAIN;
 		}
 		if (sst_create_large_msg(&msg))
@@ -163,7 +165,7 @@
 		}
 	} else {
 		retval = -EBADRQC;
-		pr_err("sst: BADQRC for stream\n");
+		pr_err("BADQRC for stream\n");
 	}
 	return retval;
 }
@@ -183,7 +185,7 @@
 	struct snd_sst_vol *fw_get_vol;
 	int str_id = get_vol->stream_id;
 
-	pr_debug("sst: get vol called\n");
+	pr_debug("get vol called\n");
 
 	if (sst_create_short_msg(&msg))
 		return -ENOMEM;
@@ -195,7 +197,7 @@
 	sst_drv_ctx->vol_info_blk.on = true;
 	fw_get_vol = kzalloc(sizeof(*fw_get_vol), GFP_ATOMIC);
 	if (!fw_get_vol) {
-		pr_err("sst: mem allocation failed\n");
+		pr_err("mem allocation failed\n");
 		kfree(msg);
 		return -ENOMEM;
 	}
@@ -209,10 +211,10 @@
 	if (retval)
 		retval = -EIO;
 	else {
-		pr_debug("sst: stream id %d\n", fw_get_vol->stream_id);
-		pr_debug("sst: volume %d\n", fw_get_vol->volume);
-		pr_debug("sst: ramp duration %d\n", fw_get_vol->ramp_duration);
-		pr_debug("sst: ramp_type %d\n", fw_get_vol->ramp_type);
+		pr_debug("stream id %d\n", fw_get_vol->stream_id);
+		pr_debug("volume %d\n", fw_get_vol->volume);
+		pr_debug("ramp duration %d\n", fw_get_vol->ramp_duration);
+		pr_debug("ramp_type %d\n", fw_get_vol->ramp_type);
 		memcpy(get_vol, fw_get_vol, sizeof(*fw_get_vol));
 	}
 	return retval;
@@ -231,10 +233,10 @@
 	int retval = 0;
 	struct ipc_post *msg = NULL;
 
-	pr_debug("sst: set vol called\n");
+	pr_debug("set vol called\n");
 
 	if (sst_create_large_msg(&msg)) {
-		pr_err("sst: message creation failed\n");
+		pr_err("message creation failed\n");
 		return -ENOMEM;
 	}
 	sst_fill_header(&msg->header, IPC_IA_SET_STREAM_VOL, 1,
@@ -254,7 +256,7 @@
 	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 			&sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
 	if (retval) {
-		pr_err("sst: error in set_vol = %d\n", retval);
+		pr_err("error in set_vol = %d\n", retval);
 		retval = -EIO;
 	}
 	return retval;
@@ -273,10 +275,10 @@
 	int retval = 0;
 	struct ipc_post *msg = NULL;
 
-	pr_debug("sst: set mute called\n");
+	pr_debug("set mute called\n");
 
 	if (sst_create_large_msg(&msg)) {
-		pr_err("sst: message creation failed\n");
+		pr_err("message creation failed\n");
 		return -ENOMEM;
 	}
 	sst_fill_header(&msg->header, IPC_IA_SET_STREAM_MUTE, 1,
@@ -297,7 +299,7 @@
 	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 			&sst_drv_ctx->mute_info_blk, SST_BLOCK_TIMEOUT);
 	if (retval) {
-		pr_err("sst: error in set_mute = %d\n", retval);
+		pr_err("error in set_mute = %d\n", retval);
 		retval = -EIO;
 	}
 	return retval;
@@ -358,20 +360,20 @@
 		slot->device_type == SND_SST_DEVICE_PCM) {
 			retval = sst_activate_target(slot);
 			if (retval)
-				pr_err("sst: SST_Activate_target_fail\n");
+				pr_err("SST_Activate_target_fail\n");
 			else
-				pr_err("sst: SST_Activate_target_pass\n");
+				pr_err("SST_Activate_target_pass\n");
 		return retval;
 	} else if (slot->action == SND_SST_PORT_PREPARE &&
 			slot->device_type == SND_SST_DEVICE_PCM) {
 				retval = sst_prepare_target(slot);
 			if (retval)
-				pr_err("sst: SST_prepare_target_fail\n");
+				pr_err("SST_prepare_target_fail\n");
 			else
-				pr_err("sst: SST_prepare_target_pass\n");
+				pr_err("SST_prepare_target_pass\n");
 			return retval;
 	} else {
-		pr_err("sst: slot_action : %d, device_type: %d\n",
+		pr_err("slot_action : %d, device_type: %d\n",
 				slot->action, slot->device_type);
 		return retval;
 	}
@@ -383,7 +385,7 @@
 	struct ipc_post *msg;
 
 	if (sst_create_large_msg(&msg)) {
-		pr_err("sst: message creation failed\n");
+		pr_err("message creation failed\n");
 		return -ENOMEM;
 	}
 	sst_fill_header(&msg->header, IPC_IA_TARGET_DEV_SELECT, 1, 0);
@@ -399,11 +401,11 @@
 	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 	spin_unlock(&sst_drv_ctx->list_spin_lock);
 	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	pr_debug("sst: message sent- waiting\n");
+	pr_debug("message sent- waiting\n");
 	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 			&sst_drv_ctx->tgt_dev_blk, TARGET_DEV_BLOCK_TIMEOUT);
 	if (retval)
-		pr_err("sst: target device ipc failed = 0x%x\n", retval);
+		pr_err("target device ipc failed = 0x%x\n", retval);
 	return retval;
 
 }
@@ -439,7 +441,7 @@
 					goto err;
 			} else {
 err:
-				pr_err("sst: i/p params incorrect\n");
+				pr_err("i/p params incorrect\n");
 				return -EINVAL;
 			}
 		}
@@ -460,15 +462,15 @@
 {
 	int retval, i, prepare_count = 0;
 
-	pr_debug("sst: Target Device Select\n");
+	pr_debug("Target Device Select\n");
 
 	if (target->device_route < 0 || target->device_route > 2) {
-		pr_err("sst: device route is invalid\n");
+		pr_err("device route is invalid\n");
 		return -EINVAL;
 	}
 
 	if (target->device_route != 0) {
-		pr_err("sst: Unsupported config\n");
+		pr_err("Unsupported config\n");
 		return -EIO;
 	}
 	retval = sst_target_device_validate(target);
@@ -480,18 +482,18 @@
 		return retval;
 	for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
 		if (target->devices[i].action == SND_SST_PORT_ACTIVATE) {
-			pr_debug("sst: activate called in %d\n", i);
+			pr_debug("activate called in %d\n", i);
 			retval = sst_parse_target(&target->devices[i]);
 			if (retval)
 				return retval;
 		} else if (target->devices[i].action == SND_SST_PORT_PREPARE) {
-			pr_debug("sst: PREPARE in %d, Forwading\n", i);
+			pr_debug("PREPARE in %d, Forwarding\n", i);
 			retval = sst_parse_target(&target->devices[i]);
 			if (retval) {
-				pr_err("sst: Parse Target fail %d", retval);
+				pr_err("Parse Target fail %d\n", retval);
 				return retval;
 			}
-			pr_debug("sst: Parse Target successful %d", retval);
+			pr_debug("Parse Target successful %d\n", retval);
 			if (target->devices[i].device_type ==
 						SND_SST_DEVICE_PCM)
 				prepare_count++;
@@ -512,11 +514,11 @@
 	rar_status = rar_handle_to_bus(buffers, count);
 
 	if (count != rar_status) {
-		pr_err("sst: The rar CALL Failed");
+		pr_err("The rar CALL Failed");
 		retval = -EIO;
 	}
 	if (buffers->info.type != RAR_TYPE_AUDIO) {
-		pr_err("sst: Invalid RAR type\n");
+		pr_err("Invalid RAR type\n");
 		return -EINVAL;
 	}
 	return retval;
@@ -539,10 +541,10 @@
 		if (kbufs->in_use == false) {
 #ifdef CONFIG_MRST_RAR_HANDLER
 			if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
-				pr_debug("sst: DRM playback handling\n");
+				pr_debug("DRM playback handling\n");
 				rar_buffers.info.handle = (__u32)kbufs->addr;
 				rar_buffers.info.size = kbufs->size;
-				pr_debug("sst: rar handle 0x%x size=0x%x",
+				pr_debug("rar handle 0x%x size=0x%x\n",
 					rar_buffers.info.handle,
 					rar_buffers.info.size);
 				retval =  sst_get_RAR(&rar_buffers, 1);
@@ -552,7 +554,7 @@
 				sg_list->addr[i].addr = rar_buffers.bus_address;
 				/* rar_buffers.info.size; */
 				sg_list->addr[i].size = (__u32)kbufs->size;
-				pr_debug("sst: phyaddr[%d] 0x%x Size:0x%x\n"
+				pr_debug("phyaddr[%d] 0x%x Size:0x%x\n"
 					, i, sg_list->addr[i].addr,
 					sg_list->addr[i].size);
 			}
@@ -562,7 +564,7 @@
 					virt_to_phys((void *)
 						kbufs->addr + kbufs->offset);
 				sg_list->addr[i].size = kbufs->size;
-				pr_debug("sst: phyaddr[%d]:0x%x Size:0x%x\n"
+				pr_debug("phyaddr[%d]:0x%x Size:0x%x\n"
 				, i , sg_list->addr[i].addr, kbufs->size);
 			}
 			stream->curr_bytes += sg_list->addr[i].size;
@@ -574,7 +576,7 @@
 	}
 
 	sg_list->num_entries = i;
-	pr_debug("sst:sg list entries = %d\n", sg_list->num_entries);
+	pr_debug("sg list entries = %d\n", sg_list->num_entries);
 	return i;
 }
 
@@ -595,7 +597,7 @@
 	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
 	struct stream_info *stream;
 
-	pr_debug("sst: play frame for %d\n", str_id);
+	pr_debug("play frame for %d\n", str_id);
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return retval;
@@ -615,14 +617,14 @@
 	stream->curr_bytes = 0;
 	if (list_empty(&stream->bufs)) {
 		/* no user buffer available */
-		pr_debug("sst: Null buffer stream status %d\n", stream->status);
+		pr_debug("Null buffer stream status %d\n", stream->status);
 		stream->prev = stream->status;
 		stream->status = STREAM_INIT;
-		pr_debug("sst:new stream status = %d\n", stream->status);
+		pr_debug("new stream status = %d\n", stream->status);
 		if (stream->need_draining == true) {
-			pr_debug("sst:draining stream\n");
+			pr_debug("draining stream\n");
 			if (sst_create_short_msg(&msg)) {
-				pr_err("sst: mem alloc failed\n");
+				pr_err("mem allocation failed\n");
 				return -ENOMEM;
 			}
 			sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM,
@@ -633,7 +635,7 @@
 			spin_unlock(&sst_drv_ctx->list_spin_lock);
 			sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 		} else if (stream->data_blk.on == true) {
-			pr_debug("sst:user list empty.. wake\n");
+			pr_debug("user list empty.. wake\n");
 			/* unblock */
 			stream->data_blk.ret_code = 0;
 			stream->data_blk.condition = true;
@@ -678,7 +680,7 @@
 	struct stream_info *stream;
 
 
-	pr_debug("sst:capture frame for %d\n", str_id);
+	pr_debug("capture frame for %d\n", str_id);
 	retval = sst_validate_strid(str_id);
 	if (retval)
 		return retval;
@@ -688,19 +690,19 @@
 		if (kbufs->in_use == true) {
 			list_del(&kbufs->node);
 			kfree(kbufs);
-			pr_debug("sst:del node\n");
+			pr_debug("del node\n");
 		}
 	}
 	if (list_empty(&stream->bufs)) {
 		/* no user buffer available */
-		pr_debug("sst:Null buffer!!!!stream status %d\n",
+		pr_debug("Null buffer!!!!stream status %d\n",
 			       stream->status);
 		stream->prev = stream->status;
 		stream->status = STREAM_INIT;
-		pr_debug("sst:new stream status = %d\n",
+		pr_debug("new stream status = %d\n",
 			       stream->status);
 		if (stream->data_blk.on == true) {
-			pr_debug("sst:user list empty.. wake\n");
+			pr_debug("user list empty.. wake\n");
 			/* unblock */
 			stream->data_blk.ret_code = 0;
 			stream->data_blk.condition = true;
@@ -731,7 +733,7 @@
 	stream->cumm_bytes += stream->curr_bytes;
 	stream->curr_bytes = 0;
 
-    pr_debug("sst:Cum bytes  = %d\n", stream->cumm_bytes);
+    pr_debug("Cum bytes  = %d\n", stream->cumm_bytes);
 	return 0;
 }
 
@@ -743,7 +745,7 @@
 		if (bufs->buff_entry[i].size < min_val)
 			min_val = bufs->buff_entry[i].size;
 	}
-	pr_debug("sst:min_val = %d\n", min_val);
+	pr_debug("min_val = %d\n", min_val);
 	return min_val;
 }
 
@@ -754,7 +756,7 @@
 		if (bufs->buff_entry[i].size > max_val)
 			max_val = bufs->buff_entry[i].size;
 	}
-	pr_debug("sst:max_val = %d\n", max_val);
+	pr_debug("max_val = %d\n", max_val);
 	return max_val;
 }
 
@@ -773,7 +775,7 @@
 			if (dbufs->ibufs->entries == dbufs->obufs->entries)
 				return 0;
 			else {
-				pr_err("sst: RAR entries dont match\n");
+				pr_err("RAR entries dont match\n");
 				 return -EINVAL;
 			}
 		} else
@@ -783,26 +785,26 @@
 	}
 #endif
 	if (!str_info->decode_ibuf) {
-		pr_debug("sst:no i/p buffers, trying full size\n");
+		pr_debug("no i/p buffers, trying full size\n");
 		str_info->decode_isize = cum_input_given;
 		str_info->decode_ibuf = kzalloc(str_info->decode_isize,
 						GFP_KERNEL);
 		str_info->idecode_alloc = str_info->decode_isize;
 	}
 	if (!str_info->decode_ibuf) {
-		pr_debug("sst:buff alloc failed, try max size\n");
+		pr_debug("buff alloc failed, try max size\n");
 		str_info->decode_isize = calculate_max_size(dbufs->ibufs);
 		str_info->decode_ibuf = kzalloc(
 				str_info->decode_isize, GFP_KERNEL);
 		str_info->idecode_alloc = str_info->decode_isize;
 	}
 	if (!str_info->decode_ibuf) {
-		pr_debug("sst:buff alloc failed, try min size\n");
+		pr_debug("buff alloc failed, try min size\n");
 		str_info->decode_isize = calculate_min_size(dbufs->ibufs);
 		str_info->decode_ibuf = kzalloc(str_info->decode_isize,
 						GFP_KERNEL);
 		if (!str_info->decode_ibuf) {
-			pr_err("sst: mem allocation failed\n");
+			pr_err("mem allocation failed\n");
 			return -ENOMEM;
 		}
 		str_info->idecode_alloc = str_info->decode_isize;
@@ -820,7 +822,7 @@
 	struct ipc_post *msg = NULL;
 	int retval = 0;
 
-	pr_debug("SST DBGsst_set_mute:called\n");
+	pr_debug("SST DBG:sst_set_mute:called\n");
 
 	if (str_info->decode_ibuf_type == SST_BUF_RAR) {
 #ifdef CONFIG_MRST_RAR_HANDLER
@@ -857,7 +859,7 @@
 	dec_info->input_bytes_consumed = 0;
 	dec_info->output_bytes_produced = 0;
 	if (sst_create_large_msg(&msg)) {
-		pr_err("sst: message creation failed\n");
+		pr_err("message creation failed\n");
 		return -ENOMEM;
 	}
 
@@ -894,7 +896,7 @@
 				dbufs->ibufs->buff_entry[i].buffer,
 				sizeof(__u32));
 		if (retval) {
-			pr_err("sst:cpy from user fail\n");
+			pr_err("cpy from user fail\n");
 			return -EAGAIN;
 		}
 		rar_buffers.info.type = dbufs->ibufs->type;
@@ -931,7 +933,7 @@
 {
 	int i, cpy_size, retval = 0;
 
-	pr_debug("sst:input_index = %d, input entries = %d\n",
+	pr_debug("input_index = %d, input entries = %d\n",
 			 *input_index, dbufs->ibufs->entries);
 	for (i = *input_index; i < dbufs->ibufs->entries; i++) {
 #ifdef CONFIG_MRST_RAR_HANDLER
@@ -939,7 +941,7 @@
 			dbufs, input_index, in_copied,
 				input_index_valid_size, new_entry_flag);
 		if (retval) {
-			pr_err("sst: In prepare input buffers for RAR\n");
+			pr_err("In prepare input buffers for RAR\n");
 			return -EIO;
 		}
 #endif
@@ -947,10 +949,10 @@
 		if (*input_index_valid_size == 0)
 			*input_index_valid_size =
 				dbufs->ibufs->buff_entry[i].size;
-		pr_debug("sst:inout addr = %p, size = %d\n",
+		pr_debug("inout addr = %p, size = %d\n",
 			dbufs->ibufs->buff_entry[i].buffer,
 			*input_index_valid_size);
-		pr_debug("sst:decode_isize = %d, in_copied %d\n",
+		pr_debug("decode_isize = %d, in_copied %d\n",
 			str_info->decode_isize, *in_copied);
 		if (*input_index_valid_size <=
 					(str_info->decode_isize - *in_copied))
@@ -958,12 +960,12 @@
 		else
 			cpy_size = str_info->decode_isize - *in_copied;
 
-		pr_debug("sst:cpy size = %d\n", cpy_size);
+		pr_debug("cpy size = %d\n", cpy_size);
 		if (!dbufs->ibufs->buff_entry[i].buffer) {
-			pr_err("sst: i/p buffer is null\n");
+			pr_err("i/p buffer is null\n");
 			return -EINVAL;
 		}
-		pr_debug("sst:Try copy To %p, From %p, size %d\n",
+		pr_debug("Try copy To %p, From %p, size %d\n",
 				str_info->decode_ibuf + *in_copied,
 				dbufs->ibufs->buff_entry[i].buffer, cpy_size);
 
@@ -972,22 +974,22 @@
 				(void *) dbufs->ibufs->buff_entry[i].buffer,
 				cpy_size);
 		if (retval) {
-			pr_err("sst: copy from user failed\n");
+			pr_err("copy from user failed\n");
 			return -EIO;
 		}
 		*in_copied += cpy_size;
 		*input_index_valid_size -= cpy_size;
-		pr_debug("sst:in buff size = %d, in_copied = %d\n",
+		pr_debug("in buff size = %d, in_copied = %d\n",
 			*input_index_valid_size, *in_copied);
 		if (*input_index_valid_size != 0) {
-			pr_debug("sst:more input buffers left\n");
+			pr_debug("more input buffers left\n");
 			dbufs->ibufs->buff_entry[i].buffer += cpy_size;
 			break;
 		}
 		if (*in_copied == str_info->decode_isize &&
 			*input_index_valid_size == 0 &&
 			(i+1) <= dbufs->ibufs->entries) {
-			pr_debug("sst:all input buffers copied\n");
+			pr_debug("all input buffers copied\n");
 			*new_entry_flag = true;
 			*input_index = i + 1;
 			break;
@@ -1005,23 +1007,23 @@
 
 {
 	int i, cpy_size, retval = 0;
-	pr_debug("sst:output_index = %d, output entries = %d\n",
+	pr_debug("output_index = %d, output entries = %d\n",
 				*output_index,
 				dbufs->obufs->entries);
 	for (i = *output_index; i < dbufs->obufs->entries; i++) {
 		*output_index = i;
-		pr_debug("sst:output addr = %p, size = %d\n",
+		pr_debug("output addr = %p, size = %d\n",
 			dbufs->obufs->buff_entry[i].buffer,
 			dbufs->obufs->buff_entry[i].size);
-		pr_debug("sst:output_size = %d, out_copied = %d\n",
+		pr_debug("output_size = %d, out_copied = %d\n",
 				output_size, *out_copied);
 		if (dbufs->obufs->buff_entry[i].size <
 				(output_size - *out_copied))
 			cpy_size = dbufs->obufs->buff_entry[i].size;
 		else
 			cpy_size = output_size - *out_copied;
-		pr_debug("sst:cpy size = %d\n", cpy_size);
-		pr_debug("sst:Try copy To: %p, From %p, size %d\n",
+		pr_debug("cpy size = %d\n", cpy_size);
+		pr_debug("Try copy To: %p, From %p, size %d\n",
 				dbufs->obufs->buff_entry[i].buffer,
 				sst_drv_ctx->mmap_mem + *out_copied,
 				cpy_size);
@@ -1029,13 +1031,13 @@
 					sst_drv_ctx->mmap_mem + *out_copied,
 					cpy_size);
 		if (retval) {
-			pr_err("sst: copy to user failed\n");
+			pr_err("copy to user failed\n");
 			return -EIO;
 		} else
-			pr_debug("sst:copy to user passed\n");
+			pr_debug("copy to user passed\n");
 		*out_copied += cpy_size;
 		dbufs->obufs->buff_entry[i].size -= cpy_size;
-		pr_debug("sst:o/p buff size %d, out_copied %d\n",
+		pr_debug("o/p buff size %d, out_copied %d\n",
 			dbufs->obufs->buff_entry[i].size, *out_copied);
 		if (dbufs->obufs->buff_entry[i].size != 0) {
 			*output_index = i;
@@ -1073,7 +1075,7 @@
 	unsigned long long input_bytes, output_bytes;
 
 	sst_drv_ctx->scard_ops->power_down_pmic();
-	pr_debug("sst: Powering_down_PMIC...\n");
+	pr_debug("Powering_down_PMIC...\n");
 
 	retval = sst_validate_strid(str_id);
 	if (retval)
@@ -1081,7 +1083,7 @@
 
 	str_info = &sst_drv_ctx->streams[str_id];
 	if (str_info->status != STREAM_INIT) {
-		pr_err("sst: invalid stream state = %d\n",
+		pr_err("invalid stream state = %d\n",
 			       str_info->status);
 		return -EINVAL;
 	}
@@ -1098,7 +1100,7 @@
 	retval =  sst_allocate_decode_buf(str_info, dbufs,
 				cum_input_given, cum_output_given);
 	if (retval) {
-		pr_err("sst: mem allocation failed, abort!!!\n");
+		pr_err("mem allocation failed, abort!!!\n");
 		retval = -ENOMEM;
 		goto finish;
 	}
@@ -1114,7 +1116,7 @@
 			dbufs, &input_index, &in_copied,
 			&input_index_valid_size, &new_entry_flag);
 		if (retval) {
-			pr_err("sst: prepare in buffers failed\n");
+			pr_err("prepare in buffers failed\n");
 			goto finish;
 		}
 
@@ -1145,8 +1147,8 @@
 				str_info->decode_osize = dbufs->obufs->
 					buff_entry[output_index].size;
 				str_info->decode_obuf_type = dbufs->obufs->type;
-				pr_debug("sst:DRM handling\n");
-				pr_debug("o/p_add=0x%lu Size=0x%x",
+				pr_debug("DRM handling\n");
+				pr_debug("o/p_add=0x%lu Size=0x%x\n",
 					(unsigned long) str_info->decode_obuf,
 					str_info->decode_osize);
 			} else {
@@ -1160,7 +1162,7 @@
 		if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
 			if (str_info->decode_isize > in_copied) {
 				str_info->decode_isize = in_copied;
-				pr_debug("sst:i/p size = %d\n",
+				pr_debug("i/p size = %d\n",
 						str_info->decode_isize);
 			}
 		}
@@ -1168,20 +1170,19 @@
 
 		retval = sst_send_decode_mess(str_id, str_info, &dec_info);
 		if (retval || dec_info.input_bytes_consumed == 0) {
-			pr_err(
-				"SST ERR: mess failed or no input consumed\n");
+			pr_err("SST ERR: mess failed or no input consumed\n");
 			goto finish;
 		}
 		input_bytes = dec_info.input_bytes_consumed;
 		output_bytes = dec_info.output_bytes_produced;
 
-		pr_debug("sst:in_copied=%d, con=%lld, prod=%lld\n",
+		pr_debug("in_copied=%d, con=%lld, prod=%lld\n",
 			in_copied, input_bytes, output_bytes);
 		if (dbufs->obufs->type == SST_BUF_RAR) {
 			output_index += 1;
 			if (output_index == dbufs->obufs->entries) {
 				copy_in_done = true;
-				pr_debug("sst:all i/p cpy done\n");
+				pr_debug("all i/p cpy done\n");
 			}
 			total_output += output_bytes;
 		} else {
@@ -1190,14 +1191,14 @@
 			retval = sst_prepare_output_buffers(str_info, dbufs,
 				&output_index, output_size, &out_copied);
 			if (retval) {
-				pr_err("sst:prep out buff fail\n");
+				pr_err("prep out buff fail\n");
 				goto finish;
 			}
 			if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
 				if (in_copied != input_bytes) {
 					int bytes_left = in_copied -
 								input_bytes;
-					pr_debug("sst:bytes %d\n",
+					pr_debug("bytes %d\n",
 							bytes_left);
 					if (new_entry_flag == true)
 						input_index--;
@@ -1237,7 +1238,7 @@
 			total_output += out_copied;
 			if (str_info->decode_osize != out_copied) {
 				str_info->decode_osize -= out_copied;
-				pr_debug("sst:output size modified = %d\n",
+				pr_debug("output size modified = %d\n",
 						str_info->decode_osize);
 			}
 		}
@@ -1251,16 +1252,16 @@
 		} else {
 			if (total_output == cum_output_given) {
 				copy_out_done = true;
-				pr_debug("sst:all o/p cpy done\n");
+				pr_debug("all o/p cpy done\n");
 			}
 
 			if (total_input == cum_input_given) {
 				copy_in_done = true;
-				pr_debug("sst:all i/p cpy done\n");
+				pr_debug("all i/p cpy done\n");
 			}
 		}
 
-		pr_debug("sst:copy_out = %d, copy_in = %d\n",
+		pr_debug("copy_out = %d, copy_in = %d\n",
 				copy_out_done, copy_in_done);
 	}
 
diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c
index 4c0264c..47b91e5 100644
--- a/drivers/staging/intel_sst/intelmid.c
+++ b/drivers/staging/intel_sst/intelmid.c
@@ -24,6 +24,9 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  * ALSA driver for Intel MID sound card chipset
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
@@ -118,7 +121,7 @@
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		pr_debug("sst: Trigger Start\n");
+		pr_debug("Trigger Start\n");
 		ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_START,
 				&stream->stream_info.str_id);
 		if (ret_val)
@@ -128,7 +131,7 @@
 		stream->stream_status = RUNNING;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		pr_debug("sst: in stop\n");
+		pr_debug("in stop\n");
 		ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_DROP,
 				&stream->stream_info.str_id);
 		if (ret_val)
@@ -136,7 +139,7 @@
 		stream->stream_status = DROPPED;
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		pr_debug("sst: in pause\n");
+		pr_debug("in pause\n");
 		ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_PAUSE,
 				&stream->stream_info.str_id);
 		if (ret_val)
@@ -144,7 +147,7 @@
 		stream->stream_status = PAUSED;
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		pr_debug("sst: in pause release\n");
+		pr_debug("in pause release\n");
 		ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_RESUME,
 						&stream->stream_info.str_id);
 		if (ret_val)
@@ -170,17 +173,17 @@
 	int ret_val = 0;
 	struct snd_intelmad *intelmaddata;
 
-	pr_debug("sst: pcm_prepare called\n");
+	pr_debug("pcm_prepare called\n");
 
 	WARN_ON(!substream);
 	stream = substream->runtime->private_data;
 	intelmaddata = snd_pcm_substream_chip(substream);
-	pr_debug("sst: pb cnt = %d cap cnt = %d\n",\
+	pr_debug("pb cnt = %d cap cnt = %d\n",\
 		intelmaddata->playback_cnt,
 		intelmaddata->capture_cnt);
 
 	if (stream->stream_info.str_id) {
-		pr_debug("sst: Prepare called for already set stream\n");
+		pr_debug("Prepare called for already set stream\n");
 		ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_DROP,
 					&stream->stream_info.str_id);
 		return ret_val;
@@ -197,7 +200,7 @@
 	/* return back the stream id */
 	snprintf(substream->pcm->id, sizeof(substream->pcm->id),
 			"%d", stream->stream_info.str_id);
-	pr_debug("sst: stream id to user = %s\n",
+	pr_debug("stream id to user = %s\n",
 			substream->pcm->id);
 
 	ret_val = snd_intelmad_init_stream(substream);
@@ -212,7 +215,7 @@
 {
 	int ret_val;
 
-	pr_debug("sst: snd_intelmad_hw_params called\n");
+	pr_debug("snd_intelmad_hw_params called\n");
 	ret_val = snd_pcm_lib_malloc_pages(substream,
 			params_buffer_bytes(hw_params));
 	memset(substream->runtime->dma_area, 0,
@@ -223,7 +226,7 @@
 
 static int snd_intelmad_hw_free(struct snd_pcm_substream *substream)
 {
-	pr_debug("sst: snd_intelmad_hw_free called\n");
+	pr_debug("snd_intelmad_hw_free called\n");
 	return snd_pcm_lib_free_pages(substream);
 }
 
@@ -253,12 +256,12 @@
 	ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_BUFFER_POINTER,
 				&stream->stream_info);
 	if (ret_val) {
-		pr_err("sst: error code = 0x%x\n", ret_val);
+		pr_err("error code = 0x%x\n", ret_val);
 		return ret_val;
 	}
-	pr_debug("sst: samples reported out 0x%llx\n",
+	pr_debug("samples reported out 0x%llx\n",
 			stream->stream_info.buffer_ptr);
-	pr_debug("sst: Frame bits:: %d period_count :: %d\n",
+	pr_debug("Frame bits:: %d period_count :: %d\n",
 			(int)substream->runtime->frame_bits,
 			(int)substream->runtime->period_size);
 
@@ -283,10 +286,10 @@
 
 	stream = substream->runtime->private_data;
 
-	pr_debug("sst: snd_intelmad_close called\n");
+	pr_debug("snd_intelmad_close called\n");
 	intelmaddata = snd_pcm_substream_chip(substream);
 
-	pr_debug("sst: str id = %d\n", stream->stream_info.str_id);
+	pr_debug("str id = %d\n", stream->stream_info.str_id);
 	if (stream->stream_info.str_id) {
 		/* SST API to actually stop/free the stream */
 		ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_FREE,
@@ -296,7 +299,7 @@
 		else
 			intelmaddata->capture_cnt--;
 	}
-	pr_debug("sst: snd_intelmad_close : pb cnt = %d cap cnt = %d\n",
+	pr_debug("snd_intelmad_close : pb cnt = %d cap cnt = %d\n",
 		intelmaddata->playback_cnt, intelmaddata->capture_cnt);
 	kfree(substream->runtime->private_data);
 	return ret_val;
@@ -319,7 +322,7 @@
 
 	WARN_ON(!substream);
 
-	pr_debug("sst: snd_intelmad_open called\n");
+	pr_debug("snd_intelmad_open called\n");
 
 	intelmaddata = snd_pcm_substream_chip(substream);
 	runtime = substream->runtime;
@@ -456,17 +459,17 @@
 {
 
 	if (!jack) {
-		pr_debug("sst: MAD error jack empty\n");
+		pr_debug("MAD error jack empty\n");
 
 	} else {
-		pr_debug("sst: MAD send jack report for = %d!!!\n", status);
-		pr_debug("sst: MAD send jack report %d\n", jack->type);
+		pr_debug("MAD send jack report for = %d!!!\n", status);
+		pr_debug("MAD send jack report %d\n", jack->type);
 		snd_jack_report(jack, status);
 
 		/*button pressed and released */
 		if (buttonpressevent)
 			snd_jack_report(jack, 0);
-		pr_debug("sst: MAD sending jack report Done !!!\n");
+		pr_debug("MAD sending jack report Done !!!\n");
 	}
 
 
@@ -490,7 +493,7 @@
 	if (intsts & 0x4) {
 
 		if (!(intelmid_audio_interrupt_enable)) {
-			pr_debug("sst: Audio interrupt enable\n");
+			pr_debug("Audio interrupt enable\n");
 			sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
 
 			sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
@@ -500,7 +503,7 @@
 
 		}
 		/* send headphone detect */
-		pr_debug("sst: MAD headphone %d\n", intsts & 0x4);
+		pr_debug("MAD headphone %d\n", intsts & 0x4);
 		jack = &intelmaddata->jack[0].jack;
 		present = !(intelmaddata->jack[0].jack_status);
 		intelmaddata->jack[0].jack_status = present;
@@ -510,7 +513,7 @@
 
 	if (intsts & 0x2) {
 		/* send short push */
-		pr_debug("sst: MAD short push %d\n", intsts & 0x2);
+		pr_debug("MAD short push %d\n", intsts & 0x2);
 		jack = &intelmaddata->jack[2].jack;
 		present = 1;
 		jack_event_flag = 1;
@@ -518,7 +521,7 @@
 	}
 	if (intsts & 0x1) {
 		/* send long push */
-		pr_debug("sst: MAD long push %d\n", intsts & 0x1);
+		pr_debug("MAD long push %d\n", intsts & 0x1);
 		jack = &intelmaddata->jack[3].jack;
 		present = 1;
 		jack_event_flag = 1;
@@ -526,7 +529,7 @@
 	}
 	if (intsts & 0x8) {
 		if (!(intelmid_audio_interrupt_enable)) {
-			pr_debug("sst: Audio interrupt enable\n");
+			pr_debug("Audio interrupt enable\n");
 			sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
 
 			sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
@@ -535,7 +538,7 @@
 			intelmaddata->jack[1].jack_status = 0;
 		}
 		/* send headset detect */
-		pr_debug("sst: MAD headset = %d\n", intsts & 0x8);
+		pr_debug("MAD headset = %d\n", intsts & 0x8);
 		jack = &intelmaddata->jack[1].jack;
 		present = !(intelmaddata->jack[1].jack_status);
 		intelmaddata->jack[1].jack_status = present;
@@ -558,10 +561,10 @@
 
 	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
 
-	pr_debug("sst: previous value: %x\n", intelmaddata->jack_prev_state);
+	pr_debug("previous value: %x\n", intelmaddata->jack_prev_state);
 
 	if (!(intelmid_audio_interrupt_enable)) {
-		pr_debug("sst: Audio interrupt enable\n");
+		pr_debug("Audio interrupt enable\n");
 		intelmaddata->jack_prev_state = 0xC0;
 		intelmid_audio_interrupt_enable = 1;
 	}
@@ -572,12 +575,12 @@
 			sc_access_read.reg_addr = 0x201;
 			sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
 			value = (sc_access_read.value);
-			pr_debug("sst: value returned = 0x%x\n", value);
+			pr_debug("value returned = 0x%x\n", value);
 		}
 
 		if (jack_prev_state == 0xc0 && value == 0x40) {
 			/*headset detected. */
-			pr_debug("sst: MAD headset inserted\n");
+			pr_debug("MAD headset inserted\n");
 			jack = &intelmaddata->jack[1].jack;
 			present = 1;
 			jack_event_flag = 1;
@@ -587,7 +590,7 @@
 
 		if (jack_prev_state == 0xc0 && value == 0x00) {
 			/* headphone  detected. */
-			pr_debug("sst: MAD headphone inserted\n");
+			pr_debug("MAD headphone inserted\n");
 			jack = &intelmaddata->jack[0].jack;
 			present = 1;
 			jack_event_flag = 1;
@@ -596,9 +599,9 @@
 
 		if (jack_prev_state == 0x40 && value == 0xc0) {
 			/*headset  removed*/
-			pr_debug("sst: Jack headset status %d\n",
+			pr_debug("Jack headset status %d\n",
 				intelmaddata->jack[1].jack_status);
-			pr_debug("sst: MAD headset removed\n");
+			pr_debug("MAD headset removed\n");
 			jack = &intelmaddata->jack[1].jack;
 			present = 0;
 			jack_event_flag = 1;
@@ -607,9 +610,9 @@
 
 		if (jack_prev_state == 0x00 && value == 0xc0) {
 			/* headphone  detected. */
-			pr_debug("sst: Jack headphone status %d\n",
+			pr_debug("Jack headphone status %d\n",
 					intelmaddata->jack[0].jack_status);
-			pr_debug("sst: headphone removed\n");
+			pr_debug("headphone removed\n");
 			jack = &intelmaddata->jack[0].jack;
 			present = 0;
 			jack_event_flag = 1;
@@ -618,7 +621,7 @@
 		if (jack_prev_state == 0x40 && value == 0x00) {
 			/*button pressed*/
 			do_gettimeofday(&intelmaddata->jack[1].buttonpressed);
-			pr_debug("sst: MAD button press detected n");
+			pr_debug("MAD button press detected\n");
 		}
 
 
@@ -628,19 +631,19 @@
 				do_gettimeofday(
 					&intelmaddata->jack[1].buttonreleased);
 				/*button pressed */
-				pr_debug("sst: Button Released detected\n");
+				pr_debug("Button Released detected\n");
 				timediff = intelmaddata->jack[1].
 					buttonreleased.tv_sec - intelmaddata->
 					jack[1].buttonpressed.tv_sec;
 				buttonpressflag = 1;
 				if (timediff > 1) {
-					pr_debug("sst: long press detected\n");
+					pr_debug("long press detected\n");
 					/* send headphone detect/undetect */
 					jack = &intelmaddata->jack[3].jack;
 					present = 1;
 					jack_event_flag = 1;
 				} else {
-					pr_debug("sst: short press detected\n");
+					pr_debug("short press detected\n");
 					/* send headphone detect/undetect */
 					jack = &intelmaddata->jack[2].jack;
 					present = 1;
@@ -667,24 +670,24 @@
 		sc_access_read.reg_addr = 0x132;
 		sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
 		value = (sc_access_read.value);
-		pr_debug("sst: value returned = 0x%x\n", value);
+		pr_debug("value returned = 0x%x\n", value);
 	}
 	if (intsts & 0x1) {
-		pr_debug("sst: headset detected\n");
+		pr_debug("headset detected\n");
 		/* send headset detect/undetect */
 		jack = &intelmaddata->jack[1].jack;
 		present = (value == 0x1) ? 1 : 0;
 		jack_event_flag = 1;
 	}
 	if (intsts & 0x2) {
-		pr_debug("sst: headphone detected\n");
+		pr_debug("headphone detected\n");
 		/* send headphone detect/undetect */
 		jack = &intelmaddata->jack[0].jack;
 		present = (value == 0x2) ? 1 : 0;
 		jack_event_flag = 1;
 	}
 	if (intsts & 0x4) {
-		pr_debug("sst: short push detected\n");
+		pr_debug("short push detected\n");
 		/* send short push */
 		jack = &intelmaddata->jack[2].jack;
 		present = 1;
@@ -692,7 +695,7 @@
 		buttonpressflag = 1;
 	}
 	if (intsts & 0x8) {
-		pr_debug("sst: long push detected\n");
+		pr_debug("long push detected\n");
 		/* send long push */
 		jack = &intelmaddata->jack[3].jack;
 		present = 1;
@@ -738,12 +741,12 @@
 	u32 regbase = AUDINT_BASE, regsize = 8;
 	char *drv_name;
 
-	pr_debug("sst: irq reg done, regbase 0x%x, regsize 0x%x\n",
+	pr_debug("irq reg done, regbase 0x%x, regsize 0x%x\n",
 					regbase, regsize);
 	intelmaddata->int_base = ioremap_nocache(regbase, regsize);
 	if (!intelmaddata->int_base)
-		pr_err("sst: Mapping of cache failed\n");
-	pr_debug("sst: irq = 0x%x\n", intelmaddata->irq);
+		pr_err("Mapping of cache failed\n");
+	pr_debug("irq = 0x%x\n", intelmaddata->irq);
 	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL)
 		drv_name = DRIVER_NAME_MFLD;
 	else
@@ -753,7 +756,7 @@
 				IRQF_SHARED, drv_name,
 				intelmaddata);
 	if (ret_val)
-		pr_err("sst: cannot register IRQ\n");
+		pr_err("cannot register IRQ\n");
 	return ret_val;
 }
 
@@ -775,10 +778,10 @@
 		if (ret_val)
 			return ret_val;
 		sst_card_vendor_id = (vendor_addr.value & (MASK2|MASK1|MASK0));
-		pr_debug("sst: orginal n extrated vendor id = 0x%x %d\n",
+		pr_debug("orginal n extrated vendor id = 0x%x %d\n",
 				vendor_addr.value, sst_card_vendor_id);
 		if (sst_card_vendor_id < 0 || sst_card_vendor_id > 2) {
-			pr_err("sst: vendor card not supported!!\n");
+			pr_err("vendor card not supported!!\n");
 			return -EIO;
 		}
 	} else
@@ -801,7 +804,7 @@
 	/* registering with SST driver to get access to SST APIs to use */
 	ret_val = register_sst_card(intelmaddata->sstdrv_ops);
 	if (ret_val) {
-		pr_err("sst: sst card registration failed\n");
+		pr_err("sst card registration failed\n");
 		return ret_val;
 	}
 
@@ -832,7 +835,7 @@
 	char name[32] = INTEL_MAD;
 	struct snd_pcm_ops *pb_ops = NULL, *cap_ops = NULL;
 
-	pr_debug("sst: called for pb %d, cp %d, idx %d\n", pb, cap, index);
+	pr_debug("called for pb %d, cp %d, idx %d\n", pb, cap, index);
 	ret_val = snd_pcm_new(card, name, index, pb, cap, &pcm);
 	if (ret_val)
 		return ret_val;
@@ -878,7 +881,7 @@
 
 	WARN_ON(!card);
 	WARN_ON(!intelmaddata);
-	pr_debug("sst: snd_intelmad_pcm called\n");
+	pr_debug("snd_intelmad_pcm called\n");
 	ret_val = snd_intelmad_pcm_new(card, intelmaddata, 1, 1, 0);
 	if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT)
 		return ret_val;
@@ -903,7 +906,7 @@
 	struct snd_jack *jack;
 	int retval;
 
-	pr_debug("sst: snd_intelmad_jack called\n");
+	pr_debug("snd_intelmad_jack called\n");
 	jack = &intelmaddata->jack[0].jack;
 	retval = snd_jack_new(intelmaddata->card, "Headphone",
 				SND_JACK_HEADPHONE, &jack);
@@ -982,9 +985,9 @@
 		ret_val = snd_ctl_add(card,
 				snd_ctl_new1(&controls[idx],
 				intelmaddata));
-		pr_debug("sst: mixer[idx]=%d added\n", idx);
+		pr_debug("mixer[idx]=%d added\n", idx);
 		if (ret_val) {
-			pr_err("sst: in adding of control index = %d\n", idx);
+			pr_err("in adding of control index = %d\n", idx);
 			break;
 		}
 	}
@@ -999,7 +1002,7 @@
 
 	intelmaddata = device->device_data;
 
-	pr_debug("sst: snd_intelmad_dev_free called\n");
+	pr_debug("snd_intelmad_dev_free called\n");
 	snd_card_free(intelmaddata->card);
 	/*genl_unregister_family(&audio_event_genl_family);*/
 	unregister_sst_card(intelmaddata->sstdrv_ops);
@@ -1040,23 +1043,23 @@
 	const struct platform_device_id *id = platform_get_device_id(pdev);
 	unsigned int cpu_id = (unsigned int)id->driver_data;
 
-	pr_debug("sst: probe for %s cpu_id %d\n", pdev->name, cpu_id);
+	pr_debug("probe for %s cpu_id %d\n", pdev->name, cpu_id);
 	if (!strcmp(pdev->name, DRIVER_NAME_MRST))
-		pr_debug("sst: detected MRST\n");
+		pr_debug("detected MRST\n");
 	else if (!strcmp(pdev->name, DRIVER_NAME_MFLD))
-		pr_debug("sst: detected MFLD\n");
+		pr_debug("detected MFLD\n");
 	else {
-		pr_err("sst: detected unknown device abort!!\n");
+		pr_err("detected unknown device abort!!\n");
 		return -EIO;
 	}
 	if ((cpu_id < CPU_CHIP_LINCROFT) || (cpu_id > CPU_CHIP_PENWELL)) {
-		pr_err("sst: detected unknown cpu_id abort!!\n");
+		pr_err("detected unknown cpu_id abort!!\n");
 		return -EIO;
 	}
 	/* allocate memory for saving internal context and working */
 	intelmaddata = kzalloc(sizeof(*intelmaddata), GFP_KERNEL);
 	if (!intelmaddata) {
-		pr_debug("sst: mem alloctn fail\n");
+		pr_debug("mem alloctn fail\n");
 		return -ENOMEM;
 	}
 
@@ -1064,7 +1067,7 @@
 	intelmaddata->sstdrv_ops = kzalloc(sizeof(struct intel_sst_card_ops),
 					GFP_KERNEL);
 	if (!intelmaddata->sstdrv_ops) {
-		pr_err("sst: mem allocation for ops fail\n");
+		pr_err("mem allocation for ops fail\n");
 		kfree(intelmaddata);
 		return -ENOMEM;
 	}
@@ -1073,7 +1076,7 @@
 	/* create a card instance with ALSA framework */
 	ret_val = snd_card_create(card_index, card_id, THIS_MODULE, 0, &card);
 	if (ret_val) {
-		pr_err("sst: snd_card_create fail\n");
+		pr_err("snd_card_create fail\n");
 		goto free_allocs;
 	}
 
@@ -1092,7 +1095,7 @@
 	/* registering with LPE driver to get access to SST APIs to use */
 	ret_val = snd_intelmad_sst_register(intelmaddata);
 	if (ret_val) {
-		pr_err("sst: snd_intelmad_sst_register failed\n");
+		pr_err("snd_intelmad_sst_register failed\n");
 		goto free_allocs;
 	}
 
@@ -1100,19 +1103,19 @@
 
 	ret_val = snd_intelmad_pcm(card, intelmaddata);
 	if (ret_val) {
-		pr_err("sst: snd_intelmad_pcm failed\n");
+		pr_err("snd_intelmad_pcm failed\n");
 		goto free_allocs;
 	}
 
 	ret_val = snd_intelmad_mixer(intelmaddata);
 	if (ret_val) {
-		pr_err("sst: snd_intelmad_mixer failed\n");
+		pr_err("snd_intelmad_mixer failed\n");
 		goto free_allocs;
 	}
 
 	ret_val = snd_intelmad_jack(intelmaddata);
 	if (ret_val) {
-		pr_err("sst: snd_intelmad_jack failed\n");
+		pr_err("snd_intelmad_jack failed\n");
 		goto free_allocs;
 	}
 
@@ -1126,31 +1129,31 @@
 
 	ret_val = snd_intelmad_register_irq(intelmaddata);
 	if (ret_val) {
-		pr_err("sst: snd_intelmad_register_irq fail\n");
+		pr_err("snd_intelmad_register_irq fail\n");
 		goto free_allocs;
 	}
 
 	/* internal function call to register device with ALSA */
 	ret_val = snd_intelmad_create(intelmaddata, card);
 	if (ret_val) {
-		pr_err("sst: snd_intelmad_create failed\n");
+		pr_err("snd_intelmad_create failed\n");
 		goto free_allocs;
 	}
 	card->private_data = &intelmaddata;
 	snd_card_set_dev(card, &pdev->dev);
 	ret_val = snd_card_register(card);
 	if (ret_val) {
-		pr_err("sst: snd_card_register failed\n");
+		pr_err("snd_card_register failed\n");
 		goto free_allocs;
 	}
 
-	pr_debug("sst:snd_intelmad_probe complete\n");
+	pr_debug("snd_intelmad_probe complete\n");
 	return ret_val;
 
 free_mad_jack_wq:
 	destroy_workqueue(intelmaddata->mad_jack_wq);
 free_allocs:
-	pr_err("sst: probe failed\n");
+	pr_err("probe failed\n");
 	snd_card_free(card);
 	kfree(intelmaddata->sstdrv_ops);
 	kfree(intelmaddata);
@@ -1200,7 +1203,7 @@
  */
 static int __init alsa_card_intelmad_init(void)
 {
-	pr_debug("sst: mad_init called\n");
+	pr_debug("mad_init called\n");
 	return platform_driver_register(&snd_intelmad_driver);
 }
 
@@ -1211,7 +1214,7 @@
  */
 static void __exit alsa_card_intelmad_exit(void)
 {
-	pr_debug("sst:mad_exit called\n");
+	pr_debug("mad_exit called\n");
 	return platform_driver_unregister(&snd_intelmad_driver);
 }
 
diff --git a/drivers/staging/intel_sst/intelmid_ctrl.c b/drivers/staging/intel_sst/intelmid_ctrl.c
index 03b4ece..0d91357 100644
--- a/drivers/staging/intel_sst/intelmid_ctrl.c
+++ b/drivers/staging/intel_sst/intelmid_ctrl.c
@@ -24,6 +24,9 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *  ALSA driver handling mixer controls for Intel MAD chipset
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <sound/core.h>
 #include <sound/control.h>
 #include "jack.h"
@@ -216,7 +219,7 @@
 	struct snd_intelmad *intelmaddata;
 	struct snd_pmic_ops *scard_ops;
 
-	pr_debug("sst: snd_intelmad_volume_get called\n");
+	pr_debug("snd_intelmad_volume_get called\n");
 
 	WARN_ON(!uval);
 	WARN_ON(!kcontrol);
@@ -273,7 +276,7 @@
 	struct snd_intelmad *intelmaddata;
 	struct snd_pmic_ops *scard_ops;
 
-	pr_debug("sst: Mute_get called\n");
+	pr_debug("Mute_get called\n");
 
 	WARN_ON(!uval);
 	WARN_ON(!kcontrol);
@@ -332,7 +335,7 @@
 	struct snd_intelmad *intelmaddata;
 	struct snd_pmic_ops *scard_ops;
 
-	pr_debug("sst: volume set called:%ld %ld\n",
+	pr_debug("volume set called:%ld %ld\n",
 			uval->value.integer.value[0],
 			uval->value.integer.value[1]);
 
@@ -387,7 +390,7 @@
 	struct snd_intelmad *intelmaddata;
 	struct snd_pmic_ops *scard_ops;
 
-	pr_debug("sst: snd_intelmad_mute_set called\n");
+	pr_debug("snd_intelmad_mute_set called\n");
 
 	WARN_ON(!uval);
 	WARN_ON(!kcontrol);
@@ -455,7 +458,7 @@
 {
 	struct snd_intelmad *intelmaddata;
 	struct snd_pmic_ops *scard_ops;
-	pr_debug("sst: device_get called\n");
+	pr_debug("device_get called\n");
 
 	WARN_ON(!uval);
 	WARN_ON(!kcontrol);
@@ -492,7 +495,7 @@
 	struct snd_pmic_ops *scard_ops;
 	int ret_val = 0, vendor, status;
 
-	pr_debug("sst: snd_intelmad_device_set called\n");
+	pr_debug("snd_intelmad_device_set called\n");
 
 	WARN_ON(!uval);
 	WARN_ON(!kcontrol);
diff --git a/drivers/staging/intel_sst/intelmid_msic_control.c b/drivers/staging/intel_sst/intelmid_msic_control.c
index 4d1755e..da093ed 100644
--- a/drivers/staging/intel_sst/intelmid_msic_control.c
+++ b/drivers/staging/intel_sst/intelmid_msic_control.c
@@ -24,6 +24,8 @@
  * This file contains the control operations of msic vendors
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/file.h>
 #include "intel_sst.h"
@@ -83,7 +85,7 @@
 	snd_msic_ops.cap_on = 0;
 	snd_msic_ops.input_dev_id = DMIC; /*def dev*/
 	snd_msic_ops.output_dev_id = STEREO_HEADPHONE;
-	pr_debug("sst: msic init complete!!\n");
+	pr_debug("msic init complete!!\n");
 	return 0;
 }
 
@@ -173,7 +175,7 @@
 			return retval;
 	}
 
-	pr_debug("sst: powering up pb.... Device %d\n", device);
+	pr_debug("powering up pb.... Device %d\n", device);
 	sst_sc_reg_access(sc_access1, PMIC_WRITE, 4);
 	switch (device) {
 	case SND_SST_DEVICE_HEADSET:
@@ -205,7 +207,7 @@
 		break;
 
 	default:
-		pr_warn("sst: Wrong Device %d, selected %d\n",
+		pr_warn("Wrong Device %d, selected %d\n",
 			       device, snd_msic_ops.output_dev_id);
 	}
 	return sst_sc_reg_access(sc_access_pcm2, PMIC_READ_MODIFY, 1);
@@ -268,7 +270,7 @@
 			return retval;
 	}
 
-	pr_debug("sst: powering up cp....%d\n", snd_msic_ops.input_dev_id);
+	pr_debug("powering up cp....%d\n", snd_msic_ops.input_dev_id);
 	sst_sc_reg_access(sc_access2, PMIC_READ_MODIFY, 1);
 	snd_msic_ops.cap_on = 1;
 	if (snd_msic_ops.input_dev_id == AMIC)
@@ -283,7 +285,7 @@
 {
 	int retval = 0;
 
-	pr_debug("sst: powering dn msic\n");
+	pr_debug("powering dn msic\n");
 	snd_msic_ops.pb_on = 0;
 	snd_msic_ops.cap_on = 0;
 	return retval;
@@ -293,7 +295,7 @@
 {
 	int retval = 0;
 
-	pr_debug("sst: powering dn pb....\n");
+	pr_debug("powering dn pb....\n");
 	snd_msic_ops.pb_on = 0;
 	return retval;
 }
@@ -302,7 +304,7 @@
 {
 	int retval = 0;
 
-	pr_debug("sst: powering dn cp....\n");
+	pr_debug("powering dn cp....\n");
 	snd_msic_ops.cap_on = 0;
 	return retval;
 }
@@ -311,7 +313,7 @@
 {
 	int retval = 0;
 
-	pr_debug("sst: msic set selected output:%d\n", value);
+	pr_debug("msic set selected output:%d\n", value);
 	snd_msic_ops.output_dev_id = value;
 	if (snd_msic_ops.pb_on)
 		msic_power_up_pb(SND_SST_DEVICE_HEADSET);
@@ -330,15 +332,15 @@
 	};
 	int retval = 0;
 
-	pr_debug("sst: msic_set_selected_input_dev:%d\n", value);
+	pr_debug("msic_set_selected_input_dev:%d\n", value);
 	snd_msic_ops.input_dev_id = value;
 	switch (value) {
 	case AMIC:
-		pr_debug("sst: Selecting AMIC1\n");
+		pr_debug("Selecting AMIC1\n");
 		retval = sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 1);
 		break;
 	case DMIC:
-		pr_debug("sst: Selecting DMIC1\n");
+		pr_debug("Selecting DMIC1\n");
 		retval = sst_sc_reg_access(sc_access_dmic, PMIC_WRITE, 1);
 		break;
 	default:
diff --git a/drivers/staging/intel_sst/intelmid_pvt.c b/drivers/staging/intel_sst/intelmid_pvt.c
index 9ed9475..4f9bdf3 100644
--- a/drivers/staging/intel_sst/intelmid_pvt.c
+++ b/drivers/staging/intel_sst/intelmid_pvt.c
@@ -23,6 +23,9 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  * ALSA driver for Intel MID sound card chipset - holding private functions
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/io.h>
 #include <asm/intel_scu_ipc.h>
 #include <sound/core.h>
@@ -50,7 +53,7 @@
 
 	if (stream->stream_status != RUNNING)
 		return;
-	pr_debug("sst: calling period elapsed\n");
+	pr_debug("calling period elapsed\n");
 	snd_pcm_period_elapsed(substream);
 	return;
 }
@@ -76,8 +79,8 @@
 	param.uc.pcm_params.period_count = substream->runtime->period_size;
 	param.uc.pcm_params.ring_buffer_addr =
 				virt_to_phys(substream->runtime->dma_area);
-	pr_debug("sst: period_cnt = %d\n", param.uc.pcm_params.period_count);
-	pr_debug("sst: sfreq= %d, wd_sz = %d\n",
+	pr_debug("period_cnt = %d\n", param.uc.pcm_params.period_count);
+	pr_debug("sfreq= %d, wd_sz = %d\n",
 		 param.uc.pcm_params.sfreq, param.uc.pcm_params.pcm_wd_sz);
 
 	str_params.sparams = param;
@@ -85,16 +88,16 @@
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		str_params.ops = STREAM_OPS_PLAYBACK;
-		pr_debug("sst: Playbck stream,Device %d\n", stream->device);
+		pr_debug("Playbck stream,Device %d\n", stream->device);
 	} else {
 		str_params.ops = STREAM_OPS_CAPTURE;
 		stream->device = SND_SST_DEVICE_CAPTURE;
-		pr_debug("sst: Capture stream,Device %d\n", stream->device);
+		pr_debug("Capture stream,Device %d\n", stream->device);
 	}
 	str_params.device_type = stream->device;
 	ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_ALLOC,
 					&str_params);
-	pr_debug("sst: SST_SND_PLAY/CAPTURE ret_val = %x\n",
+	pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n",
 			ret_val);
 	if (ret_val < 0)
 		return ret_val;
@@ -102,7 +105,7 @@
 	stream->stream_info.str_id = ret_val;
 	stream->stream_status = INIT;
 	stream->stream_info.buffer_ptr = 0;
-	pr_debug("sst: str id :  %d\n", stream->stream_info.str_id);
+	pr_debug("str id :  %d\n", stream->stream_info.str_id);
 
 	return ret_val;
 }
@@ -113,7 +116,7 @@
 	struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
 	int ret_val;
 
-	pr_debug("sst: setting buffer ptr param\n");
+	pr_debug("setting buffer ptr param\n");
 	stream->stream_info.period_elapsed = period_elapsed;
 	stream->stream_info.mad_substream = substream;
 	stream->stream_info.buffer_ptr = 0;
@@ -121,7 +124,7 @@
 	ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_STREAM_INIT,
 					&stream->stream_info);
 	if (ret_val)
-		pr_err("sst: control_set ret error %d\n", ret_val);
+		pr_err("control_set ret error %d\n", ret_val);
 	return ret_val;
 
 }
@@ -146,7 +149,7 @@
 			retval = intel_scu_ipc_iowrite8(sc_access[i].reg_addr,
 							sc_access[i].value);
 			if (retval) {
-				pr_err("sst: IPC write failed!!! %d\n", retval);
+				pr_err("IPC write failed!!! %d\n", retval);
 				return retval;
 			}
 		}
@@ -155,7 +158,7 @@
 			retval = intel_scu_ipc_ioread8(sc_access[i].reg_addr,
 							&(sc_access[i].value));
 			if (retval) {
-				pr_err("sst: IPC read failed!!!!!%d\n", retval);
+				pr_err("IPC read failed!!!!!%d\n", retval);
 				return retval;
 			}
 		}
@@ -165,7 +168,7 @@
 				sc_access[i].reg_addr, sc_access[i].value,
 				sc_access[i].mask);
 			if (retval) {
-				pr_err("sst: IPC Modify failed!!!%d\n", retval);
+				pr_err("IPC Modify failed!!!%d\n", retval);
 				return retval;
 			}
 		}
diff --git a/drivers/staging/intel_sst/intelmid_v0_control.c b/drivers/staging/intel_sst/intelmid_v0_control.c
index f586d62..7859225 100644
--- a/drivers/staging/intel_sst/intelmid_v0_control.c
+++ b/drivers/staging/intel_sst/intelmid_v0_control.c
@@ -26,6 +26,8 @@
  *  This file contains the control operations of vendor 1
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/file.h>
 #include "intel_sst.h"
@@ -151,7 +153,7 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: in fs power up pb\n");
+	pr_debug("in fs power up pb\n");
 	return fs_enable_audiodac(UNMUTE);
 }
 
@@ -173,7 +175,7 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: in fsl power down pb\n");
+	pr_debug("in fsl power down pb\n");
 	return fs_enable_audiodac(UNMUTE);
 }
 
@@ -380,7 +382,7 @@
 		sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 
 	}
-	pr_debug("sst: sfreq:%d,Register value = %x\n", sfreq, config1);
+	pr_debug("sfreq:%d,Register value = %x\n", sfreq, config1);
 
 	if (word_size == 24) {
 		sc_access[0].reg_addr  = AUDIOPORT1;
@@ -438,18 +440,18 @@
 
 	switch (value) {
 	case AMIC:
-		pr_debug("sst: Selecting amic not supported in mono cfg\n");
+		pr_debug("Selecting amic not supported in mono cfg\n");
 		return sst_sc_reg_access(sc_access_mic, PMIC_READ_MODIFY, 2);
 		break;
 
 	case HS_MIC:
-		pr_debug("sst: Selecting hsmic\n");
+		pr_debug("Selecting hsmic\n");
 		return sst_sc_reg_access(sc_access_hsmic,
 				PMIC_READ_MODIFY, 2);
 		break;
 
 	case DMIC:
-		pr_debug("sst: Selecting dmic\n");
+		pr_debug("Selecting dmic\n");
 		return sst_sc_reg_access(sc_access_dmic, PMIC_READ_MODIFY, 2);
 		break;
 
@@ -505,7 +507,7 @@
 		return retval;
 
 
-	pr_debug("sst: dev_id:0x%x value:0x%x\n", dev_id, value);
+	pr_debug("dev_id:0x%x value:0x%x\n", dev_id, value);
 	switch (dev_id) {
 	case PMIC_SND_DMIC_MUTE:
 		sc_access[0].reg_addr = MICCTRL;
@@ -606,7 +608,7 @@
 
 	switch (dev_id) {
 	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("sst: PMIC_SND_LEFT_PB_VOL:%d\n", value);
+		pr_debug("PMIC_SND_LEFT_PB_VOL:%d\n", value);
 		sc_access[0].value = sc_access[1].value = value;
 		sc_access[0].reg_addr = AUD16;
 		sc_access[1].reg_addr = AUD15;
@@ -616,7 +618,7 @@
 		break;
 
 	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("sst: PMIC_SND_RIGHT_PB_VOL:%d\n", value);
+		pr_debug("PMIC_SND_RIGHT_PB_VOL:%d\n", value);
 		sc_access[0].value = sc_access[1].value = value;
 		sc_access[0].reg_addr = AUD17;
 		sc_access[1].reg_addr = AUD15;
@@ -629,7 +631,7 @@
 		reg_num = 2;
 		break;
 	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("sst: PMIC_SND_CAPTURE_VOL:%d\n", value);
+		pr_debug("PMIC_SND_CAPTURE_VOL:%d\n", value);
 		sc_access[0].reg_addr = MICLICTRL1;
 		sc_access[1].reg_addr = MICLICTRL2;
 		sc_access[2].reg_addr = DMICCTRL1;
@@ -726,17 +728,17 @@
 
 	switch (dev_id) {
 	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("sst: PMIC_SND_CAPTURE_VOL\n");
+		pr_debug("PMIC_SND_CAPTURE_VOL\n");
 		sc_access.reg_addr = MICLICTRL1;
 		mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
 		break;
 	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("sst: PMIC_SND_LEFT_PB_VOL\n");
+		pr_debug("PMIC_SND_LEFT_PB_VOL\n");
 		sc_access.reg_addr = AUD16;
 		mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
 		break;
 	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("sst: PMIC_SND_RT_PB_VOL\n");
+		pr_debug("PMIC_SND_RT_PB_VOL\n");
 		sc_access.reg_addr = AUD17;
 		mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
 		break;
@@ -745,9 +747,9 @@
 	}
 
 	retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	pr_debug("sst: value read = 0x%x\n", sc_access.value);
+	pr_debug("value read = 0x%x\n", sc_access.value);
 	*value = (int) (sc_access.value & mask);
-	pr_debug("sst: value returned = 0x%x\n", *value);
+	pr_debug("value returned = 0x%x\n", *value);
 	return retval;
 }
 
diff --git a/drivers/staging/intel_sst/intelmid_v1_control.c b/drivers/staging/intel_sst/intelmid_v1_control.c
index 9de86b2..62a932b 100644
--- a/drivers/staging/intel_sst/intelmid_v1_control.c
+++ b/drivers/staging/intel_sst/intelmid_v1_control.c
@@ -25,6 +25,8 @@
  *  This file contains the control operations of vendor 2
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/file.h>
 #include <asm/mrst.h>
@@ -150,11 +152,11 @@
 	retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 8);
 	if (0 != retval) {
 		/* pmic communication fails */
-		pr_debug("sst: pmic commn failed\n");
+		pr_debug("pmic commn failed\n");
 		return retval;
 	}
 
-	pr_debug("sst: Capture configuration complete!!\n");
+	pr_debug("Capture configuration complete!!\n");
 	return 0;
 }
 
@@ -174,11 +176,11 @@
 	retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 9);
 	if (0 != retval) {
 		/* pmic communication fails */
-		pr_debug("sst: pmic commn failed\n");
+		pr_debug("pmic commn failed\n");
 		return retval;
 	}
 
-	pr_debug("sst: Playback configuration complete!!\n");
+	pr_debug("Playback configuration complete!!\n");
 	return 0;
 }
 
@@ -204,7 +206,7 @@
 	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 	if (retval)
 		return retval;
-	pr_debug("sst: mute status = %d", snd_pmic_ops_mx.mute_status);
+	pr_debug("mute status = %d\n", snd_pmic_ops_mx.mute_status);
 	if (snd_pmic_ops_mx.mute_status == MUTE ||
 				snd_pmic_ops_mx.master_mute == MUTE)
 		return retval;
@@ -412,7 +414,7 @@
 		if (retval)
 			return retval;
 	}
-	pr_debug("sst: SST DBG mx_set_pcm_voice_params called\n");
+	pr_debug("SST DBG:mx_set_pcm_voice_params called\n");
 	return sst_sc_reg_access(sc_access, PMIC_WRITE, 44);
 }
 
@@ -529,7 +531,7 @@
 			return retval;
 	}
 
-	pr_debug("sst: mx_set_selected_output_dev dev_id:0x%x\n", dev_id);
+	pr_debug("mx_set_selected_output_dev dev_id:0x%x\n", dev_id);
 	snd_pmic_ops_mx.output_dev_id = dev_id;
 	switch (dev_id) {
 	case STEREO_HEADPHONE:
@@ -549,7 +551,7 @@
 		num_reg = 1;
 		break;
 	case RECEIVER:
-		pr_debug("sst: RECEIVER Koski selected\n");
+		pr_debug("RECEIVER Koski selected\n");
 
 		/* configuration - AS enable, receiver enable */
 		sc_access[0].reg_addr = 0xFF;
@@ -559,7 +561,7 @@
 		num_reg = 1;
 		break;
 	default:
-		pr_err("sst: Not a valid output dev\n");
+		pr_err("Not a valid output dev\n");
 		return 0;
 	}
 	return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
@@ -598,7 +600,7 @@
 			return retval;
 	}
 	snd_pmic_ops_mx.input_dev_id = dev_id;
-	pr_debug("sst: mx_set_selected_input_dev dev_id:0x%x\n", dev_id);
+	pr_debug("mx_set_selected_input_dev dev_id:0x%x\n", dev_id);
 
 	switch (dev_id) {
 	case AMIC:
@@ -646,7 +648,7 @@
 	}
 
 
-	pr_debug("sst: set_mute dev_id:0x%x , value:%d\n", dev_id, value);
+	pr_debug("set_mute dev_id:0x%x , value:%d\n", dev_id, value);
 
 	switch (dev_id) {
 	case PMIC_SND_DMIC_MUTE:
@@ -760,7 +762,7 @@
 		if (retval)
 			return retval;
 	}
-	pr_debug("sst: set_vol dev_id:0x%x ,value:%d\n", dev_id, value);
+	pr_debug("set_vol dev_id:0x%x ,value:%d\n", dev_id, value);
 	switch (dev_id) {
 	case PMIC_SND_RECEIVER_VOL:
 		return 0;
@@ -875,7 +877,7 @@
 	if (retval)
 		return retval;
 	*value = -(sc_access.value & mask);
-	pr_debug("sst: get volume value extracted %d\n", *value);
+	pr_debug("get volume value extracted %d\n", *value);
 	return retval;
 }
 
diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c
index 3a7de76..81cb9d7 100644
--- a/drivers/staging/intel_sst/intelmid_v2_control.c
+++ b/drivers/staging/intel_sst/intelmid_v2_control.c
@@ -26,6 +26,8 @@
  *  This file contains the control operations of vendor 3
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci.h>
 #include <linux/file.h>
 #include "intel_sst.h"
@@ -120,7 +122,7 @@
 	snd_pmic_ops_nc.master_mute = UNMUTE;
 	snd_pmic_ops_nc.mute_status = UNMUTE;
 	sst_sc_reg_access(sc_access, PMIC_WRITE, 26);
-	pr_debug("sst: init complete!!\n");
+	pr_debug("init complete!!\n");
 	return 0;
 }
 
@@ -169,7 +171,7 @@
 	nc_enable_audiodac(MUTE);
 	msleep(30);
 
-	pr_debug("sst: powering up pb....\n");
+	pr_debug("powering up pb....\n");
 
 	sc_access[0].reg_addr = VAUDIOCNT;
 	sc_access[0].value = 0x27;
@@ -222,7 +224,7 @@
 		return retval;
 
 
-	pr_debug("sst: powering up cp....\n");
+	pr_debug("powering up cp....\n");
 
 	if (port == 0xFF)
 		return 0;
@@ -275,7 +277,7 @@
 	nc_enable_audiodac(MUTE);
 
 
-	pr_debug("sst: powering dn nc_power_down ....\n");
+	pr_debug("powering dn nc_power_down ....\n");
 
 	msleep(30);
 
@@ -324,7 +326,7 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: powering dn pb....\n");
+	pr_debug("powering dn pb....\n");
 
 	nc_enable_audiodac(MUTE);
 
@@ -370,7 +372,7 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: powering dn cp....\n");
+	pr_debug("powering dn cp....\n");
 	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 }
 
@@ -400,7 +402,7 @@
 		return retval;
 
 	sst_sc_reg_access(sc_access, PMIC_WRITE, 14);
-	pr_debug("sst: Voice parameters set successfully!!\n");
+	pr_debug("Voice parameters set successfully!!\n");
 	return 0;
 }
 
@@ -451,20 +453,20 @@
 
 		sc_access.value = 0x07;
 		sc_access.reg_addr = RMUTE;
-		pr_debug("sst: RIGHT_HP_MUTE value%d\n", sc_access.value);
+		pr_debug("RIGHT_HP_MUTE value%d\n", sc_access.value);
 		sc_access.mask = MASK2;
 		sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
 	} else {
 		sc_access.value = 0x00;
 		sc_access.reg_addr = RMUTE;
-		pr_debug("sst: RIGHT_HP_MUTE value %d\n", sc_access.value);
+		pr_debug("RIGHT_HP_MUTE value %d\n", sc_access.value);
 		sc_access.mask = MASK2;
 		sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
 
 
 	}
 
-	pr_debug("sst: word_size = %d\n", word_size);
+	pr_debug("word_size = %d\n", word_size);
 
 	if (word_size == 24) {
 		sc_access.reg_addr = AUDIOPORT2;
@@ -477,7 +479,7 @@
 	}
 	sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
 
-	pr_debug("sst: word_size = %d\n", word_size);
+	pr_debug("word_size = %d\n", word_size);
 	sc_access.reg_addr = AUDIOPORT1;
 	sc_access.mask = MASK5|MASK4|MASK1|MASK0;
 	if (word_size == 16)
@@ -508,7 +510,7 @@
 		retval = nc_init_card();
 	if (retval)
 		return retval;
-	pr_debug("sst: nc set selected output:%d\n", value);
+	pr_debug("nc set selected output:%d\n", value);
 	switch (value) {
 	case STEREO_HEADPHONE:
 		retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2);
@@ -517,7 +519,7 @@
 		retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2);
 		break;
 	default:
-		pr_err("sst: rcvd illegal request: %d\n", value);
+		pr_err("rcvd illegal request: %d\n", value);
 		return -EINVAL;
 	}
 	return retval;
@@ -541,7 +543,7 @@
 	};
 
 	sst_sc_reg_access(sc_access, PMIC_WRITE, 12);
-	pr_debug("sst: Audio Init successfully!!\n");
+	pr_debug("Audio Init successfully!!\n");
 
 	/*set output device */
 	nc_set_selected_output_dev(snd_pmic_ops_nc.output_dev_id);
@@ -549,13 +551,13 @@
 	if (snd_pmic_ops_nc.num_channel == 1) {
 		sc_acces.value = 0x07;
 		sc_acces.reg_addr = RMUTE;
-		pr_debug("sst: RIGHT_HP_MUTE value%d\n", sc_acces.value);
+		pr_debug("RIGHT_HP_MUTE value%d\n", sc_acces.value);
 		sc_acces.mask = MASK2;
 		sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1);
 	} else {
 		sc_acces.value = 0x00;
 		sc_acces.reg_addr = RMUTE;
-		pr_debug("sst: RIGHT_HP_MUTE value%d\n", sc_acces.value);
+		pr_debug("RIGHT_HP_MUTE value%d\n", sc_acces.value);
 		sc_acces.mask = MASK2;
 		sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1);
 	}
@@ -629,11 +631,11 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: set device id::%d, value %d\n", dev_id, value);
+	pr_debug("set device id::%d, value %d\n", dev_id, value);
 
 	switch (dev_id) {
 	case PMIC_SND_MUTE_ALL:
-		pr_debug("sst: PMIC_SND_MUTE_ALL value %d\n", value);
+		pr_debug("PMIC_SND_MUTE_ALL value %d\n", value);
 		snd_pmic_ops_nc.mute_status = value;
 		snd_pmic_ops_nc.master_mute = value;
 		if (value == UNMUTE) {
@@ -669,7 +671,7 @@
 		}
 		break;
 	case PMIC_SND_HP_MIC_MUTE:
-		pr_debug("sst: PMIC_SND_HPMIC_MUTE value %d\n", value);
+		pr_debug("PMIC_SND_HPMIC_MUTE value %d\n", value);
 		if (value == UNMUTE) {
 			/* unmute the system, set the 6th bit to one */
 			sc_access[0].value = 0x00;
@@ -682,7 +684,7 @@
 		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 		break;
 	case PMIC_SND_AMIC_MUTE:
-		pr_debug("sst: PMIC_SND_AMIC_MUTE value %d\n", value);
+		pr_debug("PMIC_SND_AMIC_MUTE value %d\n", value);
 		if (value == UNMUTE) {
 			/* unmute the system, set the 6th bit to one */
 			sc_access[0].value = 0x00;
@@ -696,7 +698,7 @@
 		break;
 
 	case PMIC_SND_DMIC_MUTE:
-		pr_debug("sst: INPUT_MUTE_DMIC value%d\n", value);
+		pr_debug("INPUT_MUTE_DMIC value%d\n", value);
 		if (value == UNMUTE) {
 			/* unmute the system, set the 6th bit to one */
 			sc_access[1].value = 0x00;
@@ -724,13 +726,13 @@
 
 		if (dev_id == PMIC_SND_LEFT_HP_MUTE) {
 			sc_access[0].reg_addr = LMUTE;
-			pr_debug("sst: LEFT_HP_MUTE value %d\n",
+			pr_debug("LEFT_HP_MUTE value %d\n",
 					sc_access[0].value);
 		} else {
 			if (snd_pmic_ops_nc.num_channel == 1)
 				sc_access[0].value = 0x04;
 			sc_access[0].reg_addr = RMUTE;
-			pr_debug("sst: RIGHT_HP_MUTE value %d\n",
+			pr_debug("RIGHT_HP_MUTE value %d\n",
 					sc_access[0].value);
 		}
 		sc_access[0].mask = MASK2;
@@ -743,7 +745,7 @@
 		else
 			sc_access[0].value = 0x03;
 		sc_access[0].reg_addr = LMUTE;
-		pr_debug("sst: SPEAKER_MUTE %d\n", sc_access[0].value);
+		pr_debug("SPEAKER_MUTE %d\n", sc_access[0].value);
 		sc_access[0].mask = MASK1;
 		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 		break;
@@ -764,10 +766,10 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: set volume:%d\n", dev_id);
+	pr_debug("set volume:%d\n", dev_id);
 	switch (dev_id) {
 	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("sst: PMIC_SND_CAPTURE_VOL:value::%d\n", value);
+		pr_debug("PMIC_SND_CAPTURE_VOL:value::%d\n", value);
 		sc_access[0].value = sc_access[1].value =
 					sc_access[2].value = -value;
 		sc_access[0].mask = sc_access[1].mask = sc_access[2].mask =
@@ -779,7 +781,7 @@
 		break;
 
 	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("sst: PMIC_SND_LEFT_HP_VOL %d\n", value);
+		pr_debug("PMIC_SND_LEFT_HP_VOL %d\n", value);
 		sc_access[0].value = -value;
 		sc_access[0].reg_addr  = AUDIOLVOL;
 		sc_access[0].mask =
@@ -788,7 +790,7 @@
 		break;
 
 	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("sst: PMIC_SND_RIGHT_HP_VOL value %d\n", value);
+		pr_debug("PMIC_SND_RIGHT_HP_VOL value %d\n", value);
 		if (snd_pmic_ops_nc.num_channel == 1) {
 			sc_access[0].value = 0x04;
 		    sc_access[0].reg_addr = RMUTE;
@@ -821,11 +823,11 @@
 		return retval;
 	snd_pmic_ops_nc.input_dev_id = value;
 
-	pr_debug("sst: nc set selected input:%d\n", value);
+	pr_debug("nc set selected input:%d\n", value);
 
 	switch (value) {
 	case AMIC:
-		pr_debug("sst: Selecting AMIC\n");
+		pr_debug("Selecting AMIC\n");
 		sc_access[0].reg_addr = 0x107;
 		sc_access[0].value = 0x40;
 		sc_access[0].mask =  MASK6|MASK4|MASK3|MASK1|MASK0;
@@ -842,7 +844,7 @@
 		break;
 
 	case HS_MIC:
-		pr_debug("sst: Selecting HS_MIC\n");
+		pr_debug("Selecting HS_MIC\n");
 		sc_access[0].reg_addr = 0x107;
 		sc_access[0].mask =  MASK6|MASK4|MASK3|MASK1|MASK0;
 		sc_access[0].value = 0x10;
@@ -859,7 +861,7 @@
 		break;
 
 	case DMIC:
-		pr_debug("sst: DMIC\n");
+		pr_debug("DMIC\n");
 		sc_access[0].reg_addr = 0x107;
 		sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0;
 		sc_access[0].value = 0x0B;
@@ -890,23 +892,23 @@
 	if (retval)
 		return retval;
 
-	pr_debug("sst: get mute::%d\n", dev_id);
+	pr_debug("get mute::%d\n", dev_id);
 
 	switch (dev_id) {
 	case PMIC_SND_AMIC_MUTE:
-		pr_debug("sst: PMIC_SND_INPUT_MUTE_MIC1\n");
+		pr_debug("PMIC_SND_INPUT_MUTE_MIC1\n");
 		sc_access.reg_addr = LILSEL;
 		mask = MASK6;
 		break;
 	case PMIC_SND_HP_MIC_MUTE:
-		pr_debug("sst: PMIC_SND_INPUT_MUTE_MIC2\n");
+		pr_debug("PMIC_SND_INPUT_MUTE_MIC2\n");
 		sc_access.reg_addr = LIRSEL;
 		mask = MASK6;
 		break;
 	case PMIC_SND_LEFT_HP_MUTE:
 	case PMIC_SND_RIGHT_HP_MUTE:
 		mask = MASK2;
-		pr_debug("sst: PMIC_SN_LEFT/RIGHT_HP_MUTE\n");
+		pr_debug("PMIC_SN_LEFT/RIGHT_HP_MUTE\n");
 		if (dev_id == PMIC_SND_RIGHT_HP_MUTE)
 			sc_access.reg_addr = RMUTE;
 		else
@@ -914,12 +916,12 @@
 		break;
 
 	case PMIC_SND_LEFT_SPEAKER_MUTE:
-		pr_debug("sst: PMIC_MONO_EARPIECE_MUTE\n");
+		pr_debug("PMIC_MONO_EARPIECE_MUTE\n");
 		sc_access.reg_addr = RMUTE;
 		mask = MASK1;
 		break;
 	case PMIC_SND_DMIC_MUTE:
-		pr_debug("sst: PMIC_SND_INPUT_MUTE_DMIC\n");
+		pr_debug("PMIC_SND_INPUT_MUTE_DMIC\n");
 		sc_access.reg_addr = 0x105;
 		mask = MASK6;
 		break;
@@ -928,16 +930,16 @@
 
 	}
 	retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	pr_debug("sst: reg value = %d\n", sc_access.value);
+	pr_debug("reg value = %d\n", sc_access.value);
 	if (retval)
 		return retval;
 	*value = (sc_access.value) & mask;
-	pr_debug("sst: masked value = %d\n", *value);
+	pr_debug("masked value = %d\n", *value);
 	if (*value)
 		*value = 0;
 	else
 		*value = 1;
-	pr_debug("sst: value returned = 0x%x\n", *value);
+	pr_debug("value returned = 0x%x\n", *value);
 	return retval;
 }
 
@@ -953,19 +955,19 @@
 
 	switch (dev_id) {
 	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("sst: PMIC_SND_INPUT_CAPTURE_VOL\n");
+		pr_debug("PMIC_SND_INPUT_CAPTURE_VOL\n");
 		sc_access.reg_addr =  LILSEL;
 		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
 		break;
 
 	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("sst: GET_VOLUME_PMIC_LEFT_HP_VOL\n");
+		pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n");
 		sc_access.reg_addr = AUDIOLVOL;
 		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
 		break;
 
 	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("sst: GET_VOLUME_PMIC_RIGHT_HP_VOL\n");
+		pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n");
 		sc_access.reg_addr = AUDIORVOL;
 		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
 		break;
@@ -975,9 +977,9 @@
 
 	}
 	retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	pr_debug("sst: value read = 0x%x\n", sc_access.value);
+	pr_debug("value read = 0x%x\n", sc_access.value);
 	*value = -((sc_access.value) & mask);
-	pr_debug("sst: get vol value returned = %d\n", *value);
+	pr_debug("get vol value returned = %d\n", *value);
 	return retval;
 }
 
diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c
index 9a3fdb4..452ea8f 100644
--- a/drivers/staging/keucr/ms.c
+++ b/drivers/staging/keucr/ms.c
@@ -347,7 +347,7 @@
 	BYTE                     *PageBuffer;
 	MS_LibTypeExtdat         ExtraData;
 
-	if ((PageBuffer = (BYTE *)kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL)
+	if ((PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL)
 		return (DWORD)-1;
 
 	result = (DWORD)-1;
@@ -480,8 +480,8 @@
 	DWORD  i;
 
 
-	us->MS_Lib.Phy2LogMap = (WORD *)kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL);
-	us->MS_Lib.Log2PhyMap = (WORD *)kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL);
+	us->MS_Lib.Phy2LogMap = kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL);
+	us->MS_Lib.Log2PhyMap = kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL);
 
 	if ((us->MS_Lib.Phy2LogMap == NULL) || (us->MS_Lib.Log2PhyMap == NULL))
 	{
@@ -610,8 +610,8 @@
 {
 	us->MS_Lib.wrtblk = (WORD)-1;
 
-	us->MS_Lib.blkpag = (BYTE *)kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL);
-	us->MS_Lib.blkext = (MS_LibTypeExtdat *)kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL);
+	us->MS_Lib.blkpag = kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL);
+	us->MS_Lib.blkext = kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL);
 
 	if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL))
 	{
diff --git a/drivers/staging/msm/Makefile b/drivers/staging/msm/Makefile
index bb3606f..07a89ec 100644
--- a/drivers/staging/msm/Makefile
+++ b/drivers/staging/msm/Makefile
@@ -41,11 +41,11 @@
 obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
 
 # MDDI
-msm_mddi-objs := mddi.o mddihost.o mddihosti.o
+msm_mddi-y := mddi.o mddihost.o mddihosti.o
 obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
 
 # External MDDI
-msm_mddi_ext-objs := mddihost_e.o mddi_ext.o
+msm_mddi_ext-y := mddihost_e.o mddi_ext.o
 obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o
 
 # TVEnc
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
index 2fdb3e0..6540864 100644
--- a/drivers/staging/pohmelfs/crypto.c
+++ b/drivers/staging/pohmelfs/crypto.c
@@ -130,10 +130,8 @@
 
 void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e)
 {
-	if (e->hash)
-		crypto_free_hash(e->hash);
-	if (e->cipher)
-		crypto_free_ablkcipher(e->cipher);
+	crypto_free_hash(e->hash);
+	crypto_free_ablkcipher(e->cipher);
 	kfree(e->data);
 }
 
diff --git a/drivers/staging/rt2860/chip/mac_pci.h b/drivers/staging/rt2860/chip/mac_pci.h
index 9f25ef0..b8868a5 100644
--- a/drivers/staging/rt2860/chip/mac_pci.h
+++ b/drivers/staging/rt2860/chip/mac_pci.h
@@ -30,7 +30,8 @@
     Abstract:
 
     Revision History:
-    Who          When          What
+    Who          	When            What
+    Justin P. Mattock	11/07/2010	Fix some typos
     ---------    ----------    ----------------------------------------------
  */
 
@@ -45,7 +46,7 @@
 
 /* */
 /* Device ID & Vendor ID related definitions, */
-/* NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip. */
+/* NOTE: you should not add the new VendorID/DeviceID here unless you know for sure what chip it belongs too. */
 /* */
 #define NIC_PCI_VENDOR_ID		0x1814
 #define PCIBUS_INTEL_VENDOR	0x8086
@@ -83,7 +84,7 @@
 	u32 SDPtr1;
 	/*Word3 */
 	u32 rsv2:24;
-	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition */
+	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correct position */
 	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
 	u32 rsv:2;
 	u32 TCO:1;		/* */
diff --git a/drivers/staging/rt2860/chip/mac_usb.h b/drivers/staging/rt2860/chip/mac_usb.h
index ed0c0b4..e8158fb5 100644
--- a/drivers/staging/rt2860/chip/mac_usb.h
+++ b/drivers/staging/rt2860/chip/mac_usb.h
@@ -30,7 +30,8 @@
     Abstract:
 
     Revision History:
-    Who          When          What
+    Who          	When            What
+    Justin P. Mattock	11/07/2010	Fix a typo
     ---------    ----------    ----------------------------------------------
  */
 
@@ -93,7 +94,7 @@
 	/* Word 0 */
 	u32 USBDMATxPktLen:16;	/*used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame. */
 	u32 rsv:8;
-	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition */
+	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correct position */
 	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
 	u32 SwUseLastRound:1;	/* Software use. */
 	u32 rsv2:2;		/* Software use. */
diff --git a/drivers/staging/rt2860/chip/rtmp_mac.h b/drivers/staging/rt2860/chip/rtmp_mac.h
index e8f7172..3d1e491 100644
--- a/drivers/staging/rt2860/chip/rtmp_mac.h
+++ b/drivers/staging/rt2860/chip/rtmp_mac.h
@@ -32,6 +32,7 @@
 
 	Revision History:
 	Who			When		  What
+	Justin P. Mattock	11/07/2010	  Fix a comments, and typos
 	--------	----------	  ----------------------------------------------
 */
 
@@ -43,7 +44,7 @@
 /* ================================================================================= */
 
 /* the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. */
-/* MAC block use this TXINFO to control the transmission behavior of this frame. */
+/* MAC block uses this TXINFO to control the transmission behavior of this frame. */
 #define FIFO_MGMT                 0
 #define FIFO_HCCA                 1
 #define FIFO_EDCA                 2
@@ -458,8 +459,8 @@
 /* */
 typedef union _RF_CSR_CFG0_STRUC {
 	struct {
-		u32 RegIdAndContent:24;	/* Register     value to program into BBP */
-		u32 bitwidth:5;	/* Selected     BBP     register */
+		u32 RegIdAndContent:24;	/* Register value to program into BBP */
+		u32 bitwidth:5;	/* Selected BBP register */
 		u32 StandbyMode:1;	/* 0: high when stand by 1: low when standby */
 		u32 Sel:1;	/* 0:RF_LE0 activate  1:RF_LE1 activate */
 		u32 Busy:1;	/* 0: idle 1: 8busy */
@@ -469,7 +470,7 @@
 #define RF_CSR_CFG1			0x1024
 typedef union _RF_CSR_CFG1_STRUC {
 	struct {
-		u32 RegIdAndContent:24;	/* Register     value to program into BBP */
+		u32 RegIdAndContent:24;	/* Register value to program into BBP */
 		u32 RFGap:5;	/* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */
 		u32 rsv:7;	/* 0: idle 1: 8busy */
 	} field;
@@ -478,7 +479,7 @@
 #define RF_CSR_CFG2			0x1028	/* */
 typedef union _RF_CSR_CFG2_STRUC {
 	struct {
-		u32 RegIdAndContent:24;	/* Register     value to program into BBP */
+		u32 RegIdAndContent:24;	/* Register value to program into BBP */
 		u32 rsv:8;	/* 0: idle 1: 8busy */
 	} field;
 	u32 word;
@@ -490,7 +491,7 @@
 		u32 OffPeriod:8;	/* blinking off period unit 1ms */
 		u32 SlowBlinkPeriod:6;	/* slow blinking period. unit:1ms */
 		u32 rsv:2;
-		u32 RLedMode:2;	/* red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on */
+		u32 RLedMode:2;	/* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */
 		u32 GLedMode:2;	/* green Led Mode */
 		u32 YLedMode:2;	/* yellow Led Mode */
 		u32 LedPolar:1;	/* Led Polarity.  0: active low1: active high */
@@ -621,9 +622,9 @@
 #define TX_RTY_CFG	0x134c
 typedef union PACKED _TX_RTY_CFG_STRUC {
 	struct {
-		u32 ShortRtyLimit:8;	/*  short retry limit */
-		u32 LongRtyLimit:8;	/*long retry limit */
-		u32 LongRtyThre:12;	/* Long retry threshoold */
+		u32 ShortRtyLimit:8;	/* short retry limit */
+		u32 LongRtyLimit:8;	/* long retry limit */
+		u32 LongRtyThre:12;	/* Long retry threshold */
 		u32 NonAggRtyMode:1;	/* Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer */
 		u32 AggRtyMode:1;	/* Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer */
 		u32 TxautoFBEnable:1;	/* Tx retry PHY rate auto fallback enable */
diff --git a/drivers/staging/rt2860/chips/rt3090.c b/drivers/staging/rt2860/chips/rt3090.c
index c2933c6..156eb36 100644
--- a/drivers/staging/rt2860/chips/rt3090.c
+++ b/drivers/staging/rt2860/chips/rt3090.c
@@ -28,10 +28,11 @@
 	rt3090.c
 
 	Abstract:
-	Specific funcitons and variables for RT3070
+	Specific functions and variables for RT3070
 
 	Revision History:
-	Who         When          What
+	Who         		When            What
+	Justin P. Mattock	11/07/2010	Fix a typo
 	--------    ----------    ----------------------------------------------
 */
 
diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c
index 4367a19..c8f7282 100644
--- a/drivers/staging/rt2860/chips/rt30xx.c
+++ b/drivers/staging/rt2860/chips/rt30xx.c
@@ -28,10 +28,11 @@
 	rt30xx.c
 
 	Abstract:
-	Specific funcitons and variables for RT30xx.
+	Specific functions and variables for RT30xx.
 
 	Revision History:
-	Who         When          What
+	Who         		When            What
+	Justin P. Mattock	11/07/2010	Fix some typos
 	--------    ----------    ----------------------------------------------
 */
 
@@ -89,7 +90,7 @@
 
 u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair));
 
-/* Antenna divesity use GPIO3 and EESK pin for control */
+/* Antenna diversity use GPIO3 and EESK pin for control */
 /* Antenna and EEPROM access are both using EESK pin, */
 /* Therefor we should avoid accessing EESK at the same time */
 /* Then restore antenna after EEPROM access */
@@ -243,7 +244,7 @@
 				break;
 			}
 
-			/* prevent infinite loop cause driver hang. */
+			/* prevent infinite loop; causes driver hang. */
 			if (loopcnt++ > 100) {
 				DBGPRINT(RT_DEBUG_ERROR,
 					 ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating",
diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
index 8eef82d..ed8854b 100644
--- a/drivers/staging/rt2860/common/ba_action.c
+++ b/drivers/staging/rt2860/common/ba_action.c
@@ -799,8 +799,8 @@
 			/* force send specified TID DelBA */
 			struct rt_mlme_delba_req DelbaReq;
 			struct rt_mlme_queue_elem *Elem =
-			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
-							MEM_ALLOC_FLAG);
+				kmalloc(sizeof(struct rt_mlme_queue_elem),
+					MEM_ALLOC_FLAG);
 			if (Elem != NULL) {
 				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
@@ -839,8 +839,8 @@
 	    && (pBAEntry->ORI_BA_Status == Originator_Done)) {
 		struct rt_mlme_delba_req DelbaReq;
 		struct rt_mlme_queue_elem *Elem =
-		    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
-						MEM_ALLOC_FLAG);
+			kmalloc(sizeof(struct rt_mlme_queue_elem),
+				MEM_ALLOC_FLAG);
 		if (Elem != NULL) {
 			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 			NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
@@ -908,8 +908,8 @@
 		/* */
 		if (bPassive == FALSE) {
 			struct rt_mlme_queue_elem *Elem =
-			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
-							MEM_ALLOC_FLAG);
+				kmalloc(sizeof(struct rt_mlme_queue_elem),
+					MEM_ALLOC_FLAG);
 			if (Elem != NULL) {
 				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
diff --git a/drivers/staging/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h
index 01414c3..cd1ee3d 100644
--- a/drivers/staging/rt2860/mlme.h
+++ b/drivers/staging/rt2860/mlme.h
@@ -32,8 +32,9 @@
 	Revision History:
 	Who			When			What
 	--------	----------		------------------------------
-	John Chang	2003-08-28		Created
-	John Chang  2004-09-06      modified for RT2600
+	John Chang		2003-08-28		Created
+	John Chang  		2004-09-06      	modified for RT2600
+	Justin P. Mattock	11/07/2010		Fix typos in comments
 
 */
 #ifndef __MLME_H__
@@ -41,7 +42,7 @@
 
 #include "rtmp_dot11.h"
 
-/* maximum supported capability information - */
+/* maximum supported capability information */
 /* ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot */
 #define SUPPORTED_CAPABILITY_INFO   0x0533
 
@@ -77,7 +78,7 @@
 #define CW_MAX_IN_BITS              10	/* actual CwMax = 2^CW_MAX_IN_BITS - 1 */
 
 /* Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). */
-/* SHould not refer to this constant anymore */
+/* Should not refer to this constant anymore */
 /*#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm */
 #define RSSI_FOR_MID_TX_POWER       -55	/* -55 db is considered mid-distance */
 #define RSSI_FOR_LOW_TX_POWER       -45	/* -45 db is considered very short distance and */
@@ -123,7 +124,7 @@
 #define TID_MAC_HASH_INDEX(Addr, TID)      (TID_MAC_HASH(Addr, TID) % HASH_TABLE_SIZE)
 
 /* LED Control */
-/* assoiation ON. one LED ON. another blinking when TX, OFF when idle */
+/* association ON. one LED ON. another blinking when TX, OFF when idle */
 /* no association, both LED off */
 #define ASIC_LED_ACT_ON(pAd)        RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
 #define ASIC_LED_ACT_OFF(pAd)       RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
@@ -284,8 +285,8 @@
 
 /* 802.11n draft3 related structure definitions. */
 /* 7.3.2.60 */
-#define dot11OBSSScanPassiveDwell							20	/* in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan. */
-#define dot11OBSSScanActiveDwell							10	/* in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan. */
+#define dot11OBSSScanPassiveDwell							20	/* in TU. min amount of time that the STA continuously scans each channel when performing an active OBSS scan. */
+#define dot11OBSSScanActiveDwell							10	/* in TU.min amount of time that the STA continuously scans each channel when performing an passive OBSS scan. */
 #define dot11BSSWidthTriggerScanInterval					300	/* in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. */
 #define dot11OBSSScanPassiveTotalPerChannel					200	/* in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. */
 #define dot11OBSSScanActiveTotalPerChannel					20	/*in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan */
@@ -325,7 +326,7 @@
 };
 
 /* 20/40 trigger event table */
-/* If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP. */
+/* If one Event (A) is deleted or created, or if Event (B) is detected or not detected, STA should send 2040BSSCoexistence to AP. */
 #define MAX_TRIGGER_EVENT		64
 struct rt_trigger_event_tab {
 	u8 EventANo;
@@ -357,14 +358,14 @@
 	u8 ChList[0];
 };
 
-/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */
+/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */
 struct PACKED rt_cha_switch_announce_ie {
 	u8 SwitchMode;	/*channel switch mode */
 	u8 NewChannel;	/* */
 	u8 SwitchCount;	/* */
 };
 
-/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */
+/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */
 struct PACKED rt_sec_cha_offset_ie {
 	u8 SecondaryChannelOffset;	/* 1: Secondary above, 3: Secondary below, 0: no Secondary */
 };
@@ -377,7 +378,7 @@
 	u8 MCSSet[16];
 };
 
-/*This structure substracts ralink supports from all 802.11n-related features. */
+/*This structure subtracts ralink supports from all 802.11n-related features. */
 /*Features not listed here but contained in 802.11n spec are not supported in rt2860. */
 struct rt_ht_capability {
 	u16 ChannelWidth:1;
@@ -387,14 +388,14 @@
 	u16 ShortGIfor40:1;	/*for40MHz */
 	u16 TxSTBC:1;
 	u16 RxSTBC:2;	/* 2 bits */
-	u16 AmsduEnable:1;	/* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n */
+	u16 AmsduEnable:1;	/* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benefit of 802.11n */
 	u16 AmsduSize:1;	/* Max receiving A-MSDU size */
 	u16 rsv:5;
 
 	/*Substract from Addiont HT INFO IE */
 	u8 MaxRAmpduFactor:2;
 	u8 MpduDensity:3;
-	u8 ExtChanOffset:2;	/* Please not the difference with following     u8   NewExtChannelOffset; from 802.11n */
+	u8 ExtChanOffset:2;	/* Please note the difference with following     u8   NewExtChannelOffset; from 802.11n */
 	u8 RecomWidth:1;
 
 	u16 OperaionMode:2;
@@ -481,7 +482,7 @@
 	u16 AMSDUSupported:1;	/* 0: not permitted             1: permitted */
 	u16 BAPolicy:1;	/* 1: immediately BA    0:delayed BA */
 	u16 TID:4;		/* value of TC os TS */
-	u16 BufSize:10;	/* number of buffe of size 2304 octetsr */
+	u16 BufSize:10;	/* number of buffer of size 2304 octetsr */
 };
 
 /* 2-byte BA Starting Seq CONTROL field */
@@ -551,7 +552,7 @@
 	BASEQ_CONTROL BAStartingSeq;
 };
 
-/* Compressed format is mandantory in HT STA */
+/* Compressed format is mandatory in HT STA */
 struct PACKED rt_frame_mtba {
 	struct rt_frame_control FC;
 	u16 Duration;
@@ -647,7 +648,7 @@
 	u8 bitmask[8];
 };
 
-/* Radio Measuement Request Frame Format */
+/* Radio Measurement Request Frame Format */
 struct PACKED rt_frame_rm_req_action {
 	struct rt_header_802_11 Hdr;
 	u8 Category;
@@ -709,7 +710,7 @@
 	u8 Cwmin[4];
 	u8 Cwmax[4];
 	u16 Txop[4];		/* in unit of 32-us */
-	BOOLEAN bACM[4];	/* 1: Admission Control of AC_BK is mandattory */
+	BOOLEAN bACM[4];	/* 1: Admission Control of AC_BK is mandatory */
 };
 
 /* QBSS LOAD information from QAP's BEACON/ProbeRsp */
@@ -757,7 +758,7 @@
 struct rt_bss_entry {
 	u8 Bssid[MAC_ADDR_LEN];
 	u8 Channel;
-	u8 CentralChannel;	/*Store the wide-band central channel for 40MHz.  .used in 40MHz AP. Or this is the same as Channel. */
+	u8 CentralChannel;	/*Store the wide-band central channel for 40MHz. used in 40MHz AP. Or this is the same as Channel. */
 	u8 BssType;
 	u16 AtimWin;
 	u16 BeaconPeriod;
@@ -855,7 +856,7 @@
 	STATE_MACHINE_FUNC *TransFunc;
 };
 
-/* MLME AUX data structure that hold temporarliy settings during a connection attempt. */
+/* MLME AUX data structure that holds temporarliy settings during a connection attempt. */
 /* Once this attemp succeeds, all settings will be copy to pAd->StaActive. */
 /* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */
 /* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */
@@ -996,7 +997,7 @@
 #define MAC_TABLE_ASSOC_TIMEOUT			5	/* unit: sec */
 #define MAC_TABLE_FULL(Tab)				((Tab).size == MAX_LEN_OF_MAC_TABLE)
 
-/* AP shall drop the sta if contine Tx fail count reach it. */
+/* AP shall drop the sta if continue Tx fail count reach it. */
 #define MAC_ENTRY_LIFE_CHECK_CNT		20	/* packet cnt. */
 
 /* Value domain of pMacEntry->Sst */
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index 1704c27..eaa3fe0 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -32,7 +32,8 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
+	Name			Date			Modification logs
+	Justin P. Mattock 	11/07/2010	Fix typos in comments
 */
 #ifndef _OID_H_
 #define _OID_H_
@@ -78,7 +79,7 @@
 #define NDIS_802_11_LENGTH_RATES        8
 #define NDIS_802_11_LENGTH_RATES_EX     16
 #define MAC_ADDR_LENGTH                 6
-/*#define MAX_NUM_OF_CHS                                        49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc */
+/*#define MAX_NUM_OF_CHS                                        49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
 #define MAX_NUM_OF_CHS				54	/* 14 channels @2.4G +  12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination */
 #define MAX_NUMBER_OF_EVENT				10	/* entry # in EVENT table */
 #define MAX_NUMBER_OF_MAC				32	/* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */
@@ -610,7 +611,7 @@
 
 struct rt_802_11_event_table {
 	unsigned long Num;
-	unsigned long Rsv;		/* to align Log[] at LARGE_INEGER boundary */
+	unsigned long Rsv;		/* to align Log[] at LARGE_INTEGER boundary */
 	struct rt_802_11_event_log Log[MAX_NUMBER_OF_EVENT];
 };
 
@@ -721,9 +722,9 @@
 #define	AUTH_FAIL				0x4	/* Open authentication fail */
 #define	AUTH_FAIL_KEYS			0x5	/* Shared authentication fail */
 #define	ASSOC_FAIL				0x6	/* Association failed */
-#define	EAP_MIC_FAILURE			0x7	/* Deauthencation because MIC failure */
-#define	EAP_4WAY_TIMEOUT		0x8	/* Deauthencation on 4-way handshake timeout */
-#define	EAP_GROUP_KEY_TIMEOUT	0x9	/* Deauthencation on group key handshake timeout */
+#define	EAP_MIC_FAILURE			0x7	/* Deauthentication because MIC failure */
+#define	EAP_4WAY_TIMEOUT		0x8	/* Deauthentication on 4-way handshake timeout */
+#define	EAP_GROUP_KEY_TIMEOUT	0x9	/* Deauthentication on group key handshake timeout */
 #define	EAP_SUCCESS				0xa	/* EAP succeed */
 #define	DETECT_RADAR_SIGNAL		0xb	/* Radar signal occur in current channel */
 #define EXTRA_INFO_MAX			0xb	/* Indicate Last OID */
diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c
index 321facd..c35c804 100644
--- a/drivers/staging/rt2860/pci_main_dev.c
+++ b/drivers/staging/rt2860/pci_main_dev.c
@@ -31,7 +31,8 @@
     Create and register network interface for PCI based chipsets in Linux platform.
 
     Revision History:
-    Who         When            What
+    Who         	When            What
+    Justin P. Mattock	11/07/2010	Fix typos in some comments
     --------    ----------      ----------------------------------------------
 */
 
@@ -40,8 +41,8 @@
 #include <linux/slab.h>
 
 /* Following information will be show when you run 'modinfo' */
-/* *** If you have a solution for the bug in current version of driver, please mail to me. */
-/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */
+/* If you have a solution for a bug in current version of driver, please e-mail me. */
+/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. */
 MODULE_AUTHOR("Jett Chen <jett_chen@ralinktech.com>");
 MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver");
 MODULE_LICENSE("GPL");
@@ -599,7 +600,7 @@
 		DBGPRINT_RAW(RT_DEBUG_ERROR,
 			     (" AUX_CTRL = 0x%32x\n", MacValue));
 
-		/* for RT30xx F and after, PCIe infterface, and for power solution 3 */
+		/* for RT30xx F and after, PCIe interface, and for power solution 3 */
 		if ((IS_VERSION_AFTER_F(pAd))
 		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2)
 		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) {
@@ -902,7 +903,7 @@
 				  Configuration);
 		if ((Configuration != 0) && (Configuration != 0xFFFF)) {
 			Configuration &= 0xfefc;
-			/* If call from interface down, restore to orginial setting. */
+			/* If call from interface down, restore to original setting. */
 			if (Level == RESTORE_CLOSE)
 				Configuration |= pAd->HostLnkCtrlConfiguration;
 			else
@@ -924,7 +925,7 @@
 				  Configuration);
 		if ((Configuration != 0) && (Configuration != 0xFFFF)) {
 			Configuration &= 0xfefc;
-			/* If call from interface down, restore to orginial setting. */
+			/* If call from interface down, restore to original setting. */
 			if (Level == RESTORE_CLOSE)
 				Configuration |= pAd->RLnkCtrlConfiguration;
 			else
@@ -1106,12 +1107,12 @@
 		if (pos != 0)
 			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
 
-		/* If configurared to turn on L1. */
+		/* If configured to turn on L1. */
 		HostConfiguration = 0;
 		if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) {
 			DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM\n"));
 
-			/* Skip non-exist deice right away */
+			/* Skip non-exist device right away */
 			if ((pAd->HostLnkCtrlOffset != 0)) {
 				PCI_REG_READ_WORD(pObj->parent_pci_dev,
 						  pAd->HostLnkCtrlOffset,
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index abfeea1..e680b0d 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -767,13 +767,13 @@
 		/* QOS */
 		if (pRxBlk->pHeader->FC.SubType & 0x08) {
 			header_len += 2;
-			/* Data skip QOS contorl field */
+			/* Data skip QOS control field */
 			pRxBlk->DataSize -= 2;
 		}
 		/* Order bit: A-Ralink or HTC+ */
 		if (pRxBlk->pHeader->FC.Order) {
 			header_len += 4;
-			/* Data skip HTC contorl field */
+			/* Data skip HTC control field */
 			pRxBlk->DataSize -= 4;
 		}
 		/* Copy Header */
@@ -1175,7 +1175,7 @@
 	net_dev = pNetDev;
 	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
-	/* work-around for the SuSE due to it has it's own interface name management system. */
+	/* work-around for SuSE, due to them having their own interface name management system. */
 	{
 		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
 		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
@@ -1300,7 +1300,7 @@
 	int ret, rtnl_locked = FALSE;
 
 	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
-	/* If we need hook some callback function to the net device structrue, now do it. */
+	/* If we need hook some callback function to the net device structure, now do it. */
 	if (pDevOpHook) {
 		struct rt_rtmp_adapter *pAd = NULL;
 
@@ -1351,10 +1351,10 @@
 		return NULL;
 	}
 
-	/* find a available interface name, max 32 interfaces */
+	/* find an available interface name, max 32 interfaces */
 	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
 	if (status != NDIS_STATUS_SUCCESS) {
-		/* error! no any available ra name can be used! */
+		/* error! no available ra name can be used! */
 		DBGPRINT(RT_DEBUG_ERROR,
 			 ("Assign interface name (%s with suffix 0~32) failed...\n",
 			  pNamePrefix));
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index 5acedf1..a449b0b 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -30,7 +30,8 @@
     Abstract:
 
     Revision History:
-    Who          When          What
+    Who          	When         	What
+    Justin P. Mattock	11/07/2010 	Fix typo in a comment
     ---------    ----------    ----------------------------------------------
 */
 
@@ -726,7 +727,7 @@
 #define RTMP_GET_PACKET_MOREDATA(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
 
 /* */
-/*      Sepcific Pakcet Type definition */
+/*      Specific Packet Type definition */
 /* */
 #define RTMP_PACKET_SPECIFIC_CB_OFFSET	11
 
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index ad60cea..e864821 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -31,7 +31,8 @@
     Create and register network interface.
 
     Revision History:
-    Who         When            What
+    Who         	When            What
+    Justin P. Mattock	11/07/2010	Fix typos in comments
     --------    ----------      ----------------------------------------------
 */
 
@@ -101,8 +102,8 @@
 		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
 			struct rt_mlme_disassoc_req DisReq;
 			struct rt_mlme_queue_elem *MsgElem =
-			    (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem),
-							MEM_ALLOC_FLAG);
+				kmalloc(sizeof(struct rt_mlme_queue_elem),
+					MEM_ALLOC_FLAG);
 
 			if (MsgElem) {
 				COPY_MAC_ADDR(DisReq.Addr,
@@ -234,7 +235,7 @@
 		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
 #endif /* RTMP_MAC_PCI // */
 
-		/* If dirver doesn't wake up firmware here, */
+		/* If driver doesn't wake up firmware here, */
 		/* NICLoadFirmware will hang forever when interface is up again. */
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
 			AsicForceWakeup(pAd, TRUE);
@@ -310,8 +311,8 @@
 			RTMP_ASIC_INTERRUPT_DISABLE(pAd);
 		}
 		/* Receive packets to clear DMA index after disable interrupt. */
-		/*RTMPHandleRxDoneInterrupt(pAd); */
-		/* put to radio off to save power when driver unload.  After radiooff, can't write /read register.  So need to finish all */
+		/* RTMPHandleRxDoneInterrupt(pAd); */
+		/* put radio off to save power when driver unloads.  After radiooff, can't write/read register, so need to finish all. */
 		/* register access before Radio off. */
 
 		brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
@@ -724,7 +725,8 @@
 int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
 {
 
-	*ppAd = (void *)vmalloc(sizeof(struct rt_rtmp_adapter));	/*pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
+	*ppAd = vmalloc(sizeof(struct rt_rtmp_adapter));
+	/* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
 
 	if (*ppAd) {
 		NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter));
diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c
index 3004be6..e5fb67c 100644
--- a/drivers/staging/rt2860/rt_pci_rbus.c
+++ b/drivers/staging/rt2860/rt_pci_rbus.c
@@ -31,7 +31,8 @@
     Create and register network interface.
 
     Revision History:
-    Who         When            What
+    Who         	When            What
+    Justin P. Mattock	11/07/2010	Fix a typo
     --------    ----------      ----------------------------------------------
 */
 
@@ -356,7 +357,7 @@
 
 	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
 
-	/* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any */
+	/* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, without any */
 	/* bug report output */
 	RTMP_INT_LOCK(&pAd->irq_lock, flags);
 	/*
@@ -787,7 +788,7 @@
 }
 
 /*
- * invaild or writeback cache
+ * invalid or writeback cache
  * and convert virtual address to physical address
  */
 dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr,
diff --git a/drivers/staging/rt2860/rt_usb.c b/drivers/staging/rt2860/rt_usb.c
index bcfc0f5..580a20d 100644
--- a/drivers/staging/rt2860/rt_usb.c
+++ b/drivers/staging/rt2860/rt_usb.c
@@ -32,7 +32,8 @@
 	Revision History:
 	Who			When		What
 	--------	----------	----------------------------------------------
-	Name		Date		Modification logs
+	Name			Date		Modification logs
+	Justin P. Mattock	11/07/2010	Fix some typos.
 
 */
 
@@ -279,7 +280,7 @@
 	    && !RTUSB_TEST_BULK_FLAG(pAd,
 				     (fRTUSB_BULK_OUT_DATA_FRAG <<
 				      BulkOutPipeId))) {
-		/* Indicate There is data avaliable */
+		/* Indicate There is data available */
 		RTUSB_SET_BULK_FLAG(pAd,
 				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
 				     BulkOutPipeId));
@@ -335,7 +336,7 @@
 	}
 
 	/* Always call Bulk routine, even reset bulk. */
-	/* The protectioon of rest bulk should be in BulkOut routine */
+	/* The protection of rest bulk should be in BulkOut routine */
 	RTUSBKickBulkOut(pAd);
 }
 
@@ -383,7 +384,7 @@
 	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
 
 	/* Always call Bulk routine, even reset bulk. */
-	/* The protectioon of rest bulk should be in BulkOut routine */
+	/* The protection of rest bulk should be in BulkOut routine */
 	RTUSBKickBulkOut(pAd);
 
 }
@@ -427,7 +428,7 @@
 	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
 
 	/* Always call Bulk routine, even reset bulk. */
-	/* The protectioon of rest bulk should be in BulkOut routine */
+	/* The protection of rest bulk should be in BulkOut routine */
 	RTUSBKickBulkOut(pAd);
 
 }
@@ -575,7 +576,7 @@
 		} else {
 
 			/* Always call Bulk routine, even reset bulk. */
-			/* The protectioon of rest bulk should be in BulkOut routine */
+			/* The protection of rest bulk should be in BulkOut routine */
 			if (pAd->MgmtRing.TxSwFreeIdx <
 			    MGMT_RING_SIZE
 			    /* pMLMEContext->bWaitingBulkOut == TRUE */) {
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index ca54e53..caf4662 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -31,11 +31,12 @@
     Miniport generic portion header file
 
     Revision History:
-    Who         When          What
+    Who         	When          	What
     --------    ----------    ----------------------------------------------
-    Paul Lin    2002-08-01    created
-    James Tan   2002-09-06    modified (Revise NTCRegTable)
-    John Chang  2004-09-06    modified for RT2600
+    Paul Lin    	2002-08-01    	created
+    James Tan   	2002-09-06    	modified (Revise NTCRegTable)
+    John Chang  	2004-09-06    	modified for RT2600
+    Justin P. Mattock	11/07/2010	Fix some typos
 */
 #ifndef __RTMP_H__
 #define __RTMP_H__
@@ -337,7 +338,7 @@
 #define LEAP_ON(_p)                 (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
 #define LEAP_CCKM_ON(_p)            ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
 
-/* if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */
+/* if original Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */
 #define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap)		\
 {																\
 	if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) {	\
@@ -466,7 +467,7 @@
 /* Control block (Descriptor) for all ring descriptor DMA operation, buffer must be */
 /* contiguous physical memory. char stored the binding Rx packet descriptor */
 /* which won't be released, driver has to wait until upper layer return the packet */
-/* before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair */
+/* before giving up this rx ring descriptor to ASIC. NDIS_BUFFER is associated pair */
 /* to describe the packet buffer. For Tx, char stored the tx packet descriptor */
 /* which driver should ACK upper layer when the tx is physically done or failed. */
 /* */
@@ -602,7 +603,7 @@
 };
 
 struct rt_counter_drs {
-	/* to record the each TX rate's quality. 0 is best, the bigger the worse. */
+	/* record each TX rate's quality. 0 is best, the bigger the worse. */
 	u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
 	u8 PER[MAX_STEP_OF_TX_RATE_SWITCH];
 	u8 TxRateUpPenalty;	/* extra # of second penalty due to last unstable condition */
@@ -719,7 +720,7 @@
 /* Packet information for NdisQueryPacket */
 /* */
 struct rt_packet_info {
-	u32 PhysicalBufferCount;	/* Physical breaks of buffer descripor chained */
+	u32 PhysicalBufferCount;	/* Physical breaks of buffer descriptor chained */
 	u32 BufferCount;	/* Number of Buffer descriptor chained */
 	u32 TotalPacketLength;	/* Self explained */
 	char *pFirstBuffer;	/* Pointer to first buffer descriptor */
@@ -846,8 +847,8 @@
 /* Power save method control */
 typedef union _PS_CONTROL {
 	struct {
-		unsigned long EnablePSinIdle:1;	/* Enable radio off when not connect to AP. radio on only when sitesurvey, */
-		unsigned long EnableNewPS:1;	/* Enable new  Chip power save fucntion . New method can only be applied in chip version after 2872. and PCIe. */
+		unsigned long EnablePSinIdle:1;	/* Enable radio off when not connected to AP. radio on only when sitesurvey, */
+		unsigned long EnableNewPS:1;	/* Enable new  Chip power save function . New method can only be applied in chip version after 2872. and PCIe. */
 		unsigned long rt30xxPowerMode:2;	/* Power Level Mode for rt30xx chip */
 		unsigned long rt30xxFollowHostASPM:1;	/* Card Follows Host's setting for rt30xx chip. */
 		unsigned long rt30xxForceASPMTest:1;	/* Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode. */
@@ -1117,8 +1118,8 @@
 	unsigned long TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
 	unsigned long CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
 	BOOLEAN EnableBeacon;	/* trigger to enable beacon transmission. */
-	u8 BeaconBitMap;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */
-	u8 DtimBitOn;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */
+	u8 BeaconBitMap;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */
+	u8 DtimBitOn;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */
 };
 #endif /* RTMP_MAC_USB // */
 
@@ -1211,7 +1212,7 @@
 	/*BOOLEAN               bAutoTxRateSwitch; */
 	u8 MinTxRate;	/* RATE_1, RATE_2, RATE_5_5, RATE_11 */
 	u8 RtsRate;		/* RATE_xxx */
-	HTTRANSMIT_SETTING MlmeTransmit;	/* MGMT frame PHY rate setting when operatin at Ht rate. */
+	HTTRANSMIT_SETTING MlmeTransmit;	/* MGMT frame PHY rate setting when operation at Ht rate. */
 	u8 MlmeRate;		/* RATE_xxx, used to send MLME frames */
 	u8 BasicMlmeRate;	/* Default Rate for sending MLME frames */
 
@@ -1264,7 +1265,7 @@
 	struct rt_ht_capability_ie HtCapability;
 	struct rt_add_ht_info_ie AddHTInfo;	/* Useful as AP. */
 	/*This IE is used with channel switch announcement element when changing to a new 40MHz. */
-	/*This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp. */
+	/*This IE is included in channel switch announcement frames 7.4.1.5, beacons, probe Rsp. */
 	struct rt_new_ext_chan_ie NewExtChanOffset;	/*7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present */
 
 	BOOLEAN bHTProtect;
@@ -1329,7 +1330,7 @@
 	/* GROUP 1 - */
 	/*   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */
 	/*   the user intended configuration, but not necessary fully equal to the final */
-	/*   settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either */
+	/*   settings in ACTIVE BSS after negotiation/compromise with the BSS holder (either */
 	/*   AP or IBSS holder). */
 	/*   Once initialized, user configuration can only be changed via OID_xxx */
 	u8 BssType;		/* BSS_INFRA or BSS_ADHOC */
@@ -1386,12 +1387,12 @@
 
 	/* For WPA countermeasures */
 	unsigned long LastMicErrorTime;	/* record last MIC error time */
-	unsigned long MicErrCnt;	/* Should be 0, 1, 2, then reset to zero (after disassoiciation). */
+	unsigned long MicErrCnt;	/* Should be 0, 1, 2, then reset to zero (after disassociation). */
 	BOOLEAN bBlockAssoc;	/* Block associate attempt for 60 seconds after counter measure occurred. */
 	/* For WPA-PSK supplicant state */
 	WPA_STATE WpaState;	/* Default is SS_NOTUSE and handled by microsoft 802.1x */
 	u8 ReplayCounter[8];
-	u8 ANonce[32];	/* ANonce for WPA-PSK from aurhenticator */
+	u8 ANonce[32];	/* ANonce for WPA-PSK from auhenticator */
 	u8 SNonce[32];	/* SNonce for WPA-PSK */
 
 	u8 LastSNR0;		/* last received BEACON's SNR */
@@ -1423,7 +1424,7 @@
 	u8 RSNIE_Len;
 	u8 RSN_IE[MAX_LEN_OF_RSNIE];	/* The content saved here should be little-endian format. */
 
-	unsigned long CLBusyBytes;	/* Save the total bytes received durning channel load scan time */
+	unsigned long CLBusyBytes;	/* Save the total bytes received during channel load scan time */
 	u16 RPIDensity[8];	/* Array for RPI density collection */
 
 	u8 RMReqCnt;		/* Number of measurement request saved. */
@@ -1489,9 +1490,9 @@
 	BOOLEAN bForceTxBurst;	/* 1: force enble TX PACKET BURST, 0: disable */
 };
 
-/* This data structure keep the current active BSS/IBSS's configuration that this STA */
+/* This data structure keeps the current active BSS/IBSS's configuration that this STA */
 /* had agreed upon joining the network. Which means these parameters are usually decided */
-/* by the BSS/IBSS creator instead of user configuration. Data in this data structurre */
+/* by the BSS/IBSS creator instead of user configuration. Data in this data structure */
 /* is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE. */
 /* Normally, after SCAN or failed roaming attempts, we need to recover back to */
 /* the current active settings. */
@@ -1519,7 +1520,7 @@
 	/*Choose 1 from ValidAsWDS and ValidAsCLI  to validize. */
 	BOOLEAN ValidAsCLI;	/* Sta mode, set this TRUE after Linkup,too. */
 	BOOLEAN ValidAsWDS;	/* This is WDS Entry. only for AP mode. */
-	BOOLEAN ValidAsApCli;	/*This is a AP-Client entry, only for AP mode which enable AP-Client functions. */
+	BOOLEAN ValidAsApCli;	/* This is a AP-Client entry, only for AP mode which enable AP-Client functions. */
 	BOOLEAN ValidAsMesh;
 	BOOLEAN ValidAsDls;	/* This is DLS Entry. only for STA mode. */
 	BOOLEAN isCached;
@@ -1527,7 +1528,7 @@
 
 	u8 EnqueueEapolStartTimerRunning;	/* Enqueue EAPoL-Start for triggering EAP SM */
 	/*jan for wpa */
-	/* record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB */
+	/* record which entry revoke MIC Failure, if it leaves the BSS itself, AP won't update aMICFailTime MIB */
 	u8 CMTimerRunning;
 	u8 apidx;		/* MBSS number */
 	u8 RSNIE_Len;
@@ -1722,7 +1723,7 @@
 	unsigned long Rt3xxRalinkLinkCtrl;	/* USed for 3090F chip */
 	u16 DeviceID;	/* Read from PCI config */
 	unsigned long AccessBBPFailCount;
-	BOOLEAN bPCIclkOff;	/* flag that indicate if the PICE power status in Configuration SPace.. */
+	BOOLEAN bPCIclkOff;	/* flag that indicates if the PICE power status in Configuration Space.. */
 	BOOLEAN bPCIclkOffDisableTx;	/* */
 
 	BOOLEAN brt30xxBanMcuCmd;	/*when = 0xff means all commands are ok to set . */
@@ -1871,9 +1872,9 @@
 	/* ---------------------------- */
 	u8 RfIcType;		/* RFIC_xxx */
 	unsigned long RfFreqOffset;	/* Frequency offset for channel switching */
-	struct rt_rtmp_rf_regs LatchRfRegs;	/* latch th latest RF programming value since RF IC doesn't support READ */
+	struct rt_rtmp_rf_regs LatchRfRegs;	/* latch the latest RF programming value since RF IC doesn't support READ */
 
-	EEPROM_ANTENNA_STRUC Antenna;	/* Since ANtenna definition is different for a & g. We need to save it for future reference. */
+	EEPROM_ANTENNA_STRUC Antenna;	/* Since Antenna definition is different for a & g. We need to save it for future reference. */
 	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
 
 	/* This soft Rx Antenna Diversity mechanism is used only when user set */
@@ -1990,7 +1991,7 @@
 	struct rt_common_config CommonCfg;
 	struct rt_mlme Mlme;
 
-	/* AP needs those vaiables for site survey feature. */
+	/* AP needs those variables for site survey feature. */
 	struct rt_mlme_aux MlmeAux;	/* temporary settings used during MLME state machine */
 	struct rt_bss_table ScanTab;	/* store the latest SCAN result */
 
@@ -2012,7 +2013,7 @@
 	/* various Counters */
 	struct rt_counter_802_3 Counters8023;	/* 802.3 counters */
 	struct rt_counter_802_11 WlanCounters;	/* 802.11 MIB counters */
-	struct rt_counter_ralink RalinkCounters;	/* Ralink propriety counters */
+	struct rt_counter_ralink RalinkCounters;	/* Ralink proprietary counters */
 	struct rt_counter_drs DrsCounters;	/* counters for Dynamic TX Rate Switching */
 	struct rt_private PrivateInfo;	/* Private information & counters */
 
@@ -2024,7 +2025,7 @@
 	u16 Sequence;
 
 	/* Control disconnect / connect event generation */
-	/*+++Didn't used anymore */
+	/*+++Not used anymore */
 	unsigned long LinkDownTime;
 	/*--- */
 	unsigned long LastRxRate;
@@ -2036,7 +2037,7 @@
 	unsigned long ExtraInfo;	/* Extra information for displaying status */
 	unsigned long SystemErrorBitmap;	/* b0: E2PROM version error */
 
-	/*+++Didn't used anymore */
+	/*+++Not used anymore */
 	unsigned long MacIcVersion;	/* MAC/BBP serial interface issue solved after ver.D */
 	/*--- */
 
@@ -2089,7 +2090,7 @@
 	unsigned long BulkOutReq;
 	unsigned long BulkOutComplete;
 	unsigned long BulkOutCompleteOther;
-	unsigned long BulkOutCompleteCancel;	/* seems not use now? */
+	unsigned long BulkOutCompleteCancel;	/* seems not used now? */
 	unsigned long BulkInReq;
 	unsigned long BulkInComplete;
 	unsigned long BulkInCompleteFail;
@@ -2196,9 +2197,9 @@
 struct rt_tx_blk {
 	u8 QueIdx;
 	u8 TxFrameType;	/* Indicate the Transmission type of the all frames in one batch */
-	u8 TotalFrameNum;	/* Total frame number want to send-out in one batch */
+	u8 TotalFrameNum;	/* Total frame number that wants to send-out in one batch */
 	u16 TotalFragNum;	/* Total frame fragments required in one batch */
-	u16 TotalFrameLen;	/* Total length of all frames want to send-out in one batch */
+	u16 TotalFrameLen;	/* Total length of all frames that wants to send-out in one batch */
 
 	struct rt_queue_header TxPacketList;
 	struct rt_mac_table_entry *pMacEntry;	/* NULL: packet with 802.11 RA field is multicast/broadcast address */
@@ -2207,7 +2208,7 @@
 	/* Following structure used for the characteristics of a specific packet. */
 	void *pPacket;
 	u8 *pSrcBufHeader;	/* Reference to the head of sk_buff->data */
-	u8 *pSrcBufData;	/* Reference to the sk_buff->data, will changed depends on hanlding progresss */
+	u8 *pSrcBufData;	/* Reference to the sk_buff->data, will change depending on the handling progresss */
 	u32 SrcBufLen;		/* Length of packet payload which not including Layer 2 header */
 	u8 *pExtraLlcSnapEncap;	/* NULL means no extra LLC/SNAP is required */
 	u8 HeaderBuf[128];	/* TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */
@@ -2219,7 +2220,7 @@
 	u8 apidx;		/* The interface associated to this packet */
 	u8 Wcid;		/* The MAC entry associated to this packet */
 	u8 UserPriority;	/* priority class of packet */
-	u8 FrameGap;		/* what kind of IFS this packet use */
+	u8 FrameGap;		/* what kind of IFS does this packet use */
 	u8 MpduReqNum;	/* number of fragments of this frame */
 	u8 TxRate;		/* TODO: Obsoleted? Should change to MCS? */
 	u8 CipherAlg;	/* cipher alogrithm */
diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
index 9c54bac..6ac617e 100644
--- a/drivers/staging/rt2860/rtmp_def.h
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -31,10 +31,11 @@
     Miniport related definition header
 
     Revision History:
-    Who         When          What
+    Who        	 	When          	What
     --------    ----------    ----------------------------------------------
-    Paul Lin    08-01-2002    created
-    John Chang  08-05-2003    add definition for 11g & other drafts
+    Paul Lin    	08-01-2002    	created
+    John Chang  	08-05-2003    	add definition for 11g & other drafts
+    Justin P. Mattock	11/07/2010	Fix some typos
 */
 #ifndef __RTMP_DEF_H__
 #define __RTMP_DEF_H__
@@ -111,11 +112,11 @@
 	WMM Note: If memory of your system is not much, please reduce the definition;
 	or when you do WMM test, the queue for low priority AC will be full, i.e.
 	TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in
-	WLAN, maybe no any packet buffer can be got in Ethernet driver.
+	WLAN, maybe no packet buffers can get into the Ethernet driver.
 
-	Sometimes no packet buffer can be got in Ethernet driver, the system will
+	Sometimes no packet buffer can be get into the Ethernet driver, the system will
 	send flow control packet to the sender to slow down its sending rate.
-	So no WMM can be saw in the air.
+	So no WMM can be seen in the air.
 */
 
 /*
@@ -125,7 +126,7 @@
 	And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to
 	clConfig.clNum = RX_RING_SIZE * 4;
 */
-/* TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS????? */
+/* TODO: For VxWorks the size is 256. Shall we change the value as 256 for all OS? */
 #define MAX_PACKETS_IN_QUEUE				(512)	/*(512)    // to pass WMM A5-WPAPSK */
 
 #define MAX_PACKETS_IN_MCAST_PS_QUEUE		32
@@ -171,7 +172,7 @@
 #define fRTMP_ADAPTER_SCAN_2040 			0x04000000
 #define	fRTMP_ADAPTER_RADIO_MEASUREMENT		0x08000000
 
-#define fRTMP_ADAPTER_START_UP         		0x10000000	/*Devive already initialized and enabled Tx/Rx. */
+#define fRTMP_ADAPTER_START_UP         		0x10000000	/*Device already initialized and enabled Tx/Rx. */
 #define fRTMP_ADAPTER_MEDIA_STATE_CHANGE    0x20000000
 #define fRTMP_ADAPTER_IDLE_RADIO_OFF        0x40000000
 
@@ -205,8 +206,8 @@
 #define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND          0x00000002
 /* Indicate driver should disable kick off hardware to send packets from now. */
 #define fRTMP_PS_DISABLE_TX         0x00000004
-/* Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which  doesn't indicate unicate nor multicast packets for me */
-/*. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */
+/* Indicate driver should IMMEDIATELY go to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me */
+/* This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */
 #define fRTMP_PS_GO_TO_SLEEP_NOW         0x00000008
 #define fRTMP_PS_TOGGLE_L1		0x00000010	/* Use Toggle L1 mechanism for rt28xx PCIe */
 
@@ -303,7 +304,7 @@
 
 /* WDS definition */
 #define	MAX_WDS_ENTRY               4
-#define WDS_PAIRWISE_KEY_OFFSET     60	/* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */
+#define WDS_PAIRWISE_KEY_OFFSET     60	/* WDS links use pairwise key#60 ~ 63 in ASIC pairwise key table */
 
 #define	WDS_DISABLE_MODE            0
 #define	WDS_RESTRICT_MODE           1
@@ -559,7 +560,7 @@
 #define IE_ADD_HT2                        53	/* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */
 
 /* For 802.11n D3.03 */
-/*#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset elemet */
+/*#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset element */
 #define IE_SECONDARY_CH_OFFSET		62	/* 802.11n D3.03        Secondary Channel Offset element */
 #define IE_WAPI							68	/* WAPI information element */
 #define IE_2040_BSS_COEXIST               72	/* 802.11n D3.0.3 */
@@ -678,7 +679,7 @@
 
 #define ACT_MACHINE_BASE              0
 
-/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self. */
+/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please do not modify it by your self. */
 /*Category */
 #define MT2_PEER_SPECTRUM_CATE              0
 #define MT2_PEER_QOS_CATE              1
@@ -748,7 +749,7 @@
 
 #define ACT_FUNC_SIZE                 (MAX_ACT_STATE * MAX_ACT_MSG)
 /* */
-/* STA's AUTHENTICATION state machine: states, evvents, total function # */
+/* STA's AUTHENTICATION state machine: states, events, total function # */
 /* */
 #define AUTH_REQ_IDLE                   0
 #define AUTH_WAIT_SEQ2                  1
@@ -948,7 +949,7 @@
 #define BLOCK_ACK                   0x60	/* b6:5 = 11 */
 
 /* */
-/* rtmp_data.c use these definition */
+/* rtmp_data.c uses this definition */
 /* */
 #define LENGTH_802_11               24
 #define LENGTH_802_11_AND_H         30
@@ -1288,7 +1289,7 @@
 #define IW_STA_LINKDOWN_EVENT_FLAG					0x0210
 #define IW_SCAN_COMPLETED_EVENT_FLAG				0x0211
 #define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG				0x0212
-/* if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END */
+/* if add new system event flag, please update the IW_SYS_EVENT_FLAG_END */
 #define	IW_SYS_EVENT_FLAG_END                       0x0212
 #define	IW_SYS_EVENT_TYPE_NUM						(IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
 /* For system event - end */
@@ -1305,7 +1306,7 @@
 #define IW_SPOOF_DEAUTH_EVENT_FLAG					0x0307
 #define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG			0x0308
 #define IW_REPLAY_ATTACK_EVENT_FLAG					0x0309
-/* if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END */
+/* if add new spoof attack event flag, please update the IW_SPOOF_EVENT_FLAG_END */
 #define	IW_SPOOF_EVENT_FLAG_END                     0x0309
 #define	IW_SPOOF_EVENT_TYPE_NUM						(IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
 /* For spoof attack event - end */
@@ -1319,7 +1320,7 @@
 #define IW_FLOOD_DISASSOC_EVENT_FLAG				0x0404
 #define IW_FLOOD_DEAUTH_EVENT_FLAG					0x0405
 #define IW_FLOOD_EAP_REQ_EVENT_FLAG					0x0406
-/* if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END */
+/* if add new flooding attack event flag, please update the IW_FLOOD_EVENT_FLAG_END */
 #define	IW_FLOOD_EVENT_FLAG_END                   	0x0406
 #define	IW_FLOOD_EVENT_TYPE_NUM						(IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
 /* For flooding attack - end */
diff --git a/drivers/staging/rt2860/rtmp_timer.h b/drivers/staging/rt2860/rtmp_timer.h
index 28b8ac6..15b6287 100644
--- a/drivers/staging/rt2860/rtmp_timer.h
+++ b/drivers/staging/rt2860/rtmp_timer.h
@@ -28,13 +28,14 @@
 	rtmp_timer.h
 
     Abstract:
-	Ralink Wireless Driver timer related data structures and delcarations
+	Ralink Wireless Driver timer related data structures and declarations 
 
     Revision History:
-	Who           When                What
+	Who          		When                 What
 	--------    ----------      ----------------------------------------------
-	Name          Date                 Modification logs
-	Shiang Tu    Aug-28-2008	init version
+	Name          		Date                 Modification logs
+	Shiang Tu    		Aug-28-2008 	     init version
+	Justin P. Mattock	11/07/2010	     Fix a typo
 
 */
 
@@ -51,8 +52,8 @@
 
 /* ----------------- Timer Related MARCO ---------------*/
 /* In some os or chipset, we have a lot of timer functions and will read/write register, */
-/*   it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */
-/*  submit to ctrl pipe). So we need a wrapper function to take care it. */
+/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */
+/* submit to ctrl pipe). So we need a wrapper function to take care it. */
 
 #ifdef RTMP_TIMER_TASK_SUPPORT
 typedef void(*RTMP_TIMER_TASK_HANDLE) (void *SystemSpecific1,
diff --git a/drivers/staging/rt2860/spectrum.h b/drivers/staging/rt2860/spectrum.h
index 648fd63..4c325ba 100644
--- a/drivers/staging/rt2860/spectrum.h
+++ b/drivers/staging/rt2860/spectrum.h
@@ -37,7 +37,7 @@
 	==========================================================================
 	Description:
 		Prepare Measurement request action frame and enqueue it into
-		management queue waiting for transmition.
+		management queue waiting for transmission.
 
 	Parametrs:
 		1. the destination mac address of the frame.
@@ -60,7 +60,7 @@
 	==========================================================================
 	Description:
 		Prepare Measurement report action frame and enqueue it into
-		management queue waiting for transmition.
+		management queue waiting for transmission.
 
 	Parametrs:
 		1. the destination mac address of the frame.
@@ -80,7 +80,7 @@
 	==========================================================================
 	Description:
 		Prepare TPC Request action frame and enqueue it into
-		management queue waiting for transmition.
+		management queue waiting for transmission.
 
 	Parametrs:
 		1. the destination mac address of the frame.
@@ -94,7 +94,7 @@
 	==========================================================================
 	Description:
 		Prepare TPC Report action frame and enqueue it into
-		management queue waiting for transmition.
+		management queue waiting for transmission.
 
 	Parametrs:
 		1. the destination mac address of the frame.
@@ -110,7 +110,7 @@
 	==========================================================================
 	Description:
 		Prepare Channel Switch Announcement action frame and enqueue it into
-		management queue waiting for transmition.
+		management queue waiting for transmission.
 
 	Parametrs:
 		1. the destination mac address of the frame.
@@ -126,7 +126,7 @@
 /*
 	==========================================================================
 	Description:
-		Spectrun action frames Handler such as channel switch annoucement,
+		Spectrun action frames Handler such as channel switch announcement,
 		measurement report, measurement request actions frames.
 
 	Parametrs:
diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
index b7efb0b..ab0a83b 100644
--- a/drivers/staging/rt2860/sta/assoc.c
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -32,7 +32,8 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	John		2004-9-3		porting from RT2500
+	John			2004-9-3		porting from RT2500
+	Justin P. Mattock	11/07/2010		Fix typos
 */
 #include "../rt_config.h"
 
@@ -277,10 +278,10 @@
 	u16 VarIesOffset;
 	u16 Status;
 
-	/* Block all authentication request durning WPA block period */
+	/* Block all authentication request during WPA block period */
 	if (pAd->StaCfg.bBlockAssoc == TRUE) {
 		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - Block Assoc request durning WPA block period!\n"));
+			 ("ASSOC - Block Assoc request during WPA block period!\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_STATE_MACHINE_REJECT;
 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2,
@@ -605,10 +606,10 @@
 	u8 *pOutBuffer = NULL;
 	u16 Status;
 
-	/* Block all authentication request durning WPA block period */
+	/* Block all authentication request during WPA block period */
 	if (pAd->StaCfg.bBlockAssoc == TRUE) {
 		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
+			 ("ASSOC - Block ReAssoc request during WPA block period!\n"));
 		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 		Status = MLME_STATE_MACHINE_REJECT;
 		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2,
@@ -1001,7 +1002,7 @@
 	pAd->MlmeAux.CapabilityInfo =
 	    CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
 
-	/* Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on. */
+	/* Some HT AP might lost WMM IE. We add WMM ourselves. because HT requires QoS on. */
 	if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE)) {
 		pEdcaParm->bValid = TRUE;
 		pEdcaParm->Aifsn[0] = 3;
diff --git a/drivers/staging/rt2860/sta/auth.c b/drivers/staging/rt2860/sta/auth.c
index 404bd22..a2bfafd 100644
--- a/drivers/staging/rt2860/sta/auth.c
+++ b/drivers/staging/rt2860/sta/auth.c
@@ -32,7 +32,8 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	John		2004-9-3		porting from RT2500
+	John			2004-9-3		porting from RT2500
+	Justin P. Mattock	11/07/2010		Fix typos
 */
 #include "../rt_config.h"
 
@@ -455,10 +456,10 @@
 	u8 *pOutBuffer = NULL;
 	unsigned long FrameLen = 0, tmp = 0;
 
-	/* Block all authentication request durning WPA block period */
+	/* Block all authentication request during WPA block period */
 	if (pAd->StaCfg.bBlockAssoc == TRUE) {
 		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s - Block Auth request durning WPA block period!\n",
+			 ("%s - Block Auth request during WPA block period!\n",
 			  pSMName));
 		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
 		Status = MLME_STATE_MACHINE_REJECT;
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index c380551..4b2c84e 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -32,7 +32,8 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	John			2004-08-08			Major modification from RT2560
+	John			2004-08-08		Major modification from RT2560
+	Justin P. Mattock	11/07/2010		Fix typos
 */
 #include "../rt_config.h"
 
@@ -64,7 +65,7 @@
 
 /* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
 /* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
-/* All settings successfuly negotiated furing MLME state machines become final settings */
+/* All settings successfuly negotiated firing MLME state machines become final settings */
 /* and are copied to pAd->StaActive */
 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
 {                                                                                       \
@@ -553,7 +554,7 @@
 	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0],
 		       &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry));
 
-	/* Add SSID into MlmeAux for site surey joining hidden SSID */
+	/* Add SSID into MlmeAux for site survey joining hidden SSID */
 	pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
 	NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,
 		       pAd->MlmeAux.SsidLen);
@@ -666,7 +667,7 @@
 }
 
 /* Roaming is the only external request triggering CNTL state machine */
-/* despite of other "SET OID" operation. All "SET OID" related oerations */
+/* despite of other "SET OID" operation. All "SET OID" related operations */
 /* happen in sequence, because no other SET OID will be sent to this device */
 /* until the the previous SET operation is complete (successful o failed). */
 /* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */
@@ -1224,7 +1225,7 @@
 	/* Change to AP channel */
 	if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
 	    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
-		/* Must using 40MHz. */
+		/* Must use 40MHz. */
 		pAd->CommonCfg.BBPCurrentBW = BW_40;
 		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
 		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
@@ -1259,7 +1260,7 @@
 	} else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
 		   && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
 		       BW_40)) {
-		/* Must using 40MHz. */
+		/* Must use 40MHz. */
 		pAd->CommonCfg.BBPCurrentBW = BW_40;
 		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
 		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
@@ -1343,12 +1344,12 @@
 	AsicSetSlotTime(pAd, TRUE);
 	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
 
-	/* Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit */
+	/* Call this for RTS protection for legacy rate, we will always enable RTS threshold, but normally it will not hit */
 	AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE,
 			  FALSE);
 
 	if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) {
-		/* Update HT protectionfor based on AP's operating mode. */
+		/* Update HT protection for based on AP's operating mode. */
 		if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) {
 			AsicUpdateProtect(pAd,
 					  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
@@ -1530,7 +1531,7 @@
 		/* Add BSSID to WCID search table */
 		AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
 
-		/* If WEP is enabled, add paiewise and shared key */
+		/* If WEP is enabled, add pairwise and shared key */
 		if (((pAd->StaCfg.WpaSupplicantUP) &&
 		     (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
 		     (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
@@ -1681,9 +1682,9 @@
 	pAd->Mlme.PeriodicRound = 0;
 	pAd->Mlme.OneSecPeriodicRound = 0;
 	pAd->bConfigChanged = FALSE;	/* Reset config flag */
-	pAd->ExtraInfo = GENERAL_LINK_UP;	/* Update extra information to link is up */
+	pAd->ExtraInfo = GENERAL_LINK_UP;	/* Update extra information after link is up */
 
-	/* Set asic auto fall back */
+	/* Set basic auto fall back */
 	{
 		u8 *pTable;
 		u8 TableSize = 0;
@@ -1854,8 +1855,8 @@
 	Note:
 		We need more information to know it's this requst from AP.
 		If yes! we need to do extra handling, for example, remove the WPA key.
-		Otherwise on 4-way handshaking will faied, since the WPA key didn't be
-		remove while auto reconnect.
+		Otherwise on 4-way handshaking will fail, since the WPA key didn't get
+		removed while auto reconnect.
 		Disconnect request from AP, it means we will start afresh 4-way handshaking
 		on WPA mode.
 
@@ -1870,9 +1871,9 @@
 		return;
 
 	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-	/*Comment the codes, beasue the line 2291 call the same function. */
-	/*RTMPCancelTimer(&pAd->Mlme.PsPollTimer,               &Cancelled); */
-	/* Not allow go to sleep within linkdown function. */
+	/* Comment the codes, because the line 2291 call the same function. */
+	/* RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */
+	/* Not allowed go to sleep within the linkdown function. */
 	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 
 	if (pAd->CommonCfg.bWirelessEvent) {
@@ -1970,7 +1971,7 @@
 	/* Set LED */
 	RTMPSetLED(pAd, LED_LINK_DOWN);
 	pAd->LedIndicatorStrength = 0xF0;
-	RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, firmware is not done it. */
+	RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, firmware has not done it. */
 
 	AsicDisableSync(pAd);
 
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
index 23879b7..d7c2012 100644
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -31,7 +31,8 @@
 	Data path subroutines
 
 	Revision History:
-	Who 		When			What
+	Who 	  		When		What
+	Justin P. Mattock	11/07/2010	Fix typos
 	--------	----------		----------------------------------------------
 */
 #include "../rt_config.h"
@@ -257,8 +258,8 @@
 		    && (pAd->CommonCfg.bDisableReordering == 0)) {
 			Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
 		} else {
-			/* Determin the destination of the EAP frame */
-			/*  to WPA state machine or upper layer */
+			/* Determine the destination of the EAP frame */
+			/* to WPA state machine or upper layer */
 			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk,
 						FromWhichBSSID);
 		}
@@ -853,7 +854,7 @@
 	NONE
 
 Note:
-	This function do early checking and classification for send-out packet.
+	This function does early checking and classification for send-out packet.
 	You only can put OS-depened & STA related code in here.
 ========================================================================
 */
@@ -943,7 +944,7 @@
 		DBGPRINT(RT_DEBUG_ERROR,
 			 ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n",
 			  SrcBufLen));
-		/* Resourece is low, system did not allocate virtual address */
+		/* Resource is low, system did not allocate virtual address */
 		/* return NDIS_STATUS_FAILURE directly to upper layer */
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 		return NDIS_STATUS_FAILURE;
@@ -979,7 +980,7 @@
 		DBGPRINT(RT_DEBUG_ERROR,
 			("STASendPacket->Cannot find pEntry(%pM) in MacTab!\n",
 				pSrcBufVA));
-		/* Resourece is low, system did not allocate virtual address */
+		/* Resource is low, system did not allocate virtual address */
 		/* return NDIS_STATUS_FAILURE directly to upper layer */
 		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 		return NDIS_STATUS_FAILURE;
@@ -1057,9 +1058,9 @@
 
 	/* STEP 2. Check the requirement of RTS: */
 	/*         If multiple fragment required, RTS is required only for the first fragment */
-	/*         if the fragment size large than RTS threshold */
+	/*         if the fragment size is larger than RTS threshold */
 	/*     For RT28xx, Let ASIC send RTS/CTS */
-/*      RTMP_SET_PACKET_RTS(pPacket, 0); */
+	/*      RTMP_SET_PACKET_RTS(pPacket, 0); */
 	if (NumberOfFrag > 1)
 		RTSRequired =
 		    (pAd->CommonCfg.FragmentThreshold >
@@ -1171,8 +1172,8 @@
 	========================================================================
 
 	Routine Description:
-		This subroutine will scan through releative ring descriptor to find
-		out avaliable free ring descriptor and compare with request size.
+		This subroutine will scan through relative ring descriptor to find
+		out available free ring descriptor and compare with request size.
 
 	Arguments:
 		pAd Pointer to our adapter
@@ -1588,7 +1589,7 @@
 		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += 2;
 	}
-	/* padding at front of LLC header. LLC header should at 4-bytes aligment. */
+	/* padding at front of LLC header. LLC header should at 4-bytes alignment. */
 	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
 	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
 	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
@@ -2014,7 +2015,7 @@
 		pHeaderBufPtr += 2;
 		pTxBlk->MpduHeaderLen += 2;
 	}
-	/* The remaining content of MPDU header should locate at 4-octets aligment */
+	/* The remaining content of MPDU header should locate at 4-octets alignment */
 	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
 	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
 	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
@@ -2114,7 +2115,7 @@
 			    STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
 
 			/* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */
-			/*      will be updated after final frame was handled. */
+			/* will be updated after final frame was handled. */
 			RTMPWriteTxWI_Data(pAd,
 					   (struct rt_txwi *) (&pTxBlk->
 							  HeaderBuf
@@ -2291,8 +2292,8 @@
 				      pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey,
 				      0);
 
-		/* NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust */
-		/*                      to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
+		/* NOTE: DON'T refer the skb->len directly after following copy. Because the length is not adjusted */
+		/*                      to correct length, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
 		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen,
 			       &pAd->PrivateInfo.Tx.MIC[0], 8);
 		/*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */
@@ -2301,7 +2302,7 @@
 		pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
 	}
 	/* */
-	/* calcuate the overhead bytes that encryption algorithm may add. This */
+	/* calculate the overhead bytes that encryption algorithm may add. This */
 	/* affects the calculate of "duration" field */
 	/* */
 	if ((pTxBlk->CipherAlg == CIPHER_WEP64)
diff --git a/drivers/staging/rt2860/sta/sanity.c b/drivers/staging/rt2860/sta/sanity.c
index 8f9fd19..0c32604 100644
--- a/drivers/staging/rt2860/sta/sanity.c
+++ b/drivers/staging/rt2860/sta/sanity.c
@@ -32,7 +32,8 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	John Chang  2004-09-01      add WMM support
+	John Chang  		2004-09-01      add WMM support
+	Justin P. Mattock	11/07/2010	Fix typos
 */
 #include "../rt_config.h"
 
@@ -118,7 +119,7 @@
 	NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
 	Length += 2;
 
-	/* Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform */
+	/* Aid already swapped byte order in RTMPFrameEndianChange() for big endian platform */
 	*pAid = (*pAid) & 0x3fff;	/* AID is low 14-bit */
 
 	/* -- get supported rates from payload and advance the pointer */
diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
index 747d3c6..05007d9 100644
--- a/drivers/staging/rt2860/sta/sync.c
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -32,8 +32,9 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	John Chang	2004-09-01      modified for rt2561/2661
-	Jan Lee		2006-08-01      modified for rt2860 for 802.11n
+	John Chang		2004-09-01      	modified for rt2561/2661
+	Jan Lee			2006-08-01      	modified for rt2860 for 802.11n
+	Justin P. Mattock	11/07/2010		Fix typos
 */
 #include "../rt_config.h"
 
@@ -233,9 +234,9 @@
 		RTMPSuspendMsduTransmission(pAd);
 
 		/* */
-		/* To prevent data lost. */
-		/* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
-		/* And should send an NULL data with turned PSM bit off to AP, when scan progress done */
+		/* To prevent data loss. */
+		/* Send a NULL data with turned PSM bit on to current associated AP before SCAN progress. */
+		/* And should send a NULL data with turned PSM bit off to AP, when scan progress done */
 		/* */
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
 		    && (INFRA_ON(pAd))) {
@@ -750,9 +751,9 @@
 
 		/* BEACON from desired BSS/IBSS found. We should be able to decide most */
 		/* BSS parameters here. */
-		/* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? */
-		/*    Do we need to receover back all parameters belonging to previous BSS? */
-		/* A. Should be not. There's no back-door recover to previous AP. It still need */
+		/* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATION? */
+		/*    Do we need to recover back all parameters belonging to previous BSS? */
+		/* A. Should be not. There's no back-door recover to previous AP. It still needs */
 		/*    a new JOIN-AUTH-ASSOC sequence. */
 		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) {
 			DBGPRINT(RT_DEBUG_TRACE,
@@ -876,7 +877,7 @@
 			pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
 			pAd->MlmeAux.APRalinkIe = RalinkIe;
 
-			/* Copy AP's supported rate to MlmeAux for creating assoication request */
+			/* Copy AP's supported rate to MlmeAux for creating association request */
 			/* Also filter out not supported rate */
 			pAd->MlmeAux.SupRateLen = SupRateLen;
 			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate,
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
index 69b8a24..ff34832 100644
--- a/drivers/staging/rt2860/sta/wpa.c
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -33,7 +33,8 @@
 	Who			When			What
 	--------	----------		----------------------------------------------
 	Jan	Lee		03-07-22		Initial
-	Paul Lin	03-11-28		Modify for supplicant
+	Paul Lin		03-11-28		Modify for supplicant
+	Justin P. Mattock	11/07/2010		Fix typos
 */
 #include "../rt_config.h"
 
@@ -86,7 +87,7 @@
 			/* Violate MIC error counts, MIC countermeasures kicks in */
 			pAd->StaCfg.MicErrCnt++;
 			/* We shall block all reception */
-			/* We shall clean all Tx ring and disassoicate from AP after next EAPOL frame */
+			/* We shall clean all Tx ring and disassociate from AP after next EAPOL frame */
 			/* */
 			/* No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets */
 			/* if pAd->StaCfg.MicErrCnt greater than 2. */
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index e095a44..5717e12 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -31,10 +31,11 @@
     IOCTL related subroutines
 
     Revision History:
-    Who         When          What
+    	Who        		 When          What
     --------    ----------    ----------------------------------------------
-    Rory Chen   01-03-2003    created
-	Rory Chen   02-14-2005    modify to support RT61
+   	Rory Chen   		01-03-2003    	created
+	Rory Chen   		02-14-2005    	modify to support RT61
+	Justin P. Mattock	11/07/2010	Fix typos
 */
 
 #include	"rt_config.h"
@@ -851,7 +852,7 @@
 
 		/*
 		   Protocol:
-		   it will show scanned AP's WirelessMode .
+		   it will show scanned AP's WirelessMode.
 		   it might be
 		   802.11a
 		   802.11a/n
@@ -875,13 +876,13 @@
 					strcpy(iwe.u.name, "802.11a");
 			} else {
 				/*
-				   if one of non B mode rate is set supported rate . it mean G only.
+				   if one of non B mode rate is set supported rate, it means G only.
 				 */
 				for (rateCnt = 0;
 				     rateCnt < pBssEntry->SupRateLen;
 				     rateCnt++) {
 					/*
-					   6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
+					   6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate, it means G only.
 					 */
 					if (pBssEntry->SupRate[rateCnt] == 140
 					    || pBssEntry->SupRate[rateCnt] ==
@@ -1417,7 +1418,7 @@
 		if ((index >= 0) && (index < 4)) {
 			pAdapter->StaCfg.DefaultKeyId = index;
 		} else
-			/* Don't complain if only change the mode */
+			/* Don't complain if the mode is only changed */
 		if (!(erq->flags & IW_ENCODE_MODE))
 			return -EINVAL;
 	}
@@ -2732,8 +2733,8 @@
 			}
 			if (INFRA_ON(pAdapter)) {
 				/*BOOLEAN Cancelled; */
-				/* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
-				/* Since calling this indicate user don't want to connect to that SSID anymore. */
+				/* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */
+				/* Since calling this indicates users don't want to connect to that SSID anymore. */
 				pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
 				NdisZeroMemory(pAdapter->MlmeAux.
 					       AutoReconnectSsid,
@@ -2766,8 +2767,8 @@
 				LinkDown(pAdapter, FALSE);
 			}
 			if (ADHOC_ON(pAdapter)) {
-				/* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
-				/* Since calling this indicate user don't want to connect to that SSID anymore. */
+				/* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */
+				/* Since calling this indicates users don't want to connect to that SSID anymore. */
 				pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
 				NdisZeroMemory(pAdapter->MlmeAux.
 					       AutoReconnectSsid,
@@ -2884,7 +2885,7 @@
 		}
 		/* Enable Rx with promiscuous reception */
 		RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
-		/* ASIC supporsts sniffer function with replacing RSSI with timestamp. */
+		/* ASIC supports sniffer function with replacing RSSI with timestamp. */
 		/*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */
 		/*Value |= (0x80); */
 		/*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index ddacfc6..d90c260 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -27,8 +27,8 @@
 #include "rt_config.h"
 
 /* Following information will be show when you run 'modinfo' */
-/* *** If you have a solution for the bug in current version of driver, please mail to me. */
-/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */
+/* If you have a solution for the bug in current version of driver, please e-mail me. */
+/* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */
 MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
 MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver");
 MODULE_LICENSE("GPL");
@@ -883,8 +883,8 @@
 	if (net_dev == NULL)
 		goto err_out_free_radev;
 
-	/* Here are the net_device structure with usb specific parameters. */
-	/* for supporting Network Manager.
+	/* Here are the net_device structure with usb specific parameters. 
+	 * for supporting Network Manager.
 	 * Set the sysfs physical device reference for the network logical device if set prior to registration will
 	 * cause a symlink during initialization.
 	 */
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
index 6199ae6..116fc2c 100644
--- a/drivers/staging/rt2860/wpa.h
+++ b/drivers/staging/rt2860/wpa.h
@@ -32,13 +32,14 @@
 	Revision History:
 	Who			When			What
 	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
+	Name			Date			Modification logs
+	Justin P. Mattock	11/07/2010		Fix a typo
 */
 
 #ifndef	__WPA_H__
 #define	__WPA_H__
 
-/* EAPOL Key descripter frame format related length */
+/* EAPOL Key descriptor frame format related length */
 #define LEN_KEY_DESC_NONCE			32
 #define LEN_KEY_DESC_IV				16
 #define LEN_KEY_DESC_RSC			8
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index b1786dc..b7d0860 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -2283,9 +2283,7 @@
 				IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
 
 	priv->AcmControl = 0;
-	priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
-	if (priv->pFirmware)
-	memset(priv->pFirmware, 0, sizeof(rt_firmware));
+	priv->pFirmware = vzalloc(sizeof(rt_firmware));
 
 	/* rx related queue */
         skb_queue_head_init(&priv->rx_queue);
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 494f180..4cc7b41 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -1507,7 +1507,7 @@
 	{
 		//
 		// Handle HW Beacon:
-		// We had transfer our beacon frame to host controler at this moment.
+		// We had transfer our beacon frame to host controller at this moment.
 		//
 		//
 		// Caution:
diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO
index 5c88821..2aa5deb 100644
--- a/drivers/staging/rtl8712/TODO
+++ b/drivers/staging/rtl8712/TODO
@@ -3,7 +3,6 @@
 - switch to use LIB80211
 - switch to use MAC80211
 - checkpatch.pl fixes - only a few remain
-- sparse fixes
 - switch from large inline firmware file to use the firmware interface
   and add the file to the linux-firmware package.
 
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index d1674cd..7d62714 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -196,10 +196,7 @@
 
 static inline u8 *_malloc(u32 sz)
 {
-	u8 *pbuf;
-
-	pbuf =	kmalloc(sz, GFP_ATOMIC);
-	return pbuf;
+	return	kmalloc(sz, GFP_ATOMIC);
 }
 
 static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
@@ -221,34 +218,22 @@
 
 static inline u32 _RND8(u32 sz)
 {
-	u32	val;
-
-	val = ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3;
-	return val;
+	return ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3;
 }
 
 static inline u32 _RND128(u32 sz)
 {
-	u32	val;
-
-	val = ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7;
-	return val;
+	return ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7;
 }
 
 static inline u32 _RND256(u32 sz)
 {
-	u32	val;
-
-	val = ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8;
-	return val;
+	return ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8;
 }
 
 static inline u32 _RND512(u32 sz)
 {
-	u32	val;
-
-	val = ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9;
-	return val;
+	return ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9;
 }
 
 #define STRUCT_PACKED __attribute__ ((packed))
diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/solo6x10/Kconfig
index d96398c..de60ac8 100644
--- a/drivers/staging/solo6x10/Kconfig
+++ b/drivers/staging/solo6x10/Kconfig
@@ -1,7 +1,7 @@
 config SOLO6X10
 	tristate "Softlogic 6x10 MPEG codec cards"
 	depends on PCI && VIDEO_DEV && SND
-	select VIDEOBUF_DMA_CONTIG
+	select VIDEOBUF_DMA_SG
 	---help---
 	  This driver supports the Softlogic based MPEG-4 and h.264 codec
 	  codec cards.
diff --git a/drivers/staging/solo6x10/TODO b/drivers/staging/solo6x10/TODO
index e6a2ee2..7e6c4fa 100644
--- a/drivers/staging/solo6x10/TODO
+++ b/drivers/staging/solo6x10/TODO
@@ -1,7 +1,5 @@
 TODO (staging => main):
 
-	* checkpatch.pl (haven't run it yet)
-	* Lindent (should be clean, but check)
 	* Motion detection flags need to be moved to v4l2
 	* Some private CIDs need to be moved to v4l2
 
@@ -21,8 +19,6 @@
 	  - implement playback via external sound jack
 	  - implement loopback of external sound jack with incoming audio?
 	  - implement pause/resume
-	  - check into jacking sound from tx28xx chips directly (to avoid
-	    g.723/8khz limitations)
 
 Plase send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc Ben Collins
 <bcollins@bluecherry.net>
diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c
index 4a051cd..c433136 100644
--- a/drivers/staging/solo6x10/solo6010-core.c
+++ b/drivers/staging/solo6x10/solo6010-core.c
@@ -136,6 +136,7 @@
 	int ret;
 	int sdram;
 	u8 chip_id;
+
 	solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL);
 	if (solo_dev == NULL)
 		return -ENOMEM;
@@ -163,21 +164,21 @@
 	chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) &
 					SOLO_CHIP_ID_MASK;
 	switch (chip_id) {
-		case 7:
-			solo_dev->nr_chans = 16;
-			solo_dev->nr_ext = 5;
-			break;
-		case 6:
-			solo_dev->nr_chans = 8;
-			solo_dev->nr_ext = 2;
-			break;
-		default:
-			dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, "
-				 "defaulting to 4 channels\n",
-				 chip_id);
-		case 5:
-			solo_dev->nr_chans = 4;
-			solo_dev->nr_ext = 1;
+	case 7:
+		solo_dev->nr_chans = 16;
+		solo_dev->nr_ext = 5;
+		break;
+	case 6:
+		solo_dev->nr_chans = 8;
+		solo_dev->nr_ext = 2;
+		break;
+	default:
+		dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, "
+			 "defaulting to 4 channels\n",
+			 chip_id);
+	case 5:
+		solo_dev->nr_chans = 4;
+		solo_dev->nr_ext = 1;
 	}
 
 	/* Disable all interrupts to start */
@@ -261,13 +262,18 @@
 }
 
 static struct pci_device_id solo6010_id_table[] = {
+	/* 6010 based cards */
 	{PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16)},
-	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_4)},
-	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_9)},
-	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_16)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_4)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_9)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_16)},
+	/* 6110 based cards */
+	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_4)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_8)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16)},
 	{0,}
 };
 
diff --git a/drivers/staging/solo6x10/solo6010-disp.c b/drivers/staging/solo6x10/solo6010-disp.c
index 555f024..f866f84 100644
--- a/drivers/staging/solo6x10/solo6010-disp.c
+++ b/drivers/staging/solo6x10/solo6010-disp.c
@@ -198,12 +198,12 @@
 	}
 
 	/* Default motion settings */
-        solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) |
+	solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) |
 		       (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));
 	solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL,
 		       SOLO_VI_MOTION_FRAME_COUNT(3) |
 		       SOLO_VI_MOTION_SAMPLE_LENGTH(solo_dev->video_hsize / 16)
-		       | //SOLO_VI_MOTION_INTR_START_STOP |
+		       | /* SOLO_VI_MOTION_INTR_START_STOP | */
 		       SOLO_VI_MOTION_SAMPLE_COUNT(10));
 
 	solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0);
@@ -264,7 +264,7 @@
 	solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(0), 0);
 	solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(0), 0);
 	solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(0), 0);
-	
+
 	solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(1), 0);
 	solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(1), 0);
 	solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(1), 0);
diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c
index a6cf0a8..481a492 100644
--- a/drivers/staging/solo6x10/solo6010-enc.c
+++ b/drivers/staging/solo6x10/solo6010-enc.c
@@ -22,7 +22,7 @@
 #include "solo6010.h"
 #include "solo6010-osd-font.h"
 
-#define CAPTURE_MAX_BANDWIDTH		32	// D1 4channel (D1 == 4)
+#define CAPTURE_MAX_BANDWIDTH		32	/* D1 4channel (D1 == 4) */
 #define OSG_BUFFER_SIZE			1024
 
 #define VI_PROG_HSIZE			(1280 - 16)
@@ -145,8 +145,8 @@
 
 	solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR(solo_dev) +
 		     (solo_enc->ch * SOLO_EOSD_EXT_SIZE), SOLO_EOSD_EXT_SIZE);
-        reg |= (1 << solo_enc->ch);
-        solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg);
+	reg |= (1 << solo_enc->ch);
+	solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg);
 
 	kfree(buf);
 
diff --git a/drivers/staging/solo6x10/solo6010-g723.c b/drivers/staging/solo6x10/solo6010-g723.c
index 82fbcb8..254b46a 100644
--- a/drivers/staging/solo6x10/solo6010-g723.c
+++ b/drivers/staging/solo6x10/solo6010-g723.c
@@ -47,7 +47,7 @@
  * is broken down to 20 * 48 byte regions (one for each channel possible)
  * with the rest of the page being dummy data. */
 #define MAX_BUFFER		(G723_PERIOD_BYTES * PERIODS_MAX)
-#define IRQ_PAGES		4 // 0 - 4
+#define IRQ_PAGES		4 /* 0 - 4 */
 #define PERIODS_MIN		(1 << IRQ_PAGES)
 #define PERIODS_MAX		G723_FDMA_PAGES
 
@@ -158,7 +158,7 @@
 	snd_pcm_substream_chip(ss) = solo_pcm->solo_dev;
 	kfree(solo_pcm);
 
-        return 0;
+	return 0;
 }
 
 static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
@@ -197,7 +197,7 @@
 
 static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss)
 {
-        return 0;
+	return 0;
 }
 
 static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss)
@@ -271,7 +271,7 @@
 
 	value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch);
 
-        return 0;
+	return 0;
 }
 
 static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol,
@@ -279,15 +279,15 @@
 {
 	struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol);
 	u8 ch = value->id.numid - 1;
-        u8 old_val;
+	u8 old_val;
 
-        old_val = tw28_get_audio_gain(solo_dev, ch);
+	old_val = tw28_get_audio_gain(solo_dev, ch);
 	if (old_val == value->value.integer.value[0])
 		return 0;
 
 	tw28_set_audio_gain(solo_dev, ch, value->value.integer.value[0]);
 
-        return 1;
+	return 1;
 }
 
 static struct snd_kcontrol_new snd_solo_capture_volume = {
@@ -368,14 +368,16 @@
 	strcpy(card->mixername, "SOLO-6010");
 	kctl = snd_solo_capture_volume;
 	kctl.count = solo_dev->nr_chans;
-        ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev));
+	ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev));
 	if (ret < 0)
 		return ret;
 
-	if ((ret = solo_snd_pcm_init(solo_dev)) < 0)
+	ret = solo_snd_pcm_init(solo_dev);
+	if (ret < 0)
 		goto snd_error;
 
-	if ((ret = snd_card_register(card)) < 0)
+	ret = snd_card_register(card);
+	if (ret < 0)
 		goto snd_error;
 
 	solo_g723_config(solo_dev);
diff --git a/drivers/staging/solo6x10/solo6010-gpio.c b/drivers/staging/solo6x10/solo6010-gpio.c
index 46f7a71eda..8869b88 100644
--- a/drivers/staging/solo6x10/solo6010-gpio.c
+++ b/drivers/staging/solo6x10/solo6010-gpio.c
@@ -92,8 +92,8 @@
 
 int solo_gpio_init(struct solo6010_dev *solo_dev)
 {
-        solo_gpio_config(solo_dev);
-        return 0;
+	solo_gpio_config(solo_dev);
+	return 0;
 }
 
 void solo_gpio_exit(struct solo6010_dev *solo_dev)
diff --git a/drivers/staging/solo6x10/solo6010-i2c.c b/drivers/staging/solo6x10/solo6010-i2c.c
index cadd512..60b69cd 100644
--- a/drivers/staging/solo6x10/solo6010-i2c.c
+++ b/drivers/staging/solo6x10/solo6010-i2c.c
@@ -46,7 +46,7 @@
 
 	i2c_transfer(&solo_dev->i2c_adap[id], msgs, 2);
 
-        return data;
+	return data;
 }
 
 void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr,
@@ -225,9 +225,9 @@
 	}
 
 	if (i == SOLO_I2C_ADAPTERS)
-		return num; // XXX Right return value for failure?
+		return num; /* XXX Right return value for failure? */
 
-	down(&solo_dev->i2c_sem);
+	mutex_lock(&solo_dev->i2c_mutex);
 	solo_dev->i2c_id = i;
 	solo_dev->i2c_msg = msgs;
 	solo_dev->i2c_msg_num = num;
@@ -258,7 +258,7 @@
 	solo_dev->i2c_state = IIC_STATE_IDLE;
 	solo_dev->i2c_id = -1;
 
-	up(&solo_dev->i2c_sem);
+	mutex_unlock(&solo_dev->i2c_mutex);
 
 	return ret;
 }
@@ -284,7 +284,7 @@
 	solo_dev->i2c_id = -1;
 	solo_dev->i2c_state = IIC_STATE_IDLE;
 	init_waitqueue_head(&solo_dev->i2c_wait);
-	sema_init(&solo_dev->i2c_sem, 1);
+	mutex_init(&solo_dev->i2c_mutex);
 
 	for (i = 0; i < SOLO_I2C_ADAPTERS; i++) {
 		struct i2c_adapter *adap = &solo_dev->i2c_adap[i];
@@ -296,7 +296,8 @@
 		adap->retries = 1;
 		adap->dev.parent = &solo_dev->pdev->dev;
 
-		if ((ret = i2c_add_adapter(adap))) {
+		ret = i2c_add_adapter(adap);
+		if (ret) {
 			adap->algo_data = NULL;
 			break;
 		}
diff --git a/drivers/staging/solo6x10/solo6010-osd-font.h b/drivers/staging/solo6x10/solo6010-osd-font.h
index d6f565b..d72efbb 100644
--- a/drivers/staging/solo6x10/solo6010-osd-font.h
+++ b/drivers/staging/solo6x10/solo6010-osd-font.h
@@ -22,7 +22,7 @@
 
 static const unsigned int solo_osd_font[] = {
 	0x00000000, 0x0000c0c8, 0xccfefe0c, 0x08000000,
-	0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000,	// 0
+	0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000,	/* 0 */
 	0x00000000, 0xfefe7c7c, 0x38381010, 0x10000000,
 	0x00000000, 0x7c82fefe, 0xfefefe7c, 0x00000000,
 	0x00000000, 0x00001038, 0x10000000, 0x00000000,
@@ -54,67 +54,67 @@
 	0x0000003f, 0x7f404c52, 0x524c407f, 0x00000000,
 	0x0000007c, 0x82ba82ba, 0x82ba82fe, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x183c3c3c, 0x18180018, 0x18000000,	// 32   !
+	0x00000000, 0x183c3c3c, 0x18180018, 0x18000000,	/* 32   ! */
 	0x00000066, 0x66240000, 0x00000000, 0x00000000,
-	0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000,	// 34 " #
+	0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000,	/* 34 " # */
 	0x00001010, 0x7cd6d616, 0x7cd0d6d6, 0x7c101000,
-	0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000,	// 36 $ %
+	0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000,	/* 36 $ % */
 	0x00000000, 0x386c6c38, 0xdc766666, 0xdc000000,
-	0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000,	// 38 & '
+	0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000,	/* 38 & ' */
 	0x00000000, 0x30180c0c, 0x0c0c0c18, 0x30000000,
-	0x00000000, 0x0c183030, 0x30303018, 0x0c000000,	// 40 ( )
+	0x00000000, 0x0c183030, 0x30303018, 0x0c000000,	/* 40 ( ) */
 	0x00000000, 0x0000663c, 0xff3c6600, 0x00000000,
-	0x00000000, 0x00001818, 0x7e181800, 0x00000000,	// 42 * +
+	0x00000000, 0x00001818, 0x7e181800, 0x00000000,	/* 42 * + */
 	0x00000000, 0x00000000, 0x00000e0e, 0x0c060000,
-	0x00000000, 0x00000000, 0x7e000000, 0x00000000,	// 44 , -
+	0x00000000, 0x00000000, 0x7e000000, 0x00000000,	/* 44 , - */
 	0x00000000, 0x00000000, 0x00000006, 0x06000000,
-	0x00000000, 0x80c06030, 0x180c0602, 0x00000000,	// 46 . /
+	0x00000000, 0x80c06030, 0x180c0602, 0x00000000,	/* 46 . / */
 	0x0000007c, 0xc6e6f6de, 0xcec6c67c, 0x00000000,
-	0x00000030, 0x383c3030, 0x303030fc, 0x00000000,	// 48 0 1
+	0x00000030, 0x383c3030, 0x303030fc, 0x00000000,	/* 48 0 1 */
 	0x0000007c, 0xc6c06030, 0x180cc6fe, 0x00000000,
-	0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000,	// 50 2 3
+	0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000,	/* 50 2 3 */
 	0x00000060, 0x70786c66, 0xfe6060f0, 0x00000000,
-	0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000,	// 52 4 5
+	0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000,	/* 52 4 5 */
 	0x00000038, 0x0c06067e, 0xc6c6c67c, 0x00000000,
-	0x000000fe, 0xc6c06030, 0x18181818, 0x00000000,	// 54 6 7
+	0x000000fe, 0xc6c06030, 0x18181818, 0x00000000,	/* 54 6 7 */
 	0x0000007c, 0xc6c6c67c, 0xc6c6c67c, 0x00000000,
-	0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000,	// 56 8 9
+	0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000,	/* 56 8 9 */
 	0x00000000, 0x18180000, 0x00181800, 0x00000000,
-	0x00000000, 0x18180000, 0x0018180c, 0x00000000,	// 58 : ;
+	0x00000000, 0x18180000, 0x0018180c, 0x00000000,	/* 58 : ; */
 	0x00000060, 0x30180c06, 0x0c183060, 0x00000000,
 	0x00000000, 0x007e0000, 0x007e0000, 0x00000000,
 	0x00000006, 0x0c183060, 0x30180c06, 0x00000000,
 	0x0000007c, 0xc6c66030, 0x30003030, 0x00000000,
 	0x0000007c, 0xc6f6d6d6, 0x7606067c, 0x00000000,
-	0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000,	// 64 @ A
+	0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000,	/* 64 @ A */
 	0x0000007e, 0xc6c6c67e, 0xc6c6c67e, 0x00000000,
-	0x00000078, 0xcc060606, 0x0606cc78, 0x00000000,	// 66
+	0x00000078, 0xcc060606, 0x0606cc78, 0x00000000,	/* 66 */
 	0x0000003e, 0x66c6c6c6, 0xc6c6663e, 0x00000000,
-	0x000000fe, 0x0606063e, 0x060606fe, 0x00000000,	// 68
+	0x000000fe, 0x0606063e, 0x060606fe, 0x00000000,	/* 68 */
 	0x000000fe, 0x0606063e, 0x06060606, 0x00000000,
-	0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000,	// 70
+	0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000,	/* 70 */
 	0x000000c6, 0xc6c6c6fe, 0xc6c6c6c6, 0x00000000,
-	0x0000003c, 0x18181818, 0x1818183c, 0x00000000,	// 72
+	0x0000003c, 0x18181818, 0x1818183c, 0x00000000,	/* 72 */
 	0x00000060, 0x60606060, 0x6066663c, 0x00000000,
-	0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000,	// 74
+	0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000,	/* 74 */
 	0x00000006, 0x06060606, 0x060606fe, 0x00000000,
-	0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000,	// 76
+	0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000,	/* 76 */
 	0x000000c6, 0xcedefef6, 0xe6c6c6c6, 0x00000000,
-	0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000,	// 78
+	0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000,	/* 78 */
 	0x0000007e, 0xc6c6c67e, 0x06060606, 0x00000000,
-	0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000,	// 80
+	0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000,	/* 80 */
 	0x0000007e, 0xc6c6c67e, 0x66c6c6c6, 0x00000000,
-	0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000,	// 82
+	0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000,	/* 82 */
 	0x0000007e, 0x18181818, 0x18181818, 0x00000000,
-	0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000,	// 84
+	0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000,	/* 84 */
 	0x000000c6, 0xc6c6c6c6, 0xc66c3810, 0x00000000,
-	0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000,	// 86
+	0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000,	/* 86 */
 	0x000000c6, 0xc6c66c38, 0x6cc6c6c6, 0x00000000,
-	0x00000066, 0x66666666, 0x3c181818, 0x00000000,	// 88
+	0x00000066, 0x66666666, 0x3c181818, 0x00000000,	/* 88 */
 	0x000000fe, 0xc0603018, 0x0c0606fe, 0x00000000,
-	0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000,	// 90
+	0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000,	/* 90 */
 	0x00000002, 0x060c1830, 0x60c08000, 0x00000000,
-	0x0000003c, 0x30303030, 0x3030303c, 0x00000000,	// 92
+	0x0000003c, 0x30303030, 0x3030303c, 0x00000000,	/* 92 */
 	0x00001038, 0x6cc60000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00fe0000,
 	0x00001818, 0x30000000, 0x00000000, 0x00000000,
diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c
index 7ed3ed4..956dea0 100644
--- a/drivers/staging/solo6x10/solo6010-p2m.c
+++ b/drivers/staging/solo6x10/solo6010-p2m.c
@@ -18,10 +18,11 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/scatterlist.h>
 
 #include "solo6010.h"
 
-// #define SOLO_TEST_P2M
+/* #define SOLO_TEST_P2M */
 
 int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr,
 		 void *sys_addr, u32 ext_addr, u32 size)
@@ -30,8 +31,9 @@
 	int ret;
 
 	WARN_ON(!size);
-	WARN_ON(id >= SOLO_NR_P2M);
-	if (!size || id >= SOLO_NR_P2M)
+	BUG_ON(id >= SOLO_NR_P2M);
+
+	if (!size)
 		return -EINVAL;
 
 	dma_addr = pci_map_single(solo_dev->pdev, sys_addr, size,
@@ -48,41 +50,136 @@
 int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr,
 		   dma_addr_t dma_addr, u32 ext_addr, u32 size)
 {
-	struct solo_p2m_dev *p2m_dev;
-	unsigned int timeout = 0;
+	struct p2m_desc *desc = kzalloc(sizeof(*desc) * 2, GFP_DMA);
+	int ret;
 
-	WARN_ON(!size);
-	WARN_ON(id >= SOLO_NR_P2M);
-	if (!size || id >= SOLO_NR_P2M)
-		return -EINVAL;
+	if (desc == NULL)
+		return -ENOMEM;
+
+	solo_p2m_push_desc(&desc[1], wr, dma_addr, ext_addr, size, 0, 0);
+	ret = solo_p2m_dma_desc(solo_dev, id, desc, 2);
+	kfree(desc);
+
+	return ret;
+}
+
+void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr,
+			u32 ext_addr, u32 size, int repeat, u32 ext_size)
+{
+	desc->ta = dma_addr;
+	desc->fa = ext_addr;
+
+	desc->ext = SOLO_P2M_COPY_SIZE(size >> 2);
+	desc->ctrl = SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) |
+		(wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON;
+
+	/* Ext size only matters when we're repeating */
+	if (repeat) {
+		desc->ext |= SOLO_P2M_EXT_INC(ext_size >> 2);
+		desc->ctrl |=  SOLO_P2M_PCI_INC(size >> 2) |
+			SOLO_P2M_REPEAT(repeat);
+	}
+}
+
+int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id,
+		      struct p2m_desc *desc, int desc_count)
+{
+	struct solo_p2m_dev *p2m_dev;
+	unsigned int timeout;
+	int ret = 0;
+	u32 config = 0;
+	dma_addr_t desc_dma = 0;
+
+	BUG_ON(id >= SOLO_NR_P2M);
+	BUG_ON(!desc_count || desc_count > SOLO_NR_P2M_DESC);
 
 	p2m_dev = &solo_dev->p2m_dev[id];
 
-	down(&p2m_dev->sem);
+	mutex_lock(&p2m_dev->mutex);
 
-start_dma:
+	solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0);
+
 	INIT_COMPLETION(p2m_dev->completion);
 	p2m_dev->error = 0;
-	solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), dma_addr);
-	solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), ext_addr);
-	solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id),
-		       SOLO_P2M_COPY_SIZE(size >> 2));
-	solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id),
-		       SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) |
-		       (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON);
 
+	/* Enable the descriptors */
+	config = solo_reg_read(solo_dev, SOLO_P2M_CONFIG(id));
+	desc_dma = pci_map_single(solo_dev->pdev, desc,
+				  desc_count * sizeof(*desc),
+				  PCI_DMA_TODEVICE);
+	solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), desc_dma);
+	solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), desc_count - 1);
+	solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config |
+		       SOLO_P2M_DESC_MODE);
+
+	/* Should have all descriptors completed from one interrupt */
 	timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ);
 
 	solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0);
 
-	/* XXX Really looks to me like we will get stuck here if a
-	 * real PCI P2M error occurs */
+	/* Reset back to non-descriptor mode */
+	solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config);
+	solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), 0);
+	solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), 0);
+	pci_unmap_single(solo_dev->pdev, desc_dma,
+			 desc_count * sizeof(*desc),
+			 PCI_DMA_TODEVICE);
+
 	if (p2m_dev->error)
-		goto start_dma;
+		ret = -EIO;
+	else if (timeout == 0)
+		ret = -EAGAIN;
 
-	up(&p2m_dev->sem);
+	mutex_unlock(&p2m_dev->mutex);
 
-	return (timeout == 0) ? -EAGAIN : 0;
+	WARN_ON_ONCE(ret);
+
+	return ret;
+}
+
+int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id,
+		    struct p2m_desc *pdesc, int wr,
+		    struct scatterlist *sg, u32 sg_off,
+		    u32 ext_addr, u32 size)
+{
+	int i;
+	int idx;
+
+	BUG_ON(id >= SOLO_NR_P2M);
+
+	if (WARN_ON_ONCE(!size))
+		return -EINVAL;
+
+	memset(pdesc, 0, sizeof(*pdesc));
+
+	/* Should rewrite this to handle > SOLO_NR_P2M_DESC transactions */
+	for (i = 0, idx = 1; idx < SOLO_NR_P2M_DESC && sg && size > 0;
+	     i++, sg = sg_next(sg)) {
+		struct p2m_desc *desc = &pdesc[idx];
+		u32 sg_len = sg_dma_len(sg);
+		u32 len;
+
+		if (sg_off >= sg_len) {
+			sg_off -= sg_len;
+			continue;
+		}
+
+		sg_len -= sg_off;
+		len = min(sg_len, size);
+
+		solo_p2m_push_desc(desc, wr, sg_dma_address(sg) + sg_off,
+				   ext_addr, len, 0, 0);
+
+		size -= len;
+		ext_addr += len;
+		idx++;
+
+		sg_off = 0;
+	}
+
+	WARN_ON_ONCE(size || i >= SOLO_NR_P2M_DESC);
+
+	return solo_p2m_dma_desc(solo_dev, id, pdesc, idx);
 }
 
 #ifdef SOLO_TEST_P2M
@@ -147,13 +244,16 @@
 	return;
 }
 #else
-#define run_p2m_test(__solo)	do{}while(0)
+#define run_p2m_test(__solo)	do {} while (0)
 #endif
 
 void solo_p2m_isr(struct solo6010_dev *solo_dev, int id)
 {
+	struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id];
+
 	solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id));
-	complete(&solo_dev->p2m_dev[id].completion);
+
+	complete(&p2m_dev->completion);
 }
 
 void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status)
@@ -188,16 +288,14 @@
 	for (i = 0; i < SOLO_NR_P2M; i++) {
 		p2m_dev = &solo_dev->p2m_dev[i];
 
-		sema_init(&p2m_dev->sem, 1);
+		mutex_init(&p2m_dev->mutex);
 		init_completion(&p2m_dev->completion);
 
-		solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(i),
-			       __pa(p2m_dev->desc));
-
 		solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0);
 		solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i),
 			       SOLO_P2M_CSC_16BIT_565 |
-			       SOLO_P2M_DMA_INTERVAL(0) |
+			       SOLO_P2M_DMA_INTERVAL(3) |
+			       SOLO_P2M_DESC_INTR_OPT |
 			       SOLO_P2M_PCI_MASTER_MODE);
 		solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i));
 	}
diff --git a/drivers/staging/solo6x10/solo6010-tw28.c b/drivers/staging/solo6x10/solo6010-tw28.c
index 0159c83..905a6ad 100644
--- a/drivers/staging/solo6x10/solo6010-tw28.c
+++ b/drivers/staging/solo6x10/solo6010-tw28.c
@@ -35,107 +35,107 @@
 #define DEFAULT_VACTIVE_PAL		(312-DEFAULT_VDELAY_PAL)
 
 static u8 tbl_tw2864_template[] = {
-	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x00
+	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x00 */
 	0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x10
+	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x10 */
 	0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x20
+	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x20 */
 	0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x30
+	0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x30 */
 	0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00,
-	0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, // 0x80
+	0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, /* 0x80 */
 	0x22, 0x01, 0xd8, 0xbc, 0xb8, 0x44, 0x38, 0x00,
-	0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, // 0x90
+	0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, /* 0x90 */
 	0x00, 0x28, 0x44, 0x44, 0xa0, 0x88, 0x5a, 0x01,
-	0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, // 0xa0
+	0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, /* 0xa0 */
 	0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x44,
-	0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, // 0xb0
+	0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, /* 0xb0 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
 	0x00, 0x00, 0x55, 0x00, 0xb1, 0xe4, 0x40, 0x00,
-	0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, // 0xd0
+	0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, /* 0xd0 */
 	0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81,
-	0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, // 0xe0
+	0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */
 	0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
-	0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, // 0xf0
+	0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */
 	0x64, 0x11, 0x40, 0xaf, 0xff, 0x00, 0x00, 0x00,
 };
 
 static u8 tbl_tw2865_ntsc_template[] = {
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x00
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x00 */
 	0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x10
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x10 */
 	0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x20
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x20 */
 	0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, // 0x30
+	0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, /* 0x30 */
 	0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f,
-	0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, // 0x40
+	0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, /* 0x40 */
 	0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+	0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43,
-	0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, // 0x70
+	0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */
 	0xE9, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80,
-	0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, // 0x80
+	0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */
 	0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00,
-	0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, // 0x90
+	0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */
 	0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13,
-	0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, // 0xa0
+	0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, /* 0xa0 */
 	0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44,
-	0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, // 0xb0
+	0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */
 	0xFF, 0xE7, 0xE9, 0xE9, 0xEB, 0xFF, 0xD6, 0xD8,
-	0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
+	0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
 	0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80,
-	0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, // 0xd0
+	0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */
 	0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81,
-	0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, // 0xe0
+	0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */
 	0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
-	0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, // 0xf0
+	0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */
 	0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0,
 };
 
 static u8 tbl_tw2865_pal_template[] = {
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x00
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x00 */
 	0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x10
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x10 */
 	0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x20
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x20 */
 	0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
-	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x30
+	0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x30 */
 	0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f,
-	0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, // 0x40
+	0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, /* 0x40 */
 	0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+	0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43,
-	0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, // 0x70
+	0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */
 	0xEA, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80,
-	0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, // 0x80
+	0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */
 	0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00,
-	0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, // 0x90
+	0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */
 	0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13,
-	0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, // 0xa0
+	0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, /* 0xa0 */
 	0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44,
-	0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, // 0xb0
+	0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */
 	0xFF, 0xE7, 0xE9, 0xE9, 0xE9, 0xFF, 0xD7, 0xD8,
-	0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
+	0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */
 	0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80,
-	0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, // 0xd0
+	0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */
 	0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81,
-	0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, // 0xe0
+	0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */
 	0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
-	0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, // 0xf0
+	0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, /* 0xf0 */
 	0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0,
 };
 
@@ -181,8 +181,8 @@
 		msleep_interruptible(1);
 	}
 
-//	printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n",
-//		addr, off, val);
+/*	printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n",
+		addr, off, val); */
 }
 
 static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr)
@@ -217,7 +217,7 @@
 
 	for (i = 0; i < 0xff; i++) {
 		/* Skip read only registers */
-		if (i >= 0xb8 && i <= 0xc1 )
+		if (i >= 0xb8 && i <= 0xc1)
 			continue;
 		if ((i & ~0x30) == 0x00 ||
 		    (i & ~0x30) == 0x0c ||
@@ -302,7 +302,7 @@
 
 	for (i = 0; i < 0xff; i++) {
 		/* Skip read only registers */
-		if (i >= 0xb8 && i <= 0xc1 )
+		if (i >= 0xb8 && i <= 0xc1)
 			continue;
 		if ((i & ~0x30) == 0x00 ||
 		    (i & ~0x30) == 0x0c ||
@@ -334,13 +334,13 @@
 	};
 
 	u8 tbl_tw2815_sfr[] = {
-		0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, // 0x00
+		0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, /* 0x00 */
 		0x64, 0x80, 0x80, 0x82, 0x82, 0x00, 0x00, 0x00,
-		0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, // 0x10
+		0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, /* 0x10 */
 		0x00, 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00,
-		0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, // 0x20
+		0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, /* 0x20 */
 		0x31, 0x75, 0xb9, 0xfd, 0x00, 0x00, 0x88, 0x88,
-		0x88, 0x11, 0x00, 0x88, 0x88, 0x00,		// 0x30
+		0x88, 0x11, 0x00, 0x88, 0x88, 0x00,		/* 0x30 */
 	};
 	u8 *tbl_tw2815_common;
 	int i;
@@ -459,7 +459,7 @@
 
 		for (i = 0; i < 0x0f; i++) {
 			if (i == 0x00)
-				continue;	// read-only
+				continue;	/* read-only */
 			solo_i2c_writebyte(solo_dev, SOLO_I2C_TW,
 					   dev_addr, (ch * 0x10) + i,
 					   tbl_tw2815_common[i]);
@@ -597,7 +597,7 @@
 	return 0;
 }
 
-/* 
+/*
  * We accessed the video status signal in the Techwell chip through
  * iic/i2c because the video status reported by register REG_VI_STATUS1
  * (address 0x012C) of the SOLO6010 chip doesn't give the correct video
@@ -751,7 +751,7 @@
 		rval = tw_readbyte(solo_dev, chip_num,
 				   TW286x_BRIGHTNESS_ADDR(ch),
 				   TW_BRIGHTNESS_ADDR(ch));
-		if (is_tw286x(solo_dev, chip_num)) 
+		if (is_tw286x(solo_dev, chip_num))
 			*val = (s32)((char)rval) + 128;
 		else
 			*val = rval;
diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c
index 097e82b..7bbb940 100644
--- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c
+++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c
@@ -24,7 +24,7 @@
 
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf-dma-sg.h>
 
 #include "solo6010.h"
 #include "solo6010-tw28.h"
@@ -47,13 +47,14 @@
 	struct videobuf_queue	vidq;
 	struct list_head	vidq_active;
 	struct task_struct	*kthread;
+	struct p2m_desc		desc[SOLO_NR_P2M_DESC];
 };
 
 static unsigned char vid_vop_header[] = {
 	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
 	0x02, 0x48, 0x05, 0xc0, 0x00, 0x40, 0x00, 0x40,
 	0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
-	0x1f, 0x4c, 0x58, 0x10, 0x78, 0x51, 0x18, 0x3e,
+	0x1f, 0x4c, 0x58, 0x10, 0x78, 0x51, 0x18, 0x3f,
 };
 
 /*
@@ -151,6 +152,11 @@
 	else
 		solo_dev->motion_mask &= ~(1 << ch);
 
+	/* Do this regardless of if we are turning on or off */
+	solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR,
+		       1 << solo_enc->ch);
+	solo_enc->motion_detected = 0;
+
 	solo_reg_write(solo_dev, SOLO_VI_MOT_ADR,
 		       SOLO_VI_MOTION_EN(solo_dev->motion_mask) |
 		       (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));
@@ -184,7 +190,7 @@
 		solo_enc->bw_weight <<= 2;
 		break;
 	default:
-		WARN(1, "mode is unknown");
+		WARN(1, "mode is unknown\n");
 	}
 }
 
@@ -211,11 +217,6 @@
 			solo_dev->enc_bw_remain -= solo_enc->bw_weight;
 	}
 
-	fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc");
-
-	if (IS_ERR(fh->kthread))
-		return PTR_ERR(fh->kthread);
-
 	fh->enc_on = 1;
 	fh->rd_idx = solo_enc->solo_dev->enc_wr_idx;
 
@@ -279,6 +280,24 @@
 	solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0);
 }
 
+static int solo_start_fh_thread(struct solo_enc_fh *fh)
+{
+	struct solo_enc_dev *solo_enc = fh->enc;
+
+	fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc");
+
+	/* Oops, we had a problem */
+	if (IS_ERR(fh->kthread)) {
+		spin_lock(&solo_enc->lock);
+		solo_enc_off(fh);
+		spin_unlock(&solo_enc->lock);
+
+		return PTR_ERR(fh->kthread);
+	}
+
+	return 0;
+}
+
 static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch)
 {
 	BUG_ON(ch >= solo_dev->nr_chans);
@@ -299,22 +318,68 @@
 	return 0;
 }
 
-static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, dma_addr_t buf,
-			      unsigned int off, unsigned int size)
+static void enc_write_sg(struct scatterlist *sglist, void *buf, int size)
+{
+	struct scatterlist *sg;
+	u8 *src = buf;
+
+	for (sg = sglist; sg && size > 0; sg = sg_next(sg)) {
+		u8 *p = sg_virt(sg);
+		size_t len = sg_dma_len(sg);
+		int i;
+
+		for (i = 0; i < len && size; i++)
+			p[i] = *(src++);
+	}
+}
+
+static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev,
+			       struct p2m_desc *desc,
+			       struct scatterlist *sglist, int skip,
+			       unsigned int off, unsigned int size)
 {
 	int ret;
 
 	if (off > SOLO_MP4E_EXT_SIZE(solo_dev))
 		return -EINVAL;
 
-	if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev))
+	if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) {
+		return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E,
+				       desc, 0, sglist, skip,
+				       SOLO_MP4E_EXT_ADDR(solo_dev) + off, size);
+	}
+
+	/* Buffer wrap */
+	ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0,
+			      sglist, skip, SOLO_MP4E_EXT_ADDR(solo_dev) + off,
+			      SOLO_MP4E_EXT_SIZE(solo_dev) - off);
+
+	ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0,
+			       sglist, skip + SOLO_MP4E_EXT_SIZE(solo_dev) - off,
+			       SOLO_MP4E_EXT_ADDR(solo_dev),
+			       size + off - SOLO_MP4E_EXT_SIZE(solo_dev));
+
+	return ret;
+}
+
+static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev,
+			      dma_addr_t buf, unsigned int off,
+			      unsigned int size)
+{
+	int ret;
+
+	if (off > SOLO_MP4E_EXT_SIZE(solo_dev))
+		return -EINVAL;
+
+	if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) {
 		return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf,
 				      SOLO_MP4E_EXT_ADDR(solo_dev) + off, size);
+	}
 
 	/* Buffer wrap */
 	ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf,
-			    SOLO_MP4E_EXT_ADDR(solo_dev) + off,
-			    SOLO_MP4E_EXT_SIZE(solo_dev) - off);
+			     SOLO_MP4E_EXT_ADDR(solo_dev) + off,
+			     SOLO_MP4E_EXT_SIZE(solo_dev) - off);
 
 	ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0,
 			      buf + SOLO_MP4E_EXT_SIZE(solo_dev) - off,
@@ -337,70 +402,108 @@
 	return ret;
 }
 
-static int enc_get_jpeg_dma(struct solo6010_dev *solo_dev, dma_addr_t buf,
-			    unsigned int off, unsigned int size)
+static int enc_get_jpeg_dma_sg(struct solo6010_dev *solo_dev,
+			       struct p2m_desc *desc,
+			       struct scatterlist *sglist, int skip,
+			       unsigned int off, unsigned int size)
 {
 	int ret;
 
 	if (off > SOLO_JPEG_EXT_SIZE(solo_dev))
 		return -EINVAL;
 
-	if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev))
-		return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, buf,
-				      SOLO_JPEG_EXT_ADDR(solo_dev) + off, size);
+	if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev)) {
+		return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG,
+				       desc, 0, sglist, skip,
+				       SOLO_JPEG_EXT_ADDR(solo_dev) + off, size);
+	}
 
 	/* Buffer wrap */
-	ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, buf,
-			     SOLO_JPEG_EXT_ADDR(solo_dev) + off,
-			     SOLO_JPEG_EXT_SIZE(solo_dev) - off);
+	ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0,
+			      sglist, skip, SOLO_JPEG_EXT_ADDR(solo_dev) + off,
+			      SOLO_JPEG_EXT_SIZE(solo_dev) - off);
 
-	ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0,
-			      buf + SOLO_JPEG_EXT_SIZE(solo_dev) - off,
-			      SOLO_JPEG_EXT_ADDR(solo_dev),
-			      size + off - SOLO_JPEG_EXT_SIZE(solo_dev));
+	ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0,
+			       sglist, skip + SOLO_JPEG_EXT_SIZE(solo_dev) - off,
+			       SOLO_JPEG_EXT_ADDR(solo_dev),
+			       size + off - SOLO_JPEG_EXT_SIZE(solo_dev));
 
 	return ret;
 }
 
-static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
-			  struct videobuf_buffer *vb, dma_addr_t vbuf)
+/* Returns true of __chk is within the first __range bytes of __off */
+#define OFF_IN_RANGE(__off, __range, __chk) \
+	((__off <= __chk) && ((__off + __range) >= __chk))
+
+static void solo_jpeg_header(struct solo_enc_dev *solo_enc,
+			     struct videobuf_dmabuf *vbuf)
 {
-	struct solo_enc_dev *solo_enc = fh->enc;
-	struct solo6010_dev *solo_dev = solo_enc->solo_dev;
-	u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
+	struct scatterlist *sg;
+	void *src = jpeg_header;
+	size_t copied = 0;
+	size_t to_copy = sizeof(jpeg_header);
 
-	memcpy(p, jpeg_header, sizeof(jpeg_header));
-	p[SOF0_START + 5] = 0xff & (solo_enc->height >> 8);
-	p[SOF0_START + 6] = 0xff & solo_enc->height;
-	p[SOF0_START + 7] = 0xff & (solo_enc->width >> 8);
-	p[SOF0_START + 8] = 0xff & solo_enc->width;
+	for (sg = vbuf->sglist; sg && copied < to_copy; sg = sg_next(sg)) {
+		size_t this_copy = min(sg_dma_len(sg),
+				       (unsigned int)(to_copy - copied));
+		u8 *p = sg_virt(sg);
 
-	vbuf += sizeof(jpeg_header);
-	vb->size = enc_buf->jpeg_size + sizeof(jpeg_header);
+		memcpy(p, src + copied, this_copy);
 
-	return enc_get_jpeg_dma(solo_dev, vbuf, enc_buf->jpeg_off,
-				enc_buf->jpeg_size);
+		if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 5))
+			p[(SOF0_START + 5) - copied] =
+				0xff & (solo_enc->height >> 8);
+		if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 6))
+			p[(SOF0_START + 6) - copied] = 0xff & solo_enc->height;
+		if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 7))
+			p[(SOF0_START + 7) - copied] =
+				0xff & (solo_enc->width >> 8);
+		if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 8))
+			p[(SOF0_START + 8) - copied] = 0xff & solo_enc->width;
+
+		copied += this_copy;
+	}
+}
+
+static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
+			  struct videobuf_buffer *vb,
+			  struct videobuf_dmabuf *vbuf)
+{
+	struct solo6010_dev *solo_dev = fh->enc->solo_dev;
+	int size = enc_buf->jpeg_size;
+
+	/* Copy the header first (direct write) */
+	solo_jpeg_header(fh->enc, vbuf);
+
+	vb->size = size + sizeof(jpeg_header);
+
+	/* Grab the jpeg frame */
+	return enc_get_jpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist,
+				   sizeof(jpeg_header),
+				   enc_buf->jpeg_off, size);
 }
 
 static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
-			  struct videobuf_buffer *vb, dma_addr_t vbuf)
+			  struct videobuf_buffer *vb,
+			  struct videobuf_dmabuf *vbuf)
 {
 	struct solo_enc_dev *solo_enc = fh->enc;
 	struct solo6010_dev *solo_dev = solo_enc->solo_dev;
 	struct vop_header vh;
 	int ret;
 	int frame_size, frame_off;
+	int skip = 0;
 
 	if (WARN_ON_ONCE(enc_buf->size <= sizeof(vh)))
-		return -1;
+		return -EINVAL;
 
 	/* First get the hardware vop header (not real mpeg) */
 	ret = enc_get_mpeg_dma(solo_dev, &vh, enc_buf->off, sizeof(vh));
-	if (ret)
-		return -1;
+	if (WARN_ON_ONCE(ret))
+		return ret;
 
 	if (WARN_ON_ONCE(vh.size > enc_buf->size))
-		return -1;
+		return -EINVAL;
 
 	vb->width = vh.hsize << 4;
 	vb->height = vh.vsize << 4;
@@ -410,9 +513,9 @@
 	if (!enc_buf->vop) {
 		u16 fps = solo_dev->fps * 1000;
 		u16 interval = solo_enc->interval * 1000;
-		u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
+		u8 p[sizeof(vid_vop_header)];
 
-		memcpy(p, vid_vop_header, sizeof(vid_vop_header));
+		memcpy(p, vid_vop_header, sizeof(p));
 
 		if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
 			p[10] |= ((XVID_PAR_43_NTSC << 3) & 0x78);
@@ -434,43 +537,49 @@
 		if (vh.interlace)
 			p[29] |= 0x20;
 
+		enc_write_sg(vbuf->sglist, p, sizeof(p));
+
 		/* Adjust the dma buffer past this header */
 		vb->size += sizeof(vid_vop_header);
-		vbuf += sizeof(vid_vop_header);
+		skip = sizeof(vid_vop_header);
 	}
 
 	/* Now get the actual mpeg payload */
 	frame_off = (enc_buf->off + sizeof(vh)) % SOLO_MP4E_EXT_SIZE(solo_dev);
 	frame_size = enc_buf->size - sizeof(vh);
-	ret = enc_get_mpeg_dma_t(solo_dev, vbuf, frame_off, frame_size);
-	if (WARN_ON_ONCE(ret))
-		return -1;
 
-	return 0;
+	ret = enc_get_mpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist,
+				  skip, frame_off, frame_size);
+	WARN_ON_ONCE(ret);
+
+	return ret;
 }
 
-/* On successful return (0), leaves solo_enc->lock unlocked */
-static int solo_enc_fillbuf(struct solo_enc_fh *fh,
+static void solo_enc_fillbuf(struct solo_enc_fh *fh,
 			    struct videobuf_buffer *vb)
 {
 	struct solo_enc_dev *solo_enc = fh->enc;
 	struct solo6010_dev *solo_dev = solo_enc->solo_dev;
 	struct solo_enc_buf *enc_buf = NULL;
-	dma_addr_t vbuf;
+	struct videobuf_dmabuf *vbuf;
 	int ret;
+	int error = 1;
 	u16 idx = fh->rd_idx;
 
 	while (idx != solo_dev->enc_wr_idx) {
 		struct solo_enc_buf *ebuf = &solo_dev->enc_buf[idx];
+
 		idx = (idx + 1) % SOLO_NR_RING_BUFS;
+
+		if (ebuf->ch != solo_enc->ch)
+			continue;
+
 		if (fh->fmt == V4L2_PIX_FMT_MPEG) {
-			if (fh->type != ebuf->type)
-				continue;
-			if (ebuf->ch == solo_enc->ch) {
+			if (fh->type == ebuf->type) {
 				enc_buf = ebuf;
 				break;
 			}
-		} else if (ebuf->ch == solo_enc->ch) {
+		} else {
 			/* For mjpeg, keep reading to the newest frame */
 			enc_buf = ebuf;
 		}
@@ -478,48 +587,55 @@
 
 	fh->rd_idx = idx;
 
-	if (!enc_buf)
-		return -1;
+	if (WARN_ON_ONCE(!enc_buf))
+		goto buf_err;
 
 	if ((fh->fmt == V4L2_PIX_FMT_MPEG &&
 	     vb->bsize < enc_buf->size) ||
 	    (fh->fmt == V4L2_PIX_FMT_MJPEG &&
 	     vb->bsize < (enc_buf->jpeg_size + sizeof(jpeg_header)))) {
-		return -1;
+		WARN_ON_ONCE(1);
+		goto buf_err;
 	}
 
-	if (!(vbuf = videobuf_to_dma_contig(vb)))
-		return -1;
-
-	/* Is it ok that we mess with this buffer out of lock? */
-	spin_unlock(&solo_enc->lock);
+	vbuf = videobuf_to_dma(vb);
+	if (WARN_ON_ONCE(!vbuf))
+		goto buf_err;
 
 	if (fh->fmt == V4L2_PIX_FMT_MPEG)
 		ret = solo_fill_mpeg(fh, enc_buf, vb, vbuf);
 	else
 		ret = solo_fill_jpeg(fh, enc_buf, vb, vbuf);
 
-	if (ret) // Ignore failures
-		return 0;
+	if (!ret)
+		error = 0;
 
-	list_del(&vb->queue);
-	vb->field_count++;
-	vb->ts = enc_buf->ts;
-	vb->state = VIDEOBUF_DONE;
+buf_err:
+	if (error) {
+		vb->state = VIDEOBUF_ERROR;
+	} else {
+		vb->field_count++;
+		vb->ts = enc_buf->ts;
+		vb->state = VIDEOBUF_DONE;
+	}
 
 	wake_up(&vb->done);
 
-	return 0;
+	return;
 }
 
 static void solo_enc_thread_try(struct solo_enc_fh *fh)
 {
 	struct solo_enc_dev *solo_enc = fh->enc;
+	struct solo6010_dev *solo_dev = solo_enc->solo_dev;
 	struct videobuf_buffer *vb;
 
 	for (;;) {
 		spin_lock(&solo_enc->lock);
 
+		if (fh->rd_idx == solo_dev->enc_wr_idx)
+			break;
+
 		if (list_empty(&fh->vidq_active))
 			break;
 
@@ -529,9 +645,11 @@
 		if (!waitqueue_active(&vb->done))
 			break;
 
-		/* On success, returns with solo_enc->lock unlocked */
-		if (solo_enc_fillbuf(fh, vb))
-			break;
+		list_del(&vb->queue);
+
+		spin_unlock(&solo_enc->lock);
+
+		solo_enc_fillbuf(fh, vb);
 	}
 
 	assert_spin_locked(&solo_enc->lock);
@@ -557,7 +675,7 @@
 
 	remove_wait_queue(&solo_enc->thread_wait, &wait);
 
-        return 0;
+	return 0;
 }
 
 void solo_motion_isr(struct solo6010_dev *solo_dev)
@@ -614,7 +732,8 @@
 		jpeg_next = solo_reg_read(solo_dev,
 					SOLO_VE_JPEG_QUE(solo_dev->enc_idx));
 
-		if ((ch = (mpeg_current >> 24) & 0x1f) >= SOLO_MAX_CHANNELS) {
+		ch = (mpeg_current >> 24) & 0x1f;
+		if (ch >= SOLO_MAX_CHANNELS) {
 			ch -= SOLO_MAX_CHANNELS;
 			enc_type = SOLO_ENC_TYPE_EXT;
 		} else
@@ -669,12 +788,12 @@
 static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count,
 			      unsigned int *size)
 {
-        *size = FRAME_BUF_SIZE;
+	*size = FRAME_BUF_SIZE;
 
-        if (*count < MIN_VID_BUFFERS)
+	if (*count < MIN_VID_BUFFERS)
 		*count = MIN_VID_BUFFERS;
 
-        return 0;
+	return 0;
 }
 
 static int solo_enc_buf_prepare(struct videobuf_queue *vq,
@@ -696,7 +815,9 @@
 	if (vb->state == VIDEOBUF_NEEDS_INIT) {
 		int rc = videobuf_iolock(vq, vb, NULL);
 		if (rc < 0) {
-			videobuf_dma_contig_free(vq, vb);
+			struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+			videobuf_dma_unmap(vq->dev, dma);
+			videobuf_dma_free(dma);
 			vb->state = VIDEOBUF_NEEDS_INIT;
 			return rc;
 		}
@@ -719,7 +840,10 @@
 static void solo_enc_buf_release(struct videobuf_queue *vq,
 				 struct videobuf_buffer *vb)
 {
-	videobuf_dma_contig_free(vq, vb);
+	struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+
+	videobuf_dma_unmap(vq->dev, dma);
+	videobuf_dma_free(dma);
 	vb->state = VIDEOBUF_NEEDS_INIT;
 }
 
@@ -750,25 +874,22 @@
 	struct solo_enc_dev *solo_enc = video_drvdata(file);
 	struct solo_enc_fh *fh;
 
-	if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL)
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (fh == NULL)
 		return -ENOMEM;
 
-	spin_lock(&solo_enc->lock);
-
 	fh->enc = solo_enc;
 	file->private_data = fh;
 	INIT_LIST_HEAD(&fh->vidq_active);
 	fh->fmt = V4L2_PIX_FMT_MPEG;
 	fh->type = SOLO_ENC_TYPE_STD;
 
-	videobuf_queue_dma_contig_init(&fh->vidq, &solo_enc_video_qops,
-				    &solo_enc->solo_dev->pdev->dev,
-				    &solo_enc->lock,
-				    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-				    V4L2_FIELD_INTERLACED,
-				    sizeof(struct videobuf_buffer), fh, NULL);
-
-	spin_unlock(&solo_enc->lock);
+	videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops,
+			       &solo_enc->solo_dev->pdev->dev,
+			       &solo_enc->lock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct videobuf_buffer), fh, NULL);
 
 	return 0;
 }
@@ -785,7 +906,11 @@
 
 		spin_lock(&solo_enc->lock);
 		ret = solo_enc_on(fh);
-	        spin_unlock(&solo_enc->lock);
+		spin_unlock(&solo_enc->lock);
+		if (ret)
+			return ret;
+
+		ret = solo_start_fh_thread(fh);
 		if (ret)
 			return ret;
 	}
@@ -797,10 +922,15 @@
 static int solo_enc_release(struct file *file)
 {
 	struct solo_enc_fh *fh = file->private_data;
+	struct solo_enc_dev *solo_enc = fh->enc;
 
 	videobuf_stop(&fh->vidq);
 	videobuf_mmap_free(&fh->vidq);
+
+	spin_lock(&solo_enc->lock);
 	solo_enc_off(fh);
+	spin_unlock(&solo_enc->lock);
+
 	kfree(fh);
 
 	return 0;
@@ -842,7 +972,7 @@
 	if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
 		input->std = V4L2_STD_NTSC_M;
 	else
-		input->std = V4L2_STD_PAL_M;
+		input->std = V4L2_STD_PAL_B;
 
 	if (!tw28_get_video_status(solo_dev, solo_enc->ch))
 		input->status = V4L2_IN_ST_NO_SIGNAL;
@@ -915,9 +1045,8 @@
 
 	if (pix->field == V4L2_FIELD_ANY)
 		pix->field = V4L2_FIELD_INTERLACED;
-	else if (pix->field != V4L2_FIELD_INTERLACED) {
+	else if (pix->field != V4L2_FIELD_INTERLACED)
 		pix->field = V4L2_FIELD_INTERLACED;
-	}
 
 	/* Just set these */
 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
@@ -937,7 +1066,8 @@
 
 	spin_lock(&solo_enc->lock);
 
-	if ((ret = solo_enc_try_fmt_cap(file, priv, f))) {
+	ret = solo_enc_try_fmt_cap(file, priv, f);
+	if (ret) {
 		spin_unlock(&solo_enc->lock);
 		return ret;
 	}
@@ -956,7 +1086,10 @@
 
 	spin_unlock(&solo_enc->lock);
 
-	return ret;
+	if (ret)
+		return ret;
+
+	return solo_start_fh_thread(fh);
 }
 
 static int solo_enc_get_fmt_cap(struct file *file, void *priv,
@@ -977,7 +1110,7 @@
 	return 0;
 }
 
-static int solo_enc_reqbufs(struct file *file, void *priv, 
+static int solo_enc_reqbufs(struct file *file, void *priv,
 			    struct v4l2_requestbuffers *req)
 {
 	struct solo_enc_fh *fh = priv;
@@ -1014,6 +1147,10 @@
 		spin_unlock(&solo_enc->lock);
 		if (ret)
 			return ret;
+
+		ret = solo_start_fh_thread(fh);
+		if (ret)
+			return ret;
 	}
 
 	ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK);
@@ -1033,12 +1170,16 @@
 
 	/* Check for key frame on mpeg data */
 	if (fh->fmt == V4L2_PIX_FMT_MPEG) {
-		struct videobuf_buffer *vb = fh->vidq.bufs[buf->index];
-		u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
-		if (p[3] == 0x00)
-			buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
-		else
-			buf->flags |= V4L2_BUF_FLAG_PFRAME;
+		struct videobuf_dmabuf *vbuf =
+				videobuf_to_dma(fh->vidq.bufs[buf->index]);
+
+		if (vbuf) {
+			u8 *p = sg_virt(vbuf->sglist);
+			if (p[3] == 0x00)
+				buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+			else
+				buf->flags |= V4L2_BUF_FLAG_PFRAME;
+		}
 	}
 
 	return 0;
@@ -1136,7 +1277,7 @@
 	/* XXX: Shouldn't we be able to get/set this from videobuf? */
 	cp->readbuffers = 2;
 
-        return 0;
+	return 0;
 }
 
 static int solo_s_parm(struct file *file, void *priv,
@@ -1176,7 +1317,7 @@
 
 	spin_unlock(&solo_enc->lock);
 
-        return 0;
+	return 0;
 }
 
 static int solo_queryctrl(struct file *file, void *priv,
@@ -1240,7 +1381,7 @@
 		return 0;
 	}
 
-        return -EINVAL;
+	return -EINVAL;
 }
 
 static int solo_querymenu(struct file *file, void *priv,
@@ -1250,7 +1391,8 @@
 	int err;
 
 	qctrl.id = qmenu->id;
-	if ((err = solo_queryctrl(file, priv, &qctrl)))
+	err = solo_queryctrl(file, priv, &qctrl);
+	if (err)
 		return err;
 
 	return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
@@ -1350,9 +1492,9 @@
 		switch (ctrl->id) {
 		case V4L2_CID_RDS_TX_RADIO_TEXT:
 			if (ctrl->size - 1 > OSD_TEXT_MAX)
-                                err = -ERANGE;
+				err = -ERANGE;
 			else {
-                        	err = copy_from_user(solo_enc->osd_text,
+				err = copy_from_user(solo_enc->osd_text,
 						     ctrl->string,
 						     OSD_TEXT_MAX);
 				solo_enc->osd_text[OSD_TEXT_MAX] = '\0';
@@ -1459,7 +1601,7 @@
 	.minor			= -1,
 	.release		= video_device_release,
 
-	.tvnorms		= V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
+	.tvnorms		= V4L2_STD_NTSC_M | V4L2_STD_PAL_B,
 	.current_norm		= V4L2_STD_NTSC_M,
 };
 
@@ -1505,7 +1647,7 @@
 	atomic_set(&solo_enc->readers, 0);
 
 	solo_enc->qp = SOLO_DEFAULT_QP;
-        solo_enc->gop = solo_dev->fps;
+	solo_enc->gop = solo_dev->fps;
 	solo_enc->interval = 1;
 	solo_enc->mode = SOLO_ENC_MODE_CIF;
 	solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c
index 6ffd21d..a8491dc 100644
--- a/drivers/staging/solo6x10/solo6010-v4l2.c
+++ b/drivers/staging/solo6x10/solo6010-v4l2.c
@@ -24,14 +24,13 @@
 
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf-dma-sg.h>
 
 #include "solo6010.h"
 #include "solo6010-tw28.h"
 
 #define SOLO_HW_BPL		2048
 #define SOLO_DISP_PIX_FIELD	V4L2_FIELD_INTERLACED
-#define SOLO_DISP_BUF_SIZE	(64 * 1024) // 64k
 
 /* Image size is two fields, SOLO_HW_BPL is one horizontal line */
 #define solo_vlines(__solo)	(__solo->video_vsize * 2)
@@ -49,6 +48,8 @@
 	spinlock_t		slock;
 	int			old_write;
 	struct list_head	vidq_active;
+	struct p2m_desc		desc[SOLO_NR_P2M_DESC];
+	int			desc_idx;
 };
 
 unsigned video_nr = -1;
@@ -96,7 +97,7 @@
 		       SOLO_VI_WIN_EX(ex) |
 		       SOLO_VI_WIN_SCALE(scale));
 
-        solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch),
+	solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch),
 		       SOLO_VI_WIN_SY(sy) |
 		       SOLO_VI_WIN_EY(ey));
 }
@@ -203,50 +204,149 @@
 	return 0;
 }
 
+static void disp_reset_desc(struct solo_filehandle *fh)
+{
+	/* We use desc mode, which ignores desc 0 */
+	memset(fh->desc, 0, sizeof(*fh->desc));
+	fh->desc_idx = 1;
+}
+
+static int disp_flush_descs(struct solo_filehandle *fh)
+{
+	int ret;
+
+	if (!fh->desc_idx)
+		return 0;
+
+	ret = solo_p2m_dma_desc(fh->solo_dev, SOLO_P2M_DMA_ID_DISP,
+				fh->desc, fh->desc_idx);
+	disp_reset_desc(fh);
+
+	return ret;
+}
+
+static int disp_push_desc(struct solo_filehandle *fh, dma_addr_t dma_addr,
+		      u32 ext_addr, int size, int repeat, int ext_size)
+{
+	if (fh->desc_idx >= SOLO_NR_P2M_DESC) {
+		int ret = disp_flush_descs(fh);
+		if (ret)
+			return ret;
+	}
+
+	solo_p2m_push_desc(&fh->desc[fh->desc_idx], 0, dma_addr, ext_addr,
+			   size, repeat, ext_size);
+	fh->desc_idx++;
+
+	return 0;
+}
+
 static void solo_fillbuf(struct solo_filehandle *fh,
 			 struct videobuf_buffer *vb)
 {
 	struct solo6010_dev *solo_dev = fh->solo_dev;
-	dma_addr_t vbuf;
+	struct videobuf_dmabuf *vbuf;
 	unsigned int fdma_addr;
-	int frame_size;
 	int error = 1;
 	int i;
+	struct scatterlist *sg;
+	dma_addr_t sg_dma;
+	int sg_size_left;
 
-	if (!(vbuf = videobuf_to_dma_contig(vb)))
+	vbuf = videobuf_to_dma(vb);
+	if (!vbuf)
 		goto finish_buf;
 
 	if (erase_off(solo_dev)) {
-		void *p = videobuf_queue_to_vaddr(&fh->vidq, vb);
-		int image_size = solo_image_size(solo_dev);
-		for (i = 0; i < image_size; i += 2) {
-			((u8 *)p)[i] = 0x80;
-			((u8 *)p)[i + 1] = 0x00;
+		int i;
+
+		/* Just blit to the entire sg list, ignoring size */
+		for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) {
+			void *p = sg_virt(sg);
+			size_t len = sg_dma_len(sg);
+
+			for (i = 0; i < len; i += 2) {
+				((u8 *)p)[i] = 0x80;
+				((u8 *)p)[i + 1] = 0x00;
+			}
 		}
+
 		error = 0;
 		goto finish_buf;
 	}
 
-	frame_size = SOLO_HW_BPL * solo_vlines(solo_dev);
-	fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * frame_size);
+	disp_reset_desc(fh);
+	sg = vbuf->sglist;
+	sg_dma = sg_dma_address(sg);
+	sg_size_left = sg_dma_len(sg);
 
-	for (i = 0; i < frame_size / SOLO_DISP_BUF_SIZE; i++) {
-		int j;
-		for (j = 0; j < (SOLO_DISP_BUF_SIZE / SOLO_HW_BPL); j++) {
-			if (solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_DISP, 0,
-					   vbuf, fdma_addr + (j * SOLO_HW_BPL),
-					   solo_bytesperline(solo_dev)))
+	fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write *
+			(SOLO_HW_BPL * solo_vlines(solo_dev)));
+
+	for (i = 0; i < solo_vlines(solo_dev); i++) {
+		int line_len = solo_bytesperline(solo_dev);
+		int lines;
+
+		if (!sg_size_left) {
+			sg = sg_next(sg);
+			if (sg == NULL)
 				goto finish_buf;
-			vbuf += solo_bytesperline(solo_dev);
+			sg_dma = sg_dma_address(sg);
+			sg_size_left = sg_dma_len(sg);
 		}
-		fdma_addr += SOLO_DISP_BUF_SIZE;
+
+		/* No room for an entire line, so chunk it up */
+		if (sg_size_left < line_len) {
+			int this_addr = fdma_addr;
+
+			while (line_len > 0) {
+				int this_write;
+
+				if (!sg_size_left) {
+					sg = sg_next(sg);
+					if (sg == NULL)
+						goto finish_buf;
+					sg_dma = sg_dma_address(sg);
+					sg_size_left = sg_dma_len(sg);
+				}
+
+				this_write = min(sg_size_left, line_len);
+
+				if (disp_push_desc(fh, sg_dma, this_addr,
+						   this_write, 0, 0))
+					goto finish_buf;
+
+				line_len -= this_write;
+				sg_size_left -= this_write;
+				sg_dma += this_write;
+				this_addr += this_write;
+			}
+
+			fdma_addr += SOLO_HW_BPL;
+			continue;
+		}
+
+		/* Shove as many lines into a repeating descriptor as possible */
+		lines = min(sg_size_left / line_len,
+			    solo_vlines(solo_dev) - i);
+
+		if (disp_push_desc(fh, sg_dma, fdma_addr, line_len,
+				   lines - 1, SOLO_HW_BPL))
+			goto finish_buf;
+
+		i += lines - 1;
+		fdma_addr += SOLO_HW_BPL * lines;
+		sg_dma += lines * line_len;
+		sg_size_left -= lines * line_len;
 	}
-	error = 0;
+
+	error = disp_flush_descs(fh);
 
 finish_buf:
 	if (error) {
 		vb->state = VIDEOBUF_ERROR;
 	} else {
+		vb->size = solo_vlines(solo_dev) * solo_bytesperline(solo_dev);
 		vb->state = VIDEOBUF_DONE;
 		vb->field_count++;
 		do_gettimeofday(&vb->ts);
@@ -275,7 +375,7 @@
 			break;
 
 		cur_write = SOLO_VI_STATUS0_PAGE(solo_reg_read(fh->solo_dev,
-							SOLO_VI_STATUS0));
+						 SOLO_VI_STATUS0));
 		if (cur_write == fh->old_write)
 			break;
 
@@ -310,7 +410,7 @@
 
 	remove_wait_queue(&solo_dev->disp_thread_wait, &wait);
 
-        return 0;
+	return 0;
 }
 
 static int solo_start_thread(struct solo_filehandle *fh)
@@ -337,12 +437,12 @@
 	struct solo_filehandle *fh = vq->priv_data;
 	struct solo6010_dev *solo_dev  = fh->solo_dev;
 
-        *size = solo_image_size(solo_dev);
+	*size = solo_image_size(solo_dev);
 
-        if (*count < MIN_VID_BUFFERS)
+	if (*count < MIN_VID_BUFFERS)
 		*count = MIN_VID_BUFFERS;
 
-        return 0;
+	return 0;
 }
 
 static int solo_buf_prepare(struct videobuf_queue *vq,
@@ -364,7 +464,9 @@
 	if (vb->state == VIDEOBUF_NEEDS_INIT) {
 		int rc = videobuf_iolock(vq, vb, NULL);
 		if (rc < 0) {
-			videobuf_dma_contig_free(vq, vb);
+			struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+			videobuf_dma_unmap(vq->dev, dma);
+			videobuf_dma_free(dma);
 			vb->state = VIDEOBUF_NEEDS_INIT;
 			return rc;
 		}
@@ -388,7 +490,10 @@
 static void solo_buf_release(struct videobuf_queue *vq,
 			     struct videobuf_buffer *vb)
 {
-	videobuf_dma_contig_free(vq, vb);
+	struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+
+	videobuf_dma_unmap(vq->dev, dma);
+	videobuf_dma_free(dma);
 	vb->state = VIDEOBUF_NEEDS_INIT;
 }
 
@@ -404,7 +509,7 @@
 {
 	struct solo_filehandle *fh = file->private_data;
 
-        return videobuf_poll_stream(file, &fh->vidq, wait);
+	return videobuf_poll_stream(file, &fh->vidq, wait);
 }
 
 static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
@@ -420,7 +525,8 @@
 	struct solo_filehandle *fh;
 	int ret;
 
-	if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL)
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (fh == NULL)
 		return -ENOMEM;
 
 	spin_lock_init(&fh->slock);
@@ -428,16 +534,17 @@
 	fh->solo_dev = solo_dev;
 	file->private_data = fh;
 
-	if ((ret = solo_start_thread(fh))) {
+	ret = solo_start_thread(fh);
+	if (ret) {
 		kfree(fh);
 		return ret;
 	}
 
-	videobuf_queue_dma_contig_init(&fh->vidq, &solo_video_qops,
-				    &solo_dev->pdev->dev, &fh->slock,
-				    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-				    SOLO_DISP_PIX_FIELD,
-				    sizeof(struct videobuf_buffer), fh, NULL);
+	videobuf_queue_sg_init(&fh->vidq, &solo_video_qops,
+			       &solo_dev->pdev->dev, &fh->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       SOLO_DISP_PIX_FIELD,
+			       sizeof(struct videobuf_buffer), fh, NULL);
 
 	return 0;
 }
@@ -530,7 +637,7 @@
 	if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
 		input->std = V4L2_STD_NTSC_M;
 	else
-		input->std = V4L2_STD_PAL_M;
+		input->std = V4L2_STD_PAL_B;
 
 	return 0;
 }
@@ -622,7 +729,7 @@
 	return 0;
 }
 
-static int solo_reqbufs(struct file *file, void *priv, 
+static int solo_reqbufs(struct file *file, void *priv,
 			struct v4l2_requestbuffers *req)
 {
 	struct solo_filehandle *fh = priv;
@@ -781,11 +888,11 @@
 	.vidioc_qbuf			= solo_qbuf,
 	.vidioc_dqbuf			= solo_dqbuf,
 	.vidioc_streamon		= solo_streamon,
-        .vidioc_streamoff		= solo_streamoff,
+	.vidioc_streamoff		= solo_streamoff,
 	/* Controls */
 	.vidioc_queryctrl		= solo_disp_queryctrl,
-        .vidioc_g_ctrl			= solo_disp_g_ctrl,
-        .vidioc_s_ctrl			= solo_disp_s_ctrl,
+	.vidioc_g_ctrl			= solo_disp_g_ctrl,
+	.vidioc_s_ctrl			= solo_disp_s_ctrl,
 };
 
 static struct video_device solo_v4l2_template = {
@@ -795,7 +902,7 @@
 	.minor			= -1,
 	.release		= video_device_release,
 
-	.tvnorms		= V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
+	.tvnorms		= V4L2_STD_NTSC_M | V4L2_STD_PAL_B,
 	.current_norm		= V4L2_STD_NTSC_M,
 };
 
@@ -836,13 +943,13 @@
 	for (i = 0; i < solo_dev->nr_chans; i++) {
 		solo_v4l2_set_ch(solo_dev, i);
 		while (erase_off(solo_dev))
-			;// Do nothing
+			;/* Do nothing */
 	}
 
 	/* Set the default display channel */
 	solo_v4l2_set_ch(solo_dev, 0);
 	while (erase_off(solo_dev))
-		;// Do nothing
+		;/* Do nothing */
 
 	solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN);
 
diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h
index dca8e3e..9c930f3 100644
--- a/drivers/staging/solo6x10/solo6010.h
+++ b/drivers/staging/solo6x10/solo6010.h
@@ -26,8 +26,8 @@
 #include <linux/semaphore.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
-#include <linux/delay.h>
 #include <linux/wait.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
 
@@ -48,10 +48,14 @@
 #define PCI_DEVICE_ID_NEUSOLO_4		0x4304
 #define PCI_DEVICE_ID_NEUSOLO_9		0x4309
 #define PCI_DEVICE_ID_NEUSOLO_16	0x4310
-/* Commell Softlogic 6010 based cards */
-#define PCI_DEVICE_ID_COMMSOLO_4	0x4E04
-#define PCI_DEVICE_ID_COMMSOLO_9	0x4E09
-#define PCI_DEVICE_ID_COMMSOLO_16	0x4E10
+/* Bluecherry Softlogic 6010 based cards */
+#define PCI_DEVICE_ID_BC_SOLO_4		0x4E04
+#define PCI_DEVICE_ID_BC_SOLO_9		0x4E09
+#define PCI_DEVICE_ID_BC_SOLO_16	0x4E10
+/* Bluecherry Softlogic 6110 based cards */
+#define PCI_DEVICE_ID_BC_6110_4		0x5304
+#define PCI_DEVICE_ID_BC_6110_8		0x5308
+#define PCI_DEVICE_ID_BC_6110_16	0x5310
 #endif /* Bluecherry */
 
 #define SOLO6010_NAME			"solo6010"
@@ -64,7 +68,7 @@
 #define SOLO6010_VER_MINOR		0
 #define SOLO6010_VER_SUB		0
 #define SOLO6010_VER_NUM \
-    KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB)
+	KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB)
 
 /*
  * The SOLO6010 actually has 8 i2c channels, but we only use 2.
@@ -78,7 +82,6 @@
 /* DMA Engine setup */
 #define SOLO_NR_P2M			4
 #define SOLO_NR_P2M_DESC		256
-#define SOLO_P2M_DESC_SIZE		(SOLO_NR_P2M_DESC * 16)
 /* MPEG and JPEG share the same interrupt and locks so they must be together
  * in the same dma channel. */
 #define SOLO_P2M_DMA_ID_MP4E		0
@@ -123,11 +126,17 @@
 	IIC_STATE_STOP
 };
 
+struct p2m_desc {
+	u32 ctrl;
+	u32 ext;
+	u32 ta;
+	u32 fa;
+};
+
 struct solo_p2m_dev {
-	struct semaphore	sem;
+	struct mutex		mutex;
 	struct completion	completion;
 	int			error;
-	u8			desc[SOLO_P2M_DESC_SIZE];
 };
 
 #define OSD_TEXT_MAX		30
@@ -185,7 +194,7 @@
 	/* i2c related items */
 	struct i2c_adapter	i2c_adap[SOLO_I2C_ADAPTERS];
 	enum SOLO_I2C_STATE	i2c_state;
-	struct semaphore	i2c_sem;
+	struct mutex		i2c_mutex;
 	int			i2c_id;
 	wait_queue_head_t	i2c_wait;
 	struct i2c_msg		*i2c_msg;
@@ -212,7 +221,7 @@
 	struct solo_enc_buf	enc_buf[SOLO_NR_RING_BUFS];
 
 	/* Current video settings */
-	u32 			video_type;
+	u32			video_type;
 	u16			video_hsize, video_vsize;
 	u16			vout_hstart, vout_vstart;
 	u16			vin_hstart, vin_vstart;
@@ -306,6 +315,14 @@
 		   dma_addr_t dma_addr, u32 ext_addr, u32 size);
 int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr,
 		 void *sys_addr, u32 ext_addr, u32 size);
+int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id,
+		    struct p2m_desc *pdesc, int wr,
+		    struct scatterlist *sglist, u32 sg_off,
+		    u32 ext_addr, u32 size);
+void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr,
+			u32 ext_addr, u32 size, int repeat, u32 ext_size);
+int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id,
+		      struct p2m_desc *desc, int desc_count);
 
 /* Set the threshold for motion detection */
 void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val);
diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h
index 840bddb..d36c90e 100644
--- a/drivers/staging/speakup/spk_types.h
+++ b/drivers/staging/speakup/spk_types.h
@@ -52,7 +52,7 @@
 
 #define COLOR_BUFFER_SIZE 160
 
-struct spk_highlight_color_track{
+struct spk_highlight_color_track {
 	/* Count of each background color */
 	unsigned int bgcount[8];
 	/* Buffer for characters drawn with each background color */
diff --git a/drivers/staging/spectra/lld_emu.c b/drivers/staging/spectra/lld_emu.c
index 6733bbf..095f2f0 100644
--- a/drivers/staging/spectra/lld_emu.c
+++ b/drivers/staging/spectra/lld_emu.c
@@ -180,10 +180,8 @@
 	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
 		       __FILE__, __LINE__, __func__);
 
-	flash_memory[0] = (u8 *)vmalloc(GLOB_LLD_PAGE_SIZE *
-						   GLOB_LLD_BLOCKS *
-						   GLOB_LLD_PAGES *
-						   sizeof(u8));
+	flash_memory[0] = vmalloc(GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS *
+				  GLOB_LLD_PAGES * sizeof(u8));
 	if (!flash_memory[0]) {
 		printk(KERN_ERR "Fail to allocate memory "
 		       "for nand emulator!\n");
diff --git a/drivers/staging/ste_rmi4/Kconfig b/drivers/staging/ste_rmi4/Kconfig
new file mode 100644
index 0000000..95fd5a9
--- /dev/null
+++ b/drivers/staging/ste_rmi4/Kconfig
@@ -0,0 +1,9 @@
+config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
+	tristate "Synaptics i2c rmi4 touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have a Synaptics RMI4 and
+	  want to enable support for the built-in touchscreen.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_rmi4_ts.
diff --git a/drivers/staging/ste_rmi4/Makefile b/drivers/staging/ste_rmi4/Makefile
new file mode 100644
index 0000000..6cce2ed1
--- /dev/null
+++ b/drivers/staging/ste_rmi4/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for the RMI4 touchscreen driver.
+#
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
diff --git a/drivers/staging/ste_rmi4/TODO b/drivers/staging/ste_rmi4/TODO
new file mode 100644
index 0000000..9be2437
--- /dev/null
+++ b/drivers/staging/ste_rmi4/TODO
@@ -0,0 +1,7 @@
+TODO
+----
+
+Wait for the official upstream synaptics rmi4 clearpad drivers as promised over the past few months
+Merge any device support needed from this driver into it
+Delete this driver
+
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
new file mode 100644
index 0000000..e8f047e
--- /dev/null
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
@@ -0,0 +1,1179 @@
+/**
+ *
+ * Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver.
+ * Copyright (c) 2007-2010, Synaptics Incorporated
+ *
+ * Author: Js HA <js.ha@stericsson.com> for ST-Ericsson
+ * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
+ * Copyright 2010 (c) ST-Ericsson AB
+ */
+/*
+ * This file is licensed under the GPL2 license.
+ *
+ *#############################################################################
+ * GPL
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ *#############################################################################
+ */
+
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include "synaptics_i2c_rmi4.h"
+
+/* TODO: for multiple device support will need a per-device mutex */
+#define DRIVER_NAME "synaptics_rmi4_i2c"
+
+#define MAX_ERROR_REPORT	6
+#define MAX_TOUCH_MAJOR		15
+#define MAX_RETRY_COUNT		5
+#define STD_QUERY_LEN		21
+#define PAGE_LEN		2
+#define DATA_BUF_LEN		32
+#define BUF_LEN			37
+#define QUERY_LEN		9
+#define DATA_LEN		12
+#define HAS_TAP			0x01
+#define HAS_PALMDETECT		0x01
+#define HAS_ROTATE		0x02
+#define HAS_TAPANDHOLD		0x02
+#define HAS_DOUBLETAP		0x04
+#define HAS_EARLYTAP		0x08
+#define HAS_RELEASE		0x08
+#define HAS_FLICK		0x10
+#define HAS_PRESS		0x20
+#define HAS_PINCH		0x40
+
+#define MASK_16BIT		0xFFFF
+#define MASK_8BIT		0xFF
+#define MASK_7BIT		0x7F
+#define MASK_5BIT		0x1F
+#define MASK_4BIT		0x0F
+#define MASK_3BIT		0x07
+#define MASK_2BIT		0x03
+#define TOUCHPAD_CTRL_INTR	0x8
+#define PDT_START_SCAN_LOCATION (0x00E9)
+#define PDT_END_SCAN_LOCATION	(0x000A)
+#define PDT_ENTRY_SIZE		(0x0006)
+#define RMI4_NUMBER_OF_MAX_FINGERS		(8)
+#define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM	(0x11)
+#define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM	(0x01)
+
+/**
+ * struct synaptics_rmi4_fn_desc - contains the funtion descriptor information
+ * @query_base_addr: base address for query
+ * @cmd_base_addr: base address for command
+ * @ctrl_base_addr: base address for control
+ * @data_base_addr: base address for data
+ * @intr_src_count: count for the interrupt source
+ * @fn_number: function number
+ *
+ * This structure is used to gives the function descriptor information
+ * of the particular functionality.
+ */
+struct synaptics_rmi4_fn_desc {
+	unsigned char	query_base_addr;
+	unsigned char	cmd_base_addr;
+	unsigned char	ctrl_base_addr;
+	unsigned char	data_base_addr;
+	unsigned char	intr_src_count;
+	unsigned char	fn_number;
+};
+
+/**
+ * struct synaptics_rmi4_fn - contains the funtion information
+ * @fn_number: function number
+ * @num_of_data_sources: number of data sources
+ * @num_of_data_points: number of fingers touched
+ * @size_of_data_register_block: data register block size
+ * @index_to_intr_reg: index for interrupt register
+ * @intr_mask: interrupt mask value
+ * @fn_desc: variable for function descriptor structure
+ * @link: linked list for function descriptors
+ *
+ * This structure gives information about the number of data sources and
+ * the number of data registers associated with the function.
+ */
+struct synaptics_rmi4_fn {
+	unsigned char		fn_number;
+	unsigned char		num_of_data_sources;
+	unsigned char		num_of_data_points;
+	unsigned char		size_of_data_register_block;
+	unsigned char		index_to_intr_reg;
+	unsigned char		intr_mask;
+	struct synaptics_rmi4_fn_desc	fn_desc;
+	struct list_head	link;
+};
+
+/**
+ * struct synaptics_rmi4_device_info - contains the rmi4 device information
+ * @version_major: protocol major version number
+ * @version_minor: protocol minor version number
+ * @manufacturer_id: manufacturer identification byte
+ * @product_props: product properties information
+ * @product_info: product info array
+ * @date_code: device manufacture date
+ * @tester_id: tester id array
+ * @serial_number: serial number for that device
+ * @product_id_string: product id for the device
+ * @support_fn_list: linked list for device information
+ *
+ * This structure gives information about the number of data sources and
+ * the number of data registers associated with the function.
+ */
+struct synaptics_rmi4_device_info {
+	unsigned int		version_major;
+	unsigned int		version_minor;
+	unsigned char		manufacturer_id;
+	unsigned char		product_props;
+	unsigned char		product_info[2];
+	unsigned char		date_code[3];
+	unsigned short		tester_id;
+	unsigned short		serial_number;
+	unsigned char		product_id_string[11];
+	struct list_head	support_fn_list;
+};
+
+/**
+ * struct synaptics_rmi4_data - contains the rmi4 device data
+ * @rmi4_mod_info: structure variable for rmi4 device info
+ * @input_dev: pointer for input device
+ * @i2c_client: pointer for i2c client
+ * @board: constant pointer for touch platform data
+ * @fn_list_mutex: mutex for funtion list
+ * @rmi4_page_mutex: mutex for rmi4 page
+ * @current_page: variable for integer
+ * @number_of_interrupt_register: interrupt registers count
+ * @fn01_ctrl_base_addr: control base address for fn01
+ * @fn01_query_base_addr: query base address for fn01
+ * @fn01_data_base_addr: data base address for fn01
+ * @sensor_max_x: sensor maximum x value
+ * @sensor_max_y: sensor maximum y value
+ * @regulator: pointer to the regulator structure
+ * @wait: wait queue structure variable
+ * @touch_stopped: flag to stop the thread function
+ *
+ * This structure gives the device data information.
+ */
+struct synaptics_rmi4_data {
+	struct synaptics_rmi4_device_info rmi4_mod_info;
+	struct input_dev	*input_dev;
+	struct i2c_client	*i2c_client;
+	const struct synaptics_rmi4_platform_data *board;
+	struct mutex		fn_list_mutex;
+	struct mutex		rmi4_page_mutex;
+	int			current_page;
+	unsigned int		number_of_interrupt_register;
+	unsigned short		fn01_ctrl_base_addr;
+	unsigned short		fn01_query_base_addr;
+	unsigned short		fn01_data_base_addr;
+	int			sensor_max_x;
+	int			sensor_max_y;
+	struct regulator	*regulator;
+	wait_queue_head_t	wait;
+	bool			touch_stopped;
+};
+
+/**
+ * synaptics_rmi4_set_page() - sets the page
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @address: set the address of the page
+ *
+ * This function is used to set the page and returns integer.
+ */
+static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *pdata,
+					unsigned int address)
+{
+	unsigned char	txbuf[PAGE_LEN];
+	int		retval;
+	unsigned int	page;
+	struct i2c_client *i2c = pdata->i2c_client;
+
+	page	= ((address >> 8) & MASK_8BIT);
+	if (page != pdata->current_page) {
+		txbuf[0]	= MASK_8BIT;
+		txbuf[1]	= page;
+		retval	= i2c_master_send(i2c, txbuf, PAGE_LEN);
+		if (retval != PAGE_LEN)
+			dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval);
+		else
+			pdata->current_page = page;
+	} else
+		retval = PAGE_LEN;
+	return retval;
+}
+/**
+ * synaptics_rmi4_i2c_block_read() - read the block of data
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @address: read the block of data from this offset
+ * @valp: pointer to a buffer containing the data to be read
+ * @size: number of bytes to read
+ *
+ * This function is to read the block of data and returns integer.
+ */
+static int synaptics_rmi4_i2c_block_read(struct synaptics_rmi4_data *pdata,
+						unsigned short address,
+						unsigned char *valp, int size)
+{
+	int retval = 0;
+	int retry_count = 0;
+	int index;
+	struct i2c_client *i2c = pdata->i2c_client;
+
+	mutex_lock(&(pdata->rmi4_page_mutex));
+	retval = synaptics_rmi4_set_page(pdata, address);
+	if (retval != PAGE_LEN)
+		goto exit;
+	index = address & MASK_8BIT;
+retry:
+	retval = i2c_smbus_read_i2c_block_data(i2c, index, size, valp);
+	if (retval != size) {
+		if (++retry_count == MAX_RETRY_COUNT)
+			dev_err(&i2c->dev,
+				"%s:address 0x%04x size %d failed:%d\n",
+					__func__, address, size, retval);
+		else {
+			synaptics_rmi4_set_page(pdata, address);
+			goto retry;
+		}
+	}
+exit:
+	mutex_unlock(&(pdata->rmi4_page_mutex));
+	return retval;
+}
+
+/**
+ * synaptics_rmi4_i2c_byte_write() - write the single byte data
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @address: write the block of data from this offset
+ * @data: data to be write
+ *
+ * This function is to write the single byte data and returns integer.
+ */
+static int synaptics_rmi4_i2c_byte_write(struct synaptics_rmi4_data *pdata,
+						unsigned short address,
+						unsigned char data)
+{
+	unsigned char txbuf[2];
+	int retval = 0;
+	struct i2c_client *i2c = pdata->i2c_client;
+
+	/* Can't have anyone else changing the page behind our backs */
+	mutex_lock(&(pdata->rmi4_page_mutex));
+
+	retval = synaptics_rmi4_set_page(pdata, address);
+	if (retval != PAGE_LEN)
+		goto exit;
+	txbuf[0]	= address & MASK_8BIT;
+	txbuf[1]	= data;
+	retval		= i2c_master_send(pdata->i2c_client, txbuf, 2);
+	/* Add in retry on writes only in certian error return values */
+	if (retval != 2) {
+		dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval);
+		retval = -EIO;
+	} else
+		retval = 1;
+exit:
+	mutex_unlock(&(pdata->rmi4_page_mutex));
+	return retval;
+}
+
+/**
+ * synpatics_rmi4_touchpad_report() - reports for the rmi4 touchpad device
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @rfi: pointer to synaptics_rmi4_fn structure
+ *
+ * This function calls to reports for the rmi4 touchpad device
+ */
+static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata,
+						struct synaptics_rmi4_fn *rfi)
+{
+	/* number of touch points - fingers down in this case */
+	int	touch_count = 0;
+	int	finger;
+	int	fingers_supported;
+	int	finger_registers;
+	int	reg;
+	int	finger_shift;
+	int	finger_status;
+	int	retval;
+	unsigned short	data_base_addr;
+	unsigned short	data_offset;
+	unsigned char	data_reg_blk_size;
+	unsigned char	values[2];
+	unsigned char	data[DATA_LEN];
+	int	x[RMI4_NUMBER_OF_MAX_FINGERS];
+	int	y[RMI4_NUMBER_OF_MAX_FINGERS];
+	int	wx[RMI4_NUMBER_OF_MAX_FINGERS];
+	int	wy[RMI4_NUMBER_OF_MAX_FINGERS];
+	struct	i2c_client *client = pdata->i2c_client;
+
+	/* get 2D sensor finger data */
+	/*
+	 * First get the finger status field - the size of the finger status
+	 * field is determined by the number of finger supporte - 2 bits per
+	 * finger, so the number of registers to read is:
+	 * registerCount = ceil(numberOfFingers/4).
+	 * Read the required number of registers and check each 2 bit field to
+	 * determine if a finger is down:
+	 *	00 = finger not present,
+	 *	01 = finger present and data accurate,
+	 *	10 = finger present but data may not be accurate,
+	 *	11 = reserved for product use.
+	 */
+	fingers_supported	= rfi->num_of_data_points;
+	finger_registers	= (fingers_supported + 3)/4;
+	data_base_addr		= rfi->fn_desc.data_base_addr;
+	retval = synaptics_rmi4_i2c_block_read(pdata, data_base_addr, values,
+							finger_registers);
+	if (retval != finger_registers) {
+		dev_err(&client->dev, "%s:read status registers failed\n",
+								__func__);
+		return 0;
+	}
+	/*
+	 * For each finger present, read the proper number of registers
+	 * to get absolute data.
+	 */
+	data_reg_blk_size = rfi->size_of_data_register_block;
+	for (finger = 0; finger < fingers_supported; finger++) {
+		/* determine which data byte the finger status is in */
+		reg = finger/4;
+		/* bit shift to get finger's status */
+		finger_shift	= (finger % 4) * 2;
+		finger_status	= (values[reg] >> finger_shift) & 3;
+		/*
+		 * if finger status indicates a finger is present then
+		 * read the finger data and report it
+		 */
+		if (finger_status == 1 || finger_status == 2) {
+			/* Read the finger data */
+			data_offset = data_base_addr +
+					((finger * data_reg_blk_size) +
+					finger_registers);
+			retval = synaptics_rmi4_i2c_block_read(pdata,
+						data_offset, data,
+						data_reg_blk_size);
+			if (retval != data_reg_blk_size) {
+				printk(KERN_ERR "%s:read data failed\n",
+								__func__);
+				return 0;
+			} else {
+				x[touch_count]	=
+					(data[0] << 4) | (data[2] & MASK_4BIT);
+				y[touch_count]	=
+					(data[1] << 4) |
+					((data[2] >> 4) & MASK_4BIT);
+				wy[touch_count]	=
+						(data[3] >> 4) & MASK_4BIT;
+				wx[touch_count]	=
+						(data[3] & MASK_4BIT);
+
+				if (pdata->board->x_flip)
+					x[touch_count] =
+						pdata->sensor_max_x -
+								x[touch_count];
+				if (pdata->board->y_flip)
+					y[touch_count] =
+						pdata->sensor_max_y -
+								y[touch_count];
+			}
+			/* number of active touch points */
+			touch_count++;
+		}
+	}
+
+	/* report to input subsystem */
+	if (touch_count) {
+		for (finger = 0; finger < touch_count; finger++) {
+			input_report_abs(pdata->input_dev, ABS_MT_TOUCH_MAJOR,
+						max(wx[finger] , wy[finger]));
+			input_report_abs(pdata->input_dev, ABS_MT_POSITION_X,
+								x[finger]);
+			input_report_abs(pdata->input_dev, ABS_MT_POSITION_Y,
+								y[finger]);
+			input_mt_sync(pdata->input_dev);
+		}
+	} else
+		input_mt_sync(pdata->input_dev);
+
+	/* sync after groups of events */
+	input_sync(pdata->input_dev);
+	/* return the number of touch points */
+	return touch_count;
+}
+
+/**
+ * synaptics_rmi4_report_device() - reports the rmi4 device
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @rfi: pointer to synaptics_rmi4_fn
+ *
+ * This function is used to call the report function of the rmi4 device.
+ */
+static int synaptics_rmi4_report_device(struct synaptics_rmi4_data *pdata,
+					struct synaptics_rmi4_fn *rfi)
+{
+	int touch = 0;
+	struct	i2c_client *client = pdata->i2c_client;
+	static int num_error_reports;
+	if (rfi->fn_number != SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM) {
+		num_error_reports++;
+		if (num_error_reports < MAX_ERROR_REPORT)
+			dev_err(&client->dev, "%s:report not supported\n",
+								__func__);
+	} else
+		touch = synpatics_rmi4_touchpad_report(pdata, rfi);
+	return touch;
+}
+/**
+ * synaptics_rmi4_sensor_report() - reports to input subsystem
+ * @pdata: pointer to synaptics_rmi4_data structure
+ *
+ * This function is used to reads in all data sources and reports
+ * them to the input subsystem.
+ */
+static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *pdata)
+{
+	unsigned char	intr_status[4];
+	/* number of touch points - fingers or buttons */
+	int touch = 0;
+	unsigned int retval;
+	struct synaptics_rmi4_fn		*rfi;
+	struct synaptics_rmi4_device_info	*rmi;
+	struct	i2c_client *client = pdata->i2c_client;
+
+	/*
+	 * Get the interrupt status from the function $01
+	 * control register+1 to find which source(s) were interrupting
+	 * so we can read the data from the source(s) (2D sensor, buttons..)
+	 */
+	retval = synaptics_rmi4_i2c_block_read(pdata,
+					pdata->fn01_data_base_addr + 1,
+					intr_status,
+					pdata->number_of_interrupt_register);
+	if (retval != pdata->number_of_interrupt_register) {
+		dev_err(&client->dev,
+				"could not read interrupt status registers\n");
+		return 0;
+	}
+	/*
+	 * check each function that has data sources and if the interrupt for
+	 * that triggered then call that RMI4 functions report() function to
+	 * gather data and report it to the input subsystem
+	 */
+	rmi = &(pdata->rmi4_mod_info);
+	list_for_each_entry(rfi, &rmi->support_fn_list, link) {
+		if (rfi->num_of_data_sources) {
+			if (intr_status[rfi->index_to_intr_reg] &
+							rfi->intr_mask)
+				touch = synaptics_rmi4_report_device(pdata,
+									rfi);
+		}
+	}
+	/* return the number of touch points */
+	return touch;
+}
+
+/**
+ * synaptics_rmi4_irq() - thread function for rmi4 attention line
+ * @irq: irq value
+ * @data: void pointer
+ *
+ * This function is interrupt thread function. It just notifies the
+ * application layer that attention is required.
+ */
+static irqreturn_t synaptics_rmi4_irq(int irq, void *data)
+{
+	struct synaptics_rmi4_data *pdata = data;
+	int touch_count;
+	do {
+		touch_count = synaptics_rmi4_sensor_report(pdata);
+		if (touch_count)
+			wait_event_timeout(pdata->wait, pdata->touch_stopped,
+							msecs_to_jiffies(1));
+		else
+			break;
+	} while (!pdata->touch_stopped);
+	return IRQ_HANDLED;
+}
+
+/**
+ * synpatics_rmi4_touchpad_detect() - detects the rmi4 touchpad device
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @rfi: pointer to synaptics_rmi4_fn structure
+ * @fd: pointer to synaptics_rmi4_fn_desc structure
+ * @interruptcount: count the number of interrupts
+ *
+ * This function calls to detects the rmi4 touchpad device
+ */
+static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata,
+					struct synaptics_rmi4_fn *rfi,
+					struct synaptics_rmi4_fn_desc *fd,
+					unsigned int interruptcount)
+{
+	unsigned char	queries[QUERY_LEN];
+	unsigned short	intr_offset;
+	unsigned char	abs_data_size;
+	unsigned char	abs_data_blk_size;
+	unsigned char	egr_0, egr_1;
+	unsigned int	all_data_blk_size;
+	int	has_pinch, has_flick, has_tap;
+	int	has_tapandhold, has_doubletap;
+	int	has_earlytap, has_press;
+	int	has_palmdetect, has_rotate;
+	int	has_rel;
+	int	i;
+	int	retval;
+	struct	i2c_client *client = pdata->i2c_client;
+
+	rfi->fn_desc.query_base_addr	= fd->query_base_addr;
+	rfi->fn_desc.data_base_addr	= fd->data_base_addr;
+	rfi->fn_desc.intr_src_count	= fd->intr_src_count;
+	rfi->fn_desc.fn_number		= fd->fn_number;
+	rfi->fn_number			= fd->fn_number;
+	rfi->num_of_data_sources	= fd->intr_src_count;
+	rfi->fn_desc.ctrl_base_addr	= fd->ctrl_base_addr;
+	rfi->fn_desc.cmd_base_addr	= fd->cmd_base_addr;
+
+	/*
+	 * need to get number of fingers supported, data size, etc.
+	 * to be used when getting data since the number of registers to
+	 * read depends on the number of fingers supported and data size.
+	 */
+	retval = synaptics_rmi4_i2c_block_read(pdata, fd->query_base_addr,
+							queries,
+							sizeof(queries));
+	if (retval != sizeof(queries)) {
+		dev_err(&client->dev, "%s:read function query registers\n",
+							__func__);
+		return retval;
+	}
+	/*
+	 * 2D data sources have only 3 bits for the number of fingers
+	 * supported - so the encoding is a bit wierd.
+	 */
+	if ((queries[1] & MASK_3BIT) <= 4)
+		/* add 1 since zero based */
+		rfi->num_of_data_points = (queries[1] & MASK_3BIT) + 1;
+	else {
+		/*
+		 * a value of 5 is up to 10 fingers - 6 and 7 are reserved
+		 * (shouldn't get these i int retval;n a normal 2D source).
+		 */
+		if ((queries[1] & MASK_3BIT) == 5)
+			rfi->num_of_data_points = 10;
+	}
+	/* Need to get interrupt info for handling interrupts */
+	rfi->index_to_intr_reg = (interruptcount + 7)/8;
+	if (rfi->index_to_intr_reg != 0)
+		rfi->index_to_intr_reg -= 1;
+	/*
+	 * loop through interrupts for each source in fn $11
+	 * and or in a bit to the interrupt mask for each.
+	 */
+	intr_offset = interruptcount % 8;
+	rfi->intr_mask = 0;
+	for (i = intr_offset;
+		i < ((fd->intr_src_count & MASK_3BIT) + intr_offset); i++)
+		rfi->intr_mask |= 1 << i;
+
+	/* Size of just the absolute data for one finger */
+	abs_data_size	= queries[5] & MASK_2BIT;
+	/* One each for X and Y, one for LSB for X & Y, one for W, one for Z */
+	abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0));
+	rfi->size_of_data_register_block = abs_data_blk_size;
+
+	/*
+	 * need to determine the size of data to read - this depends on
+	 * conditions such as whether Relative data is reported and if Gesture
+	 * data is reported.
+	 */
+	egr_0 = queries[7];
+	egr_1 = queries[8];
+
+	/*
+	 * Get info about what EGR data is supported, whether it has
+	 * Relative data supported, etc.
+	 */
+	has_pinch	= egr_0 & HAS_PINCH;
+	has_flick	= egr_0 & HAS_FLICK;
+	has_tap		= egr_0 & HAS_TAP;
+	has_earlytap	= egr_0 & HAS_EARLYTAP;
+	has_press	= egr_0 & HAS_PRESS;
+	has_rotate	= egr_1 & HAS_ROTATE;
+	has_rel		= queries[1] & HAS_RELEASE;
+	has_tapandhold	= egr_0 & HAS_TAPANDHOLD;
+	has_doubletap	= egr_0 & HAS_DOUBLETAP;
+	has_palmdetect	= egr_1 & HAS_PALMDETECT;
+
+	/*
+	 * Size of all data including finger status, absolute data for each
+	 * finger, relative data and EGR data
+	 */
+	all_data_blk_size =
+		/* finger status, four fingers per register */
+		((rfi->num_of_data_points + 3) / 4) +
+		/* absolute data, per finger times number of fingers */
+		(abs_data_blk_size * rfi->num_of_data_points) +
+		/*
+		 * two relative registers (if relative is being reported)
+		 */
+		2 * has_rel +
+		/*
+		 * F11_2D_data8 is only present if the egr_0
+		 * register is non-zero.
+		 */
+		!!(egr_0) +
+		/*
+		 * F11_2D_data9 is only present if either egr_0 or
+		 * egr_1 registers are non-zero.
+		 */
+		(egr_0 || egr_1) +
+		/*
+		 * F11_2D_data10 is only present if EGR_PINCH or EGR_FLICK of
+		 * egr_0 reports as 1.
+		 */
+		!!(has_pinch | has_flick) +
+		/*
+		 * F11_2D_data11 and F11_2D_data12 are only present if
+		 * EGR_FLICK of egr_0 reports as 1.
+		 */
+		2 * !!(has_flick);
+	return retval;
+}
+
+/**
+ * synpatics_rmi4_touchpad_config() - confiures the rmi4 touchpad device
+ * @pdata: pointer to synaptics_rmi4_data structure
+ * @rfi: pointer to synaptics_rmi4_fn structure
+ *
+ * This function calls to confiures the rmi4 touchpad device
+ */
+int synpatics_rmi4_touchpad_config(struct synaptics_rmi4_data *pdata,
+						struct synaptics_rmi4_fn *rfi)
+{
+	/*
+	 * For the data source - print info and do any
+	 * source specific configuration.
+	 */
+	unsigned char data[BUF_LEN];
+	int retval = 0;
+	struct	i2c_client *client = pdata->i2c_client;
+
+	/* Get and print some info about the data source... */
+	/* To Query 2D devices we need to read from the address obtained
+	 * from the function descriptor stored in the RMI function info.
+	 */
+	retval = synaptics_rmi4_i2c_block_read(pdata,
+						rfi->fn_desc.query_base_addr,
+						data, QUERY_LEN);
+	if (retval != QUERY_LEN)
+		dev_err(&client->dev, "%s:read query registers failed\n",
+								__func__);
+	else {
+		retval = synaptics_rmi4_i2c_block_read(pdata,
+						rfi->fn_desc.ctrl_base_addr,
+						data, DATA_BUF_LEN);
+		if (retval != DATA_BUF_LEN) {
+			dev_err(&client->dev,
+				"%s:read control registers failed\n",
+								__func__);
+			return retval;
+		}
+		/* Store these for use later*/
+		pdata->sensor_max_x = ((data[6] & MASK_8BIT) << 0) |
+						((data[7] & MASK_4BIT) << 8);
+		pdata->sensor_max_y = ((data[8] & MASK_5BIT) << 0) |
+						((data[9] & MASK_4BIT) << 8);
+	}
+	return retval;
+}
+
+/**
+ * synaptics_rmi4_i2c_query_device() - query the rmi4 device
+ * @pdata: pointer to synaptics_rmi4_data structure
+ *
+ * This function is used to query the rmi4 device.
+ */
+static int synaptics_rmi4_i2c_query_device(struct synaptics_rmi4_data *pdata)
+{
+	int i;
+	int retval;
+	unsigned char std_queries[STD_QUERY_LEN];
+	unsigned char intr_count = 0;
+	int data_sources = 0;
+	unsigned int ctrl_offset;
+	struct synaptics_rmi4_fn *rfi;
+	struct synaptics_rmi4_fn_desc	rmi_fd;
+	struct synaptics_rmi4_device_info *rmi;
+	struct	i2c_client *client = pdata->i2c_client;
+
+	/*
+	 * init the physical drivers RMI module
+	 * info list of functions
+	 */
+	INIT_LIST_HEAD(&pdata->rmi4_mod_info.support_fn_list);
+
+	/*
+	 * Read the Page Descriptor Table to determine what functions
+	 * are present
+	 */
+	for (i = PDT_START_SCAN_LOCATION; i > PDT_END_SCAN_LOCATION;
+						i -= PDT_ENTRY_SIZE) {
+		retval = synaptics_rmi4_i2c_block_read(pdata, i,
+						(unsigned char *)&rmi_fd,
+						sizeof(rmi_fd));
+		if (retval != sizeof(rmi_fd)) {
+			/* failed to read next PDT entry */
+			dev_err(&client->dev, "%s: read error\n", __func__);
+			return -EIO;
+		}
+		rfi = NULL;
+		if (rmi_fd.fn_number) {
+			switch (rmi_fd.fn_number & MASK_8BIT) {
+			case SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM:
+				pdata->fn01_query_base_addr =
+						rmi_fd.query_base_addr;
+				pdata->fn01_ctrl_base_addr =
+						rmi_fd.ctrl_base_addr;
+				pdata->fn01_data_base_addr =
+						rmi_fd.data_base_addr;
+				break;
+			case SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM:
+				if (rmi_fd.intr_src_count) {
+					rfi = kmalloc(sizeof(*rfi),
+								GFP_KERNEL);
+					if (!rfi) {
+						dev_err(&client->dev,
+							"%s:kmalloc failed\n",
+								__func__);
+							return -ENOMEM;
+					}
+					retval = synpatics_rmi4_touchpad_detect
+								(pdata,	rfi,
+								&rmi_fd,
+								intr_count);
+					if (retval < 0)
+						return retval;
+				}
+				break;
+			}
+			/* interrupt count for next iteration */
+			intr_count += (rmi_fd.intr_src_count & MASK_3BIT);
+			/*
+			 * We only want to add functions to the list
+			 * that have data associated with them.
+			 */
+			if (rfi && rmi_fd.intr_src_count) {
+				/* link this function info to the RMI module */
+				mutex_lock(&(pdata->fn_list_mutex));
+				list_add_tail(&rfi->link,
+					&pdata->rmi4_mod_info.support_fn_list);
+				mutex_unlock(&(pdata->fn_list_mutex));
+			}
+		} else {
+			/*
+			 * A zero in the function number
+			 * signals the end of the PDT
+			 */
+			dev_dbg(&client->dev,
+				"%s:end of PDT\n", __func__);
+			break;
+		}
+	}
+	/*
+	 * calculate the interrupt register count - used in the
+	 * ISR to read the correct number of interrupt registers
+	 */
+	pdata->number_of_interrupt_register = (intr_count + 7) / 8;
+	/*
+	 * Function $01 will be used to query the product properties,
+	 * and product ID  so we had to read the PDT above first to get
+	 * the Fn $01 query address and prior to filling in the product
+	 * info. NOTE: Even an unflashed device will still have FN $01.
+	 */
+
+	/* Load up the standard queries and get the RMI4 module info */
+	retval = synaptics_rmi4_i2c_block_read(pdata,
+					pdata->fn01_query_base_addr,
+					std_queries,
+					sizeof(std_queries));
+	if (retval != sizeof(std_queries)) {
+		dev_err(&client->dev, "%s:Failed reading queries\n",
+							__func__);
+		 return -EIO;
+	}
+
+	/* Currently supported RMI version is 4.0 */
+	pdata->rmi4_mod_info.version_major	= 4;
+	pdata->rmi4_mod_info.version_minor	= 0;
+	/*
+	 * get manufacturer id, product_props, product info,
+	 * date code, tester id, serial num and product id (name)
+	 */
+	pdata->rmi4_mod_info.manufacturer_id	= std_queries[0];
+	pdata->rmi4_mod_info.product_props	= std_queries[1];
+	pdata->rmi4_mod_info.product_info[0]	= std_queries[2];
+	pdata->rmi4_mod_info.product_info[1]	= std_queries[3];
+	/* year - 2001-2032 */
+	pdata->rmi4_mod_info.date_code[0]	= std_queries[4] & MASK_5BIT;
+	/* month - 1-12 */
+	pdata->rmi4_mod_info.date_code[1]	= std_queries[5] & MASK_4BIT;
+	/* day - 1-31 */
+	pdata->rmi4_mod_info.date_code[2]	= std_queries[6] & MASK_5BIT;
+	pdata->rmi4_mod_info.tester_id = ((std_queries[7] & MASK_7BIT) << 8) |
+						(std_queries[8] & MASK_7BIT);
+	pdata->rmi4_mod_info.serial_number =
+		((std_queries[9] & MASK_7BIT) << 8) |
+				(std_queries[10] & MASK_7BIT);
+	memcpy(pdata->rmi4_mod_info.product_id_string, &std_queries[11], 10);
+
+	/* Check if this is a Synaptics device - report if not. */
+	if (pdata->rmi4_mod_info.manufacturer_id != 1)
+		dev_err(&client->dev, "%s: non-Synaptics mfg id:%d\n",
+			__func__, pdata->rmi4_mod_info.manufacturer_id);
+
+	list_for_each_entry(rfi, &pdata->rmi4_mod_info.support_fn_list, link)
+		data_sources += rfi->num_of_data_sources;
+	if (data_sources) {
+		rmi = &(pdata->rmi4_mod_info);
+		list_for_each_entry(rfi, &rmi->support_fn_list, link) {
+			if (rfi->num_of_data_sources) {
+				if (rfi->fn_number ==
+					SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM) {
+					retval = synpatics_rmi4_touchpad_config
+								(pdata, rfi);
+					if (retval < 0)
+						return retval;
+				} else
+					dev_err(&client->dev,
+						"%s:fn_number not supported\n",
+								__func__);
+				/*
+				 * Turn on interrupts for this
+				 * function's data sources.
+				 */
+				ctrl_offset = pdata->fn01_ctrl_base_addr + 1 +
+							rfi->index_to_intr_reg;
+				retval = synaptics_rmi4_i2c_byte_write(pdata,
+							ctrl_offset,
+							rfi->intr_mask);
+				if (retval < 0)
+					return retval;
+			}
+		}
+	}
+	return 0;
+}
+
+/**
+ * synaptics_rmi4_probe() - Initialze the i2c-client touchscreen driver
+ * @i2c: i2c client structure pointer
+ * @id:i2c device id pointer
+ *
+ * This function will allocate and initialize the instance
+ * data and request the irq and set the instance data as the clients
+ * platform data then register the physical driver which will do a scan of
+ * the rmi4 Physical Device Table and enumerate any rmi4 functions that
+ * have data sources associated with them.
+ */
+static int __devinit synaptics_rmi4_probe
+	(struct i2c_client *client, const struct i2c_device_id *dev_id)
+{
+	int retval;
+	unsigned char intr_status[4];
+	struct synaptics_rmi4_data *rmi4_data;
+	const struct synaptics_rmi4_platform_data *platformdata =
+						client->dev.platform_data;
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "i2c smbus byte data not supported\n");
+		return -EIO;
+	}
+
+	if (!platformdata) {
+		dev_err(&client->dev, "%s: no platform data\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Allocate and initialize the instance data for this client */
+	rmi4_data = kzalloc(sizeof(struct synaptics_rmi4_data) * 2,
+							GFP_KERNEL);
+	if (!rmi4_data) {
+		dev_err(&client->dev, "%s: no memory allocated\n", __func__);
+		return -ENOMEM;
+	}
+
+	rmi4_data->input_dev = input_allocate_device();
+	if (rmi4_data->input_dev == NULL) {
+		dev_err(&client->dev, "%s:input device alloc failed\n",
+						__func__);
+		retval = -ENOMEM;
+		goto err_input;
+	}
+
+	dev_set_name(&client->dev, platformdata->name);
+
+	if (platformdata->regulator_en) {
+		rmi4_data->regulator = regulator_get(&client->dev, "v-touch");
+		if (IS_ERR(rmi4_data->regulator)) {
+			dev_err(&client->dev, "%s:get regulator failed\n",
+								__func__);
+			retval = PTR_ERR(rmi4_data->regulator);
+			goto err_regulator;
+		}
+		regulator_enable(rmi4_data->regulator);
+	}
+
+	init_waitqueue_head(&rmi4_data->wait);
+	/*
+	 * Copy i2c_client pointer into RTID's i2c_client pointer for
+	 * later use in rmi4_read, rmi4_write, etc.
+	 */
+	rmi4_data->i2c_client		= client;
+	/* So we set the page correctly the first time */
+	rmi4_data->current_page		= MASK_16BIT;
+	rmi4_data->board		= platformdata;
+	rmi4_data->touch_stopped	= false;
+
+	/* init the mutexes for maintain the lists */
+	mutex_init(&(rmi4_data->fn_list_mutex));
+	mutex_init(&(rmi4_data->rmi4_page_mutex));
+
+	/*
+	 * Register physical driver - this will call the detect function that
+	 * will then scan the device and determine the supported
+	 * rmi4 functions.
+	 */
+	retval = synaptics_rmi4_i2c_query_device(rmi4_data);
+	if (retval) {
+		dev_err(&client->dev, "%s: rmi4 query device failed\n",
+							__func__);
+		goto err_query_dev;
+	}
+
+	/* Store the instance data in the i2c_client */
+	i2c_set_clientdata(client, rmi4_data);
+
+	/*initialize the input device parameters */
+	rmi4_data->input_dev->name	= DRIVER_NAME;
+	rmi4_data->input_dev->phys	= "Synaptics_Clearpad";
+	rmi4_data->input_dev->id.bustype = BUS_I2C;
+	rmi4_data->input_dev->dev.parent = &client->dev;
+	input_set_drvdata(rmi4_data->input_dev, rmi4_data);
+
+	/* Initialize the function handlers for rmi4 */
+	set_bit(EV_SYN, rmi4_data->input_dev->evbit);
+	set_bit(EV_KEY, rmi4_data->input_dev->evbit);
+	set_bit(EV_ABS, rmi4_data->input_dev->evbit);
+
+	input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_X, 0,
+					rmi4_data->sensor_max_x, 0, 0);
+	input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_Y, 0,
+					rmi4_data->sensor_max_y, 0, 0);
+	input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0,
+						MAX_TOUCH_MAJOR, 0, 0);
+
+	retval = input_register_device(rmi4_data->input_dev);
+	if (retval) {
+		dev_err(&client->dev, "%s:input register failed\n", __func__);
+		goto err_input_register;
+	}
+
+	/* Clear interrupts */
+	synaptics_rmi4_i2c_block_read(rmi4_data,
+			rmi4_data->fn01_data_base_addr + 1, intr_status,
+				rmi4_data->number_of_interrupt_register);
+	retval = request_threaded_irq(platformdata->irq_number, NULL,
+					synaptics_rmi4_irq,
+					platformdata->irq_type,
+					platformdata->name, rmi4_data);
+	if (retval) {
+		dev_err(&client->dev, "%s:Unable to get attn irq %d\n",
+				__func__, platformdata->irq_number);
+		goto err_request_irq;
+	}
+
+	return retval;
+
+err_request_irq:
+	free_irq(platformdata->irq_number, rmi4_data);
+	input_unregister_device(rmi4_data->input_dev);
+err_input_register:
+	i2c_set_clientdata(client, NULL);
+err_query_dev:
+	if (platformdata->regulator_en) {
+		regulator_disable(rmi4_data->regulator);
+		regulator_put(rmi4_data->regulator);
+	}
+err_regulator:
+	input_free_device(rmi4_data->input_dev);
+	rmi4_data->input_dev = NULL;
+err_input:
+	kfree(rmi4_data);
+
+	return retval;
+}
+/**
+ * synaptics_rmi4_remove() - Removes the i2c-client touchscreen driver
+ * @client: i2c client structure pointer
+ *
+ * This funtion uses to remove the i2c-client
+ * touchscreen driver and returns integer.
+ */
+static int __devexit synaptics_rmi4_remove(struct i2c_client *client)
+{
+	struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client);
+	const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
+
+	rmi4_data->touch_stopped = true;
+	wake_up(&rmi4_data->wait);
+	free_irq(pdata->irq_number, rmi4_data);
+	input_unregister_device(rmi4_data->input_dev);
+	if (pdata->regulator_en) {
+		regulator_disable(rmi4_data->regulator);
+		regulator_put(rmi4_data->regulator);
+	}
+	kfree(rmi4_data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+/**
+ * synaptics_rmi4_suspend() - suspend the touch screen controller
+ * @dev: pointer to device structure
+ *
+ * This funtion is used to suspend the
+ * touch panel controller and returns integer
+ */
+static int synaptics_rmi4_suspend(struct device *dev)
+{
+	/* Touch sleep mode */
+	int retval;
+	unsigned char intr_status;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+	const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
+
+	rmi4_data->touch_stopped = true;
+	disable_irq(pdata->irq_number);
+
+	retval = synaptics_rmi4_i2c_block_read(rmi4_data,
+				rmi4_data->fn01_data_base_addr + 1,
+				&intr_status,
+				rmi4_data->number_of_interrupt_register);
+	if (retval < 0)
+		return retval;
+
+	retval = synaptics_rmi4_i2c_byte_write(rmi4_data,
+					rmi4_data->fn01_ctrl_base_addr + 1,
+					(intr_status & ~TOUCHPAD_CTRL_INTR));
+	if (retval < 0)
+		return retval;
+
+	if (pdata->regulator_en)
+		regulator_disable(rmi4_data->regulator);
+
+	return 0;
+}
+/**
+ * synaptics_rmi4_resume() - resume the touch screen controller
+ * @dev: pointer to device structure
+ *
+ * This funtion is used to resume the touch panel
+ * controller and returns integer.
+ */
+static int synaptics_rmi4_resume(struct device *dev)
+{
+	int retval;
+	unsigned char intr_status;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+	const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board;
+
+	if (pdata->regulator_en)
+		regulator_enable(rmi4_data->regulator);
+
+	enable_irq(pdata->irq_number);
+	rmi4_data->touch_stopped = false;
+
+	retval = synaptics_rmi4_i2c_block_read(rmi4_data,
+				rmi4_data->fn01_data_base_addr + 1,
+				&intr_status,
+				rmi4_data->number_of_interrupt_register);
+	if (retval < 0)
+		return retval;
+
+	retval = synaptics_rmi4_i2c_byte_write(rmi4_data,
+					rmi4_data->fn01_ctrl_base_addr + 1,
+					(intr_status | TOUCHPAD_CTRL_INTR));
+	if (retval < 0)
+		return retval;
+
+	return 0;
+}
+
+static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = {
+	.suspend = synaptics_rmi4_suspend,
+	.resume  = synaptics_rmi4_resume,
+};
+#endif
+
+static const struct i2c_device_id synaptics_rmi4_id_table[] = {
+	{ DRIVER_NAME, 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table);
+
+static struct i2c_driver synaptics_rmi4_driver = {
+	.driver = {
+		.name	=	DRIVER_NAME,
+		.owner	=	THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	=	&synaptics_rmi4_dev_pm_ops,
+#endif
+	},
+	.probe		=	synaptics_rmi4_probe,
+	.remove		=	__devexit_p(synaptics_rmi4_remove),
+	.id_table	=	synaptics_rmi4_id_table,
+};
+/**
+ * synaptics_rmi4_init() - Initialize the touchscreen driver
+ *
+ * This funtion uses to initializes the synaptics
+ * touchscreen driver and returns integer.
+ */
+static int __init synaptics_rmi4_init(void)
+{
+	return i2c_add_driver(&synaptics_rmi4_driver);
+}
+/**
+ * synaptics_rmi4_exit() - De-initialize the touchscreen driver
+ *
+ * This funtion uses to de-initialize the synaptics
+ * touchscreen driver and returns none.
+ */
+static void __exit synaptics_rmi4_exit(void)
+{
+	i2c_del_driver(&synaptics_rmi4_driver);
+}
+
+
+module_init(synaptics_rmi4_init);
+module_exit(synaptics_rmi4_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("naveen.gaddipati@stericsson.com, js.ha@stericsson.com");
+MODULE_DESCRIPTION("synaptics rmi4 i2c touch Driver");
+MODULE_ALIAS("i2c:synaptics_rmi4_ts");
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h
new file mode 100644
index 0000000..820ae27
--- /dev/null
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h
@@ -0,0 +1,50 @@
+/**
+ *
+ * Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver.
+ * Copyright (c) 2007-2010, Synaptics Incorporated
+ *
+ * Author: Js HA <js.ha@stericsson.com> for ST-Ericsson
+ * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
+ * Copyright 2010 (c) ST-Ericsson AB
+ */
+/*
+ * This file is licensed under the GPL2 license.
+ *
+ *#############################################################################
+ * GPL
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ *#############################################################################
+ */
+
+#ifndef _SYNAPTICS_RMI4_H_INCLUDED_
+#define _SYNAPTICS_RMI4_H_INCLUDED_
+
+/**
+ * struct synaptics_rmi4_platform_data - contains the rmi4 platform data
+ * @irq_number: irq number
+ * @irq_type: irq type
+ * @x flip: x flip flag
+ * @y flip: y flip flag
+ * @regulator_en: regulator enable flag
+ *
+ * This structure gives platform data for rmi4.
+ */
+struct synaptics_rmi4_platform_data {
+	const char *name;
+	int irq_number;
+	int irq_type;
+	bool x_flip;
+	bool y_flip;
+	bool regulator_en;
+};
+
+#endif
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c
index fed2510..0cdf564c 100644
--- a/drivers/staging/udlfb/udlfb.c
+++ b/drivers/staging/udlfb/udlfb.c
@@ -1163,14 +1163,13 @@
 		 * But with imperfect damage info we may send pixels over USB
 		 * that were, in fact, unchanged - wasting limited USB bandwidth
 		 */
-		new_back = vmalloc(new_len);
+		new_back = vzalloc(new_len);
 		if (!new_back)
-			dl_info("No shadow/backing buffer allcoated\n");
+			dl_info("No shadow/backing buffer allocated\n");
 		else {
 			if (dev->backing_buffer)
 				vfree(dev->backing_buffer);
 			dev->backing_buffer = new_back;
-			memset(dev->backing_buffer, 0, new_len);
 		}
 	}
 
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index 8de21aa..a49053b 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -1092,7 +1092,7 @@
         pDevice->sMgmtObj.uCurrChannel = byNewChannel;
         bResult = CARDbSetMediaChannel(pDevice, byNewChannel);
 
-        return(bResult);
+	return bResult;
     }
     pDevice->byChannelSwitchCount = byCount;
     pDevice->byNewChannel = byNewChannel;
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index 1f9d2963..f4fb0c6 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -1608,8 +1608,8 @@
         }
     }
 
-    pDevice->bIsRxMngWorkItemQueued = FALSE;
-    spin_unlock_irq(&pDevice->lock);
+	pDevice->bIsRxMngWorkItemQueued = FALSE;
+	spin_unlock_irq(&pDevice->lock);
 
 }
 
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index bbdc127..8f18578 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -68,8 +68,7 @@
 /*---------------------  Static Classes  ----------------------------*/
 
 /*---------------------  Static Variables  --------------------------*/
-//static int          msglevel                =MSG_LEVEL_DEBUG;
-static int          msglevel                =MSG_LEVEL_INFO;
+static int          msglevel                = MSG_LEVEL_INFO;
 
 /*---------------------  Static Functions  --------------------------*/
 
diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c
index a6bd533..0715636 100644
--- a/drivers/staging/vt6656/tkip.c
+++ b/drivers/staging/vt6656/tkip.c
@@ -214,13 +214,14 @@
     /* Phase 1, step 2 */
     for (i=0; i<8; i++) {
         j = 2*(i & 1);
-        p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536 )) % 65536;
-        p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536 )) % 65536;
-        p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536 )) % 65536;
-        p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536 )) % 65536;
-        p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536 )) % 65536;
+        p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536;
+        p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536;
+        p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536;
+        p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536;
+        p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536;
         p1k[4] = (p1k[4] + i) % 65536;
     }
+ 
     /* Phase 2, Step 1 */
     ppk0 = p1k[0];
     ppk1 = p1k[1];
@@ -230,19 +231,19 @@
     ppk5 = (p1k[4] + tsc2) % 65536;
 
     /* Phase2, Step 2 */
-    ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536);
-    ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
-    ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
-    ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
-    ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
-    ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
+	ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536);
+	ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
+	ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
+	ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
+	ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
+	ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
 
-    ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
-    ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
-    ppk2 = ppk2 + rotr1(ppk1);
-    ppk3 = ppk3 + rotr1(ppk2);
-    ppk4 = ppk4 + rotr1(ppk3);
-    ppk5 = ppk5 + rotr1(ppk4);
+	ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
+	ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
+	ppk2 = ppk2 + rotr1(ppk1);
+	ppk3 = ppk3 + rotr1(ppk2);
+	ppk4 = ppk4 + rotr1(ppk3);
+	ppk5 = ppk5 + rotr1(ppk4);
 
     /* Phase 2, Step 3 */
     pbyRC4Key[0] = (tsc2 >> 8) % 256;
diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
index a678029..ad0c61d 100644
--- a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
+++ b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
@@ -2127,10 +2127,7 @@
  */
 void *cy_as_hal_alloc(uint32_t cnt)
 {
-	void *ret_p;
-
-	ret_p = kmalloc(cnt, GFP_ATOMIC);
-	return ret_p;
+	return kmalloc(cnt, GFP_ATOMIC);
 }
 
 /*
@@ -2150,10 +2147,7 @@
  */
 void *cy_as_hal_c_b_alloc(uint32_t cnt)
 {
-	void *ret_p;
-
-	ret_p = kmalloc(cnt, GFP_ATOMIC);
-	return ret_p;
+	return kmalloc(cnt, GFP_ATOMIC);
 }
 
 /*
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index 2b87a00..d7b3aca 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -4,7 +4,7 @@
 #include <linux/wireless.h>
 #include <linux/types.h>
 
-#include "wbhal_s.h"
+#include "wbhal.h"
 #include "mto.h"
 
 #include "mac_structures.h"
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
index 9217762..90f2cc0 100644
--- a/drivers/staging/winbond/mds.c
+++ b/drivers/staging/winbond/mds.c
@@ -2,8 +2,9 @@
 #include "mlmetxrx_f.h"
 #include "mto.h"
 #include "sysdef.h"
-#include "wbhal_f.h"
+#include "wbhal.h"
 #include "wblinux_f.h"
+#include "wb35tx_f.h"
 
 unsigned char
 Mds_initial(struct wbsoft_priv *adapter)
@@ -17,11 +18,6 @@
 	return hal_get_tx_buffer(&adapter->sHwData, &pMds->pTxBuffer);
 }
 
-void
-Mds_Destroy(struct wbsoft_priv *adapter)
-{
-}
-
 static void Mds_DurationSet(struct wbsoft_priv *adapter,  struct wb35_descriptor *pDes,  u8 *buffer)
 {
 	struct T00_descriptor *pT00;
diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
index 7f68dea..ce8be07 100644
--- a/drivers/staging/winbond/mds_f.h
+++ b/drivers/staging/winbond/mds_f.h
@@ -1,11 +1,10 @@
 #ifndef __WINBOND_MDS_F_H
 #define __WINBOND_MDS_F_H
 
-#include "wbhal_s.h"
+#include "wbhal.h"
 #include "core.h"
 
 unsigned char Mds_initial(struct wbsoft_priv *adapter);
-void Mds_Destroy(struct wbsoft_priv *adapter);
 void Mds_Tx(struct wbsoft_priv *adapter);
 void Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pt02);
 void Mds_MpduProcess(struct wbsoft_priv *adapter, struct wb35_descriptor *prxdes);
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
index 9cd2127..1faebce 100644
--- a/drivers/staging/winbond/mto.c
+++ b/drivers/staging/winbond/mto.c
@@ -19,7 +19,9 @@
 
 #include "sysdef.h"
 #include "sme_api.h"
-#include "wbhal_f.h"
+#include "wbhal.h"
+#include "wb35reg_f.h"
+#include "core.h"
 
 /* Declare SQ3 to rate and fragmentation threshold table */
 /* Declare fragmentation thresholds table */
diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
index 2b375ba..0658b09 100644
--- a/drivers/staging/winbond/phy_calibration.c
+++ b/drivers/staging/winbond/phy_calibration.c
@@ -12,7 +12,9 @@
 /****************** INCLUDE FILES SECTION ***********************************/
 #include "sysdef.h"
 #include "phy_calibration.h"
-#include "wbhal_f.h"
+#include "wbhal.h"
+#include "wb35reg_f.h"
+#include "core.h"
 
 
 /****************** DEBUG CONSTANT AND MACRO SECTION ************************/
diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h
index 3032031..84f6e84 100644
--- a/drivers/staging/winbond/phy_calibration.h
+++ b/drivers/staging/winbond/phy_calibration.h
@@ -1,7 +1,7 @@
 #ifndef __WINBOND_PHY_CALIBRATION_H
 #define __WINBOND_PHY_CALIBRATION_H
 
-#include "wbhal_f.h"
+#include "wbhal.h"
 
 #define REG_AGC_CTRL1		0x1000
 #define REG_AGC_CTRL2		0x1004
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
index 990f9d4..439d213 100644
--- a/drivers/staging/winbond/reg.c
+++ b/drivers/staging/winbond/reg.c
@@ -1,5 +1,7 @@
 #include "sysdef.h"
-#include "wbhal_f.h"
+#include "wbhal.h"
+#include "wb35reg_f.h"
+#include "core.h"
 
 /*
  * ====================================================
diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h
index bf23c10..95dc980 100644
--- a/drivers/staging/winbond/wb35reg_f.h
+++ b/drivers/staging/winbond/wb35reg_f.h
@@ -1,7 +1,7 @@
 #ifndef __WINBOND_WB35REG_F_H
 #define __WINBOND_WB35REG_F_H
 
-#include "wbhal_s.h"
+#include "wbhal.h"
 
 /*
  * ====================================
diff --git a/drivers/staging/winbond/wb35reg_s.h b/drivers/staging/winbond/wb35reg_s.h
index 4eff009..9d5993b 100644
--- a/drivers/staging/winbond/wb35reg_s.h
+++ b/drivers/staging/winbond/wb35reg_s.h
@@ -5,6 +5,8 @@
 #include <linux/types.h>
 #include <asm/atomic.h>
 
+struct hw_data;
+
 /* =========================================================================
  *
  *			HAL setting function
@@ -168,4 +170,76 @@
 	u32	SQ3_filter[MAX_SQ3_FILTER_SIZE];
 	u32	SQ3_index;
 };
+
+/* =====================================================================
+ * Function declaration
+ * =====================================================================
+ */
+void hal_remove_mapping_key(struct hw_data *hw_data, u8 *mac_addr);
+void hal_remove_default_key(struct hw_data *hw_data, u32 index);
+unsigned char hal_set_mapping_key(struct hw_data *adapter, u8 *mac_addr,
+				  u8 null_key, u8 wep_on, u8 *tx_tsc,
+				  u8 *rx_tsc, u8 key_type, u8 key_len,
+				  u8 *key_data);
+unsigned char hal_set_default_key(struct hw_data *adapter, u8 index,
+				  u8 null_key, u8 wep_on, u8 *tx_tsc,
+				  u8 *rx_tsc, u8 key_type, u8 key_len,
+				  u8 *key_data);
+void hal_clear_all_default_key(struct hw_data *hw_data);
+void hal_clear_all_group_key(struct hw_data *hw_data);
+void hal_clear_all_mapping_key(struct hw_data *hw_data);
+void hal_clear_all_key(struct hw_data *hw_data);
+void hal_set_power_save_mode(struct hw_data *hw_data, unsigned char power_save,
+			     unsigned char wakeup, unsigned char dtim);
+void hal_get_power_save_mode(struct hw_data *hw_data, u8 *in_pwr_save);
+void hal_set_slot_time(struct hw_data *hw_data, u8 type);
+
+#define hal_set_atim_window(_A, _ATM)
+
+void hal_start_bss(struct hw_data *hw_data, u8 mac_op_mode);
+
+/* 0:BSS STA 1:IBSS STA */
+void hal_join_request(struct hw_data *hw_data, u8 bss_type);
+
+void hal_stop_sync_bss(struct hw_data *hw_data);
+void hal_resume_sync_bss(struct hw_data *hw_data);
+void hal_set_aid(struct hw_data *hw_data, u16 aid);
+void hal_set_bssid(struct hw_data *hw_data, u8 *bssid);
+void hal_get_bssid(struct hw_data *hw_data, u8 *bssid);
+void hal_set_listen_interval(struct hw_data *hw_data, u16 listen_interval);
+void hal_set_cap_info(struct hw_data *hw_data, u16 capability_info);
+void hal_set_ssid(struct hw_data *hw_data, u8 *ssid, u8 ssid_len);
+void hal_start_tx0(struct hw_data *hw_data);
+
+#define hal_get_cwmin(_A)	((_A)->cwmin)
+
+void hal_set_cwmax(struct hw_data *hw_data, u16 cwin_max);
+
+#define hal_get_cwmax(_A)	((_A)->cwmax)
+
+void hal_set_rsn_wpa(struct hw_data *hw_data, u32 *rsn_ie_bitmap,
+		     u32 *rsn_oui_type , unsigned char desired_auth_mode);
+void hal_set_connect_info(struct hw_data *hw_data, unsigned char bo_connect);
+u8 hal_get_est_sq3(struct hw_data *hw_data, u8 count);
+void hal_descriptor_indicate(struct hw_data *hw_data,
+			     struct wb35_descriptor *des);
+u8 hal_get_antenna_number(struct hw_data *hw_data);
+u32 hal_get_bss_pk_cnt(struct hw_data *hw_data);
+
+#define hal_get_region_from_EEPROM(_A)	((_A)->reg.EEPROMRegion)
+#define hal_get_tx_buffer(_A, _B)	Wb35Tx_get_tx_buffer(_A, _B)
+#define hal_software_set(_A)		(_A->SoftwareSet)
+#define hal_driver_init_OK(_A)		(_A->IsInitOK)
+#define hal_rssi_boundary_high(_A)	(_A->RSSI_high)
+#define hal_rssi_boundary_low(_A)	(_A->RSSI_low)
+#define hal_scan_interval(_A)		(_A->Scan_Interval)
+
+#define PHY_DEBUG(msg, args...)
+
+/* return 100ms count */
+#define hal_get_time_count(_P)		(_P->time_count / 10)
+#define hal_detect_error(_P)		(_P->WbUsb.DetectCount)
+
+#define hal_ibss_disconnect(_A)		(hal_stop_sync_bss(_A))
+
 #endif
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 448514a..5af271f 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -174,7 +174,7 @@
 	/* The IRP is completed */
 	pWb35Rx->EP3vm_state = VM_COMPLETED;
 
-	if (pHwData->SurpriseRemove || pHwData->HwStop) /* Must be here, or RxBufferId is invalid */
+	if (pHwData->SurpriseRemove) /* Must be here, or RxBufferId is invalid */
 		goto error;
 
 	if (pWb35Rx->rx_halt)
@@ -239,7 +239,7 @@
 	u32			RxBufferId;
 
 	/* Issuing URB */
-	if (pHwData->SurpriseRemove || pHwData->HwStop)
+	if (pHwData->SurpriseRemove)
 		goto error;
 
 	if (pWb35Rx->rx_halt)
diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h
index 98acce5..1fdf65e 100644
--- a/drivers/staging/winbond/wb35rx_f.h
+++ b/drivers/staging/winbond/wb35rx_f.h
@@ -2,7 +2,7 @@
 #define __WINBOND_WB35RX_F_H
 
 #include <net/mac80211.h>
-#include "wbhal_s.h"
+#include "wbhal.h"
 
 //====================================
 // Interface function declare
diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c
index 2a9d055..fd52554 100644
--- a/drivers/staging/winbond/wb35tx.c
+++ b/drivers/staging/winbond/wb35tx.c
@@ -41,7 +41,7 @@
 	pWb35Tx->TxSendIndex++;
 	pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER;
 
-	if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
+	if (pHwData->SurpriseRemove) // Let WbWlanHalt to handle surprise remove
 		goto error;
 
 	if (pWb35Tx->tx_halt)
@@ -74,7 +74,7 @@
 	u32		SendIndex;
 
 
-	if (pHwData->SurpriseRemove || pHwData->HwStop)
+	if (pHwData->SurpriseRemove)
 		goto cleanup;
 
 	if (pWb35Tx->tx_halt)
@@ -222,7 +222,7 @@
 	pWb35Tx->EP2VM_status = pUrb->status;
 
 	// For Linux 2.4. Interrupt will always trigger
-	if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
+	if (pHwData->SurpriseRemove) // Let WbWlanHalt to handle surprise remove
 		goto error;
 
 	if (pWb35Tx->tx_halt)
@@ -263,7 +263,7 @@
 	u32 *	pltmp = (u32 *)pWb35Tx->EP2_buf;
 	int		retv;
 
-	if (pHwData->SurpriseRemove || pHwData->HwStop)
+	if (pHwData->SurpriseRemove)
 		goto error;
 
 	if (pWb35Tx->tx_halt)
diff --git a/drivers/staging/winbond/wb35tx_f.h b/drivers/staging/winbond/wb35tx_f.h
index 1d3b515..018fd35 100644
--- a/drivers/staging/winbond/wb35tx_f.h
+++ b/drivers/staging/winbond/wb35tx_f.h
@@ -2,7 +2,6 @@
 #define __WINBOND_WB35TX_F_H
 
 #include "core.h"
-#include "wbhal_f.h"
 
 /*
  * ====================================
diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal.h
similarity index 98%
rename from drivers/staging/winbond/wbhal_s.h
rename to drivers/staging/winbond/wbhal.h
index 821a1b3..dcf3b21 100644
--- a/drivers/staging/winbond/wbhal_s.h
+++ b/drivers/staging/winbond/wbhal.h
@@ -342,9 +342,6 @@
 	void	*buffer_address[MAX_DESCRIPTOR_BUFFER_INDEX];
 };
 
-
-#define DEFAULT_NULL_PACKET_COUNT	180000	/* 180 seconds */
-
 #define MAX_TXVGA_EEPROM		9	/* How many word(u16) of EEPROM will be used for TxVGA */
 #define MAX_RF_PARAMETER		32
 
@@ -510,16 +507,8 @@
 	u32		RxByteCountLast;
 	u32		TxByteCountLast;
 
-	atomic_t	SurpriseRemoveCount;
-
 	/* For global timer */
 	u32		time_count;	/* TICK_TIME_100ms 1 = 100ms */
-
-	/* For error recover */
-	u32		HwStop;
-
-	/* For avoid AP disconnect */
-	u32		NullPacketCount;
 };
 
 #endif
diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
deleted file mode 100644
index fc78c14..0000000
--- a/drivers/staging/winbond/wbhal_f.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * =====================================================================
- * Device related include
- * =====================================================================
-*/
-#include "wb35reg_f.h"
-#include "wb35tx_f.h"
-#include "wb35rx_f.h"
-
-#include "core.h"
-
-/* =====================================================================
- * Function declaration
- * =====================================================================
- */
-void hal_remove_mapping_key(struct hw_data *hw_data, u8 *mac_addr);
-void hal_remove_default_key(struct hw_data *hw_data, u32 index);
-unsigned char hal_set_mapping_key(struct hw_data *adapter, u8 *mac_addr,
-				  u8 null_key, u8 wep_on, u8 *tx_tsc,
-				  u8 *rx_tsc, u8 key_type, u8 key_len,
-				  u8 *key_data);
-unsigned char hal_set_default_key(struct hw_data *adapter, u8 index,
-				  u8 null_key, u8 wep_on, u8 *tx_tsc,
-				  u8 *rx_tsc, u8 key_type, u8 key_len,
-				  u8 *key_data);
-void hal_clear_all_default_key(struct hw_data *hw_data);
-void hal_clear_all_group_key(struct hw_data *hw_data);
-void hal_clear_all_mapping_key(struct hw_data *hw_data);
-void hal_clear_all_key(struct hw_data *hw_data);
-void hal_set_power_save_mode(struct hw_data *hw_data, unsigned char power_save,
-			     unsigned char wakeup, unsigned char dtim);
-void hal_get_power_save_mode(struct hw_data *hw_data, u8 *in_pwr_save);
-void hal_set_slot_time(struct hw_data *hw_data, u8 type);
-
-#define hal_set_atim_window(_A, _ATM)
-
-void hal_start_bss(struct hw_data *hw_data, u8 mac_op_mode);
-
-/* 0:BSS STA 1:IBSS STA */
-void hal_join_request(struct hw_data *hw_data, u8 bss_type);
-
-void hal_stop_sync_bss(struct hw_data *hw_data);
-void hal_resume_sync_bss(struct hw_data *hw_data);
-void hal_set_aid(struct hw_data *hw_data, u16 aid);
-void hal_set_bssid(struct hw_data *hw_data, u8 *bssid);
-void hal_get_bssid(struct hw_data *hw_data, u8 *bssid);
-void hal_set_listen_interval(struct hw_data *hw_data, u16 listen_interval);
-void hal_set_cap_info(struct hw_data *hw_data, u16 capability_info);
-void hal_set_ssid(struct hw_data *hw_data, u8 *ssid, u8 ssid_len);
-void hal_start_tx0(struct hw_data *hw_data);
-
-#define hal_get_cwmin(_A)	((_A)->cwmin)
-
-void hal_set_cwmax(struct hw_data *hw_data, u16 cwin_max);
-
-#define hal_get_cwmax(_A)	((_A)->cwmax)
-
-void hal_set_rsn_wpa(struct hw_data *hw_data, u32 *rsn_ie_bitmap,
-		     u32 *rsn_oui_type , unsigned char desired_auth_mode);
-void hal_set_connect_info(struct hw_data *hw_data, unsigned char bo_connect);
-u8 hal_get_est_sq3(struct hw_data *hw_data, u8 count);
-void hal_descriptor_indicate(struct hw_data *hw_data,
-			     struct wb35_descriptor *des);
-u8 hal_get_antenna_number(struct hw_data *hw_data);
-u32 hal_get_bss_pk_cnt(struct hw_data *hw_data);
-
-#define hal_get_region_from_EEPROM(_A)	((_A)->reg.EEPROMRegion)
-#define hal_get_tx_buffer(_A, _B)	Wb35Tx_get_tx_buffer(_A, _B)
-#define hal_software_set(_A)		(_A->SoftwareSet)
-#define hal_driver_init_OK(_A)		(_A->IsInitOK)
-#define hal_rssi_boundary_high(_A)	(_A->RSSI_high)
-#define hal_rssi_boundary_low(_A)	(_A->RSSI_low)
-#define hal_scan_interval(_A)		(_A->Scan_Interval)
-
-#define PHY_DEBUG(msg, args...)
-
-/* return 100ms count */
-#define hal_get_time_count(_P)		(_P->time_count / 10)
-#define hal_detect_error(_P)		(_P->WbUsb.DetectCount)
-
-#define hal_ibss_disconnect(_A)		(hal_stop_sync_bss(_A))
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 3f60cf7..dcb6d5b 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -16,7 +16,10 @@
 #include "mds_f.h"
 #include "mlmetxrx_f.h"
 #include "mto.h"
-#include "wbhal_f.h"
+#include "wbhal.h"
+#include "wb35reg_f.h"
+#include "wb35tx_f.h"
+#include "wb35rx_f.h"
 #include "wblinux_f.h"
 
 MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
@@ -608,15 +611,6 @@
 			}
 			break;
 		}
-
-		/* Active send null packet to avoid AP disconnect */
-		if (pHwData->LED_LinkOn) {
-			pHwData->NullPacketCount += TimeInterval;
-			if (pHwData->NullPacketCount >=
-			    DEFAULT_NULL_PACKET_COUNT) {
-				pHwData->NullPacketCount = 0;
-			}
-		}
 	}
 
 	pHwData->time_count += TimeInterval;
@@ -860,8 +854,6 @@
 
 static void wb35_hw_halt(struct wbsoft_priv *adapter)
 {
-	Mds_Destroy(adapter);
-
 	/* Turn off Rx and Tx hardware ability */
 	hal_stop(&adapter->sHwData);
 #ifdef _PE_USB_INI_DUMP_
diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c
index 7a1337d..a459e48 100644
--- a/drivers/staging/wlags49_h2/wl_profile.c
+++ b/drivers/staging/wlags49_h2/wl_profile.c
@@ -248,7 +248,7 @@
 		} else {
 			DBG_TRACE(DbgInfo, "F/W image file found\n");
 #define DHF_ALLOC_SIZE 96000			/* just below 96K, let's hope it suffices for now and for the future */
-			cp = (char *)vmalloc(DHF_ALLOC_SIZE);
+			cp = vmalloc(DHF_ALLOC_SIZE);
 			if (cp == NULL) {
 				DBG_ERROR(DbgInfo, "error in vmalloc\n");
 			} else {
diff --git a/drivers/staging/wlags49_h2/wl_sysfs.c b/drivers/staging/wlags49_h2/wl_sysfs.c
index e4c8804..9b833b3 100644
--- a/drivers/staging/wlags49_h2/wl_sysfs.c
+++ b/drivers/staging/wlags49_h2/wl_sysfs.c
@@ -42,7 +42,7 @@
     CFG_HERMES_TALLIES_STRCT tallies;
     ssize_t ret = -EINVAL;
 
-    read_lock(&dev_base_lock);
+    rcu_read_lock();
     if (dev_isalive(dev)) {
 	wl_lock(lp, &flags);
 
@@ -102,7 +102,7 @@
 	    }
     }
 
-    read_unlock(&dev_base_lock);
+    rcu_read_unlock();
     return ret;
 }
 
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 83879f9..146f365 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -148,7 +148,8 @@
 
 			/* tack on SNAP */
 			e_snap =
-			    (struct wlan_snap *) skb_push(skb, sizeof(struct wlan_snap));
+			    (struct wlan_snap *) skb_push(skb,
+				sizeof(struct wlan_snap));
 			e_snap->type = htons(proto);
 			if (ethconv == WLAN_ETHCONV_8021h
 			    && p80211_stt_findproto(proto)) {
@@ -161,7 +162,8 @@
 
 			/* tack on llc */
 			e_llc =
-			    (struct wlan_llc *) skb_push(skb, sizeof(struct wlan_llc));
+			    (struct wlan_llc *) skb_push(skb,
+				sizeof(struct wlan_llc));
 			e_llc->dsap = 0xAA;	/* SNAP, see IEEE 802 */
 			e_llc->ssap = 0xAA;
 			e_llc->ctl = 0x03;
@@ -297,10 +299,12 @@
 	if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
 		memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
 		memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
-	} else if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1)) {
+	} else if ((WLAN_GET_FC_TODS(fc) == 0)
+			&& (WLAN_GET_FC_FROMDS(fc) == 1)) {
 		memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
 		memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
-	} else if ((WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
+	} else if ((WLAN_GET_FC_TODS(fc) == 1)
+			&& (WLAN_GET_FC_FROMDS(fc) == 0)) {
 		memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
 		memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
 	} else {
@@ -349,7 +353,8 @@
 
 	e_llc = (struct wlan_llc *) (skb->data + payload_offset);
 	e_snap =
-	    (struct wlan_snap *) (skb->data + payload_offset + sizeof(struct wlan_llc));
+	    (struct wlan_snap *) (skb->data + payload_offset +
+		sizeof(struct wlan_llc));
 
 	/* Test for the various encodings */
 	if ((payload_length >= sizeof(struct wlan_ethhdr)) &&
@@ -372,9 +377,11 @@
 		/* chop off the 802.11 CRC */
 		skb_trim(skb, skb->len - WLAN_CRC_LEN);
 
-	} else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap))
-		   && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
-		   && (e_llc->ctl == 0x03)
+	} else if ((payload_length >= sizeof(struct wlan_llc) +
+		sizeof(struct wlan_snap))
+		&&(e_llc->dsap == 0xaa)
+		&& (e_llc->ssap == 0xaa)
+		&& (e_llc->ctl == 0x03)
 		   &&
 		   (((memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) == 0)
 		     && (ethconv == WLAN_ETHCONV_8021h)
@@ -406,21 +413,25 @@
 		/* chop off the 802.11 CRC */
 		skb_trim(skb, skb->len - WLAN_CRC_LEN);
 
-	} else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap))
-		   && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
-		   && (e_llc->ctl == 0x03)) {
+	} else if ((payload_length >= sizeof(struct wlan_llc) +
+		sizeof(struct wlan_snap))
+		&&(e_llc->dsap == 0xaa)
+		&& (e_llc->ssap == 0xaa)
+		&& (e_llc->ctl == 0x03)) {
 		pr_debug("802.1h/RFC1042 len: %d\n", payload_length);
-		/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
-		/* build a DIXII + RFC894 */
+		/* it's an 802.1h frame || (an RFC1042 && protocol not in STT)
+		   build a DIXII + RFC894 */
 
 		/* Test for an overlength frame */
-		if ((payload_length - sizeof(struct wlan_llc) - sizeof(struct wlan_snap))
-		    > netdev->mtu) {
+		if ((payload_length - sizeof(struct wlan_llc) -
+			sizeof(struct wlan_snap))
+			> netdev->mtu) {
 			/* A bogus length ethfrm has been sent. */
 			/* Is someone trying an oflow attack? */
 			printk(KERN_ERR "DIXII frame too large (%ld > %d)\n",
-			       (long int)(payload_length - sizeof(struct wlan_llc) -
-					  sizeof(struct wlan_snap)), netdev->mtu);
+			       (long int)(payload_length -
+					sizeof(struct wlan_llc) -
+					sizeof(struct wlan_snap)), netdev->mtu);
 			return 1;
 		}
 
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
index eca0391..ea493aa 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -66,12 +66,14 @@
 #define	P80211_FRMMETA_MAGIC	0x802110
 
 #define P80211SKB_FRMMETA(s) \
-	(((((struct p80211_frmmeta *)((s)->cb))->magic) == P80211_FRMMETA_MAGIC) ? \
+	(((((struct p80211_frmmeta *)((s)->cb))->magic) == \
+		P80211_FRMMETA_MAGIC) ? \
 		((struct p80211_frmmeta *)((s)->cb)) : \
 		(NULL))
 
 #define P80211SKB_RXMETA(s) \
-	(P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : ((struct p80211_rxmeta *)(NULL)))
+	(P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : \
+		((struct p80211_rxmeta *)(NULL)))
 
 struct p80211_rxmeta {
 	struct wlandevice *wlandev;
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index b7b4a73..b0af292 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -301,7 +301,8 @@
 					if (memcmp
 					    (hdr->a1, wlandev->netdev->dev_addr,
 					     ETH_ALEN) != 0) {
-						/* but reject anything else that isn't multicast */
+						/* but reject anything else that
+						   isn't multicast */
 						if (!(hdr->a1[0] & 0x01)) {
 							dev_kfree_skb(skb);
 							continue;
@@ -770,7 +771,8 @@
 	}
 
 	/* Allocate and initialize the struct device */
-	netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", ether_setup);
+	netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d",
+				ether_setup);
 	if (netdev == NULL) {
 		printk(KERN_ERR "Failed to alloc netdev.\n");
 		wlan_free_wiphy(wiphy);
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 1ec3374..8588417 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -94,11 +94,11 @@
 #endif
 
 /*--- NSD Capabilities Flags ------------------------------*/
-#define P80211_NSDCAP_HARDWAREWEP           0x01	/* hardware wep engine */
-#define P80211_NSDCAP_SHORT_PREAMBLE        0x10	/* hardware supports */
-#define P80211_NSDCAP_HWFRAGMENT            0x80	/* nsd handles frag/defrag */
-#define P80211_NSDCAP_AUTOJOIN              0x100	/* nsd does autojoin */
-#define P80211_NSDCAP_NOSCAN                0x200	/* nsd can scan */
+#define P80211_NSDCAP_HARDWAREWEP           0x01  /* hardware wep engine */
+#define P80211_NSDCAP_SHORT_PREAMBLE        0x10  /* hardware supports */
+#define P80211_NSDCAP_HWFRAGMENT            0x80  /* nsd handles frag/defrag */
+#define P80211_NSDCAP_AUTOJOIN              0x100 /* nsd does autojoin */
+#define P80211_NSDCAP_NOSCAN                0x200 /* nsd can scan */
 
 /* Received frame statistics */
 typedef struct p80211_frmrx_t {
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 41a99c5..9dec8596 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -141,14 +141,14 @@
 #define P80211DID_LSB_ITEM		(12)
 #define P80211DID_LSB_INDEX		(18)
 #define P80211DID_LSB_ISTABLE		(26)
-#define P80211DID_LSB_ACCESS 		(27)
+#define P80211DID_LSB_ACCESS		(27)
 
 #define P80211DID_MASK_SECTION		(0x0000003fUL)
 #define P80211DID_MASK_GROUP		(0x0000003fUL)
 #define P80211DID_MASK_ITEM		(0x0000003fUL)
 #define P80211DID_MASK_INDEX		(0x000000ffUL)
 #define P80211DID_MASK_ISTABLE		(0x00000001UL)
-#define P80211DID_MASK_ACCESS 		(0x00000003UL)
+#define P80211DID_MASK_ACCESS		(0x00000003UL)
 
 #define P80211DID_MK(a, m, l)	((((u32)(a)) & (m)) << (l))
 
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index 04514a8..6675c822 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -213,8 +213,8 @@
 		u16 wordbuf[17];
 
 		result = hfa384x_drvr_setconfig16(hw,
-						  HFA384x_RID_CNFROAMINGMODE,
-						  HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+					HFA384x_RID_CNFROAMINGMODE,
+					HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
 		if (result) {
 			printk(KERN_ERR
 			       "setconfig(ROAMINGMODE) failed. result=%d\n",
@@ -258,8 +258,8 @@
 		}
 		/* ibss options */
 		result = hfa384x_drvr_setconfig16(hw,
-						  HFA384x_RID_CREATEIBSS,
-						  HFA384x_CREATEIBSS_JOINCREATEIBSS);
+					HFA384x_RID_CREATEIBSS,
+					HFA384x_CREATEIBSS_JOINCREATEIBSS);
 		if (result) {
 			printk(KERN_ERR "Failed to set CREATEIBSS.\n");
 			msg->resultcode.data =
@@ -416,7 +416,8 @@
 #define REQBASICRATE(N) \
 	if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
 		req->basicrate ## N .data = item->supprates[(N)-1]; \
-		req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \
+		req->basicrate ## N .status = \
+			P80211ENUM_msgitem_status_data_ok; \
 	}
 
 	REQBASICRATE(1);
@@ -431,7 +432,8 @@
 #define REQSUPPRATE(N) \
 	if (count >= N) { \
 		req->supprate ## N .data = item->supprates[(N)-1]; \
-		req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \
+		req->supprate ## N .status = \
+			P80211ENUM_msgitem_status_data_ok; \
 	}
 
 	REQSUPPRATE(1);
@@ -1102,7 +1104,7 @@
 		result = hfa384x_drvr_disable(hw, 0);
 		if (result) {
 			pr_debug
-			    ("failed to disable port 0 after sniffing, result=%d\n",
+			("failed to disable port 0 after sniffing, result=%d\n",
 			     result);
 			goto failed;
 		}
@@ -1137,7 +1139,7 @@
 			result = hfa384x_drvr_enable(hw, 0);
 			if (result) {
 				pr_debug
-				    ("failed to enable port to presniff setting, result=%d\n",
+				("failed to enable port to presniff setting, result=%d\n",
 				     result);
 				goto failed;
 			}
@@ -1161,7 +1163,7 @@
 						  &(hw->presniff_port_type));
 				if (result) {
 					pr_debug
-					    ("failed to read porttype, result=%d\n",
+					("failed to read porttype, result=%d\n",
 					     result);
 					goto failed;
 				}
@@ -1171,7 +1173,7 @@
 						  &(hw->presniff_wepflags));
 				if (result) {
 					pr_debug
-					    ("failed to read wepflags, result=%d\n",
+					("failed to read wepflags, result=%d\n",
 					     result);
 					goto failed;
 				}
@@ -1238,8 +1240,8 @@
 
 			if (result) {
 				pr_debug
-				    ("failed to set wepflags=0x%04x, result=%d\n",
-				     word, result);
+				  ("failed to set wepflags=0x%04x, result=%d\n",
+				   word, result);
 				goto failed;
 			}
 		}
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 4f73d09..ee008e5 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -472,9 +472,11 @@
 			break;
 		}
 
-		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
-		if (pdev)
+		pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+		if (pdev) {
 			valid_pdev = 1;
+			pci_dev_put(pdev);
+		}
 	}
 
 	if (!valid_pdev) {
@@ -2178,8 +2180,7 @@
 
 #ifndef AGPOFF
 	if (XGIfb_queuemode == AGP_CMD_QUEUE) {
-		agp_info = vmalloc(sizeof(*agp_info));
-		memset((void *)agp_info, 0x00, sizeof(*agp_info));
+		agp_info = vzalloc(sizeof(*agp_info));
 		agp_copy_info(agp_info);
 
 		agp_backend_acquire();
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 8c3c057..43fd608 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -533,7 +533,7 @@
 	}
 
 	num_pages = zram->disksize >> PAGE_SHIFT;
-	zram->table = vmalloc(num_pages * sizeof(*zram->table));
+	zram->table = vzalloc(num_pages * sizeof(*zram->table));
 	if (!zram->table) {
 		pr_err("Error allocating zram address table\n");
 		/* To prevent accessing table entries during cleanup */
@@ -541,7 +541,6 @@
 		ret = -ENOMEM;
 		goto fail;
 	}
-	memset(zram->table, 0, num_pages * sizeof(*zram->table));
 
 	set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
 
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index ef2977d..a5e63d1 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -615,7 +615,6 @@
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0006, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0007, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0008, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0009, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000a, 0xff, 0xff, 0xff) },