diff -r 0d667d493399 -r 1432098ff390 linux/drivers/media/dvb/siano/smscoreapi.c
--- a/linux/drivers/media/dvb/siano/smscoreapi.c	Tue Jan 13 13:59:28 2009 +0200
+++ b/linux/drivers/media/dvb/siano/smscoreapi.c	Tue Jan 13 14:08:17 2009 +0200
@@ -1,25 +1,23 @@
-/*
- *  Siano core API module
- *
- *  This file contains implementation for the interface to sms core component
- *
- *  author: Anatoly Greenblat
- *
- *  Copyright (c), 2005-2008 Siano Mobile Silicon, 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;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2008, Uri Shkolnik
+
+ 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, either version 2 of the License, or
+ (at your option) any later version.
+
+ 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.  If not, see <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
 
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -28,15 +26,28 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/uaccess.h>
 
 #include <linux/firmware.h>
 
 #include "smscoreapi.h"
 #include "sms-cards.h"
 
+#define MAX_GPIO_PIN_NUMBER	31
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
+#define REQUEST_FIRMWARE_SUPPORTED
+#else
+#define DEFAULT_FW_FILE_PATH "/lib/firmware"
+#endif
+
 int sms_debug;
 module_param_named(debug, sms_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+static int default_mode = 4;
+module_param(default_mode, int, 0644);
+MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
 
 struct smscore_device_notifyee_t {
 	struct list_head entry;
@@ -45,17 +56,17 @@ struct smscore_device_notifyee_t {
 
 struct smscore_idlist_t {
 	struct list_head entry;
-	int		id;
-	int		data_type;
+	int id;
+	int data_type;
 };
 
 struct smscore_client_t {
 	struct list_head entry;
 	struct smscore_device_t *coredev;
-	void			*context;
-	struct list_head 	idlist;
-	onresponse_t	onresponse_handler;
-	onremove_t		onremove_handler;
+	void *context;
+	struct list_head idlist;
+	onresponse_t onresponse_handler;
+	onremove_t onremove_handler;
 };
 
 struct smscore_device_t {
@@ -63,47 +74,46 @@ struct smscore_device_t {
 
 	struct list_head clients;
 	struct list_head subclients;
-	spinlock_t		clientslock;
+	spinlock_t clientslock;
 
 	struct list_head buffers;
-	spinlock_t		bufferslock;
-	int				num_buffers;
+	spinlock_t bufferslock;
+	int num_buffers;
 
-	void			*common_buffer;
-	int				common_buffer_size;
-	dma_addr_t		common_buffer_phys;
+	void *common_buffer;
+	int common_buffer_size;
+	dma_addr_t common_buffer_phys;
 
-	void			*context;
-	struct device	*device;
+	void *context;
+	struct device *device;
 
-	char			devpath[32];
-	unsigned long	device_flags;
+	char devpath[32];
+	unsigned long device_flags;
 
-	setmode_t		setmode_handler;
-	detectmode_t	detectmode_handler;
-	sendrequest_t	sendrequest_handler;
-	preload_t		preload_handler;
-	postload_t		postload_handler;
+	setmode_t setmode_handler;
+	detectmode_t detectmode_handler;
+	sendrequest_t sendrequest_handler;
+	preload_t preload_handler;
+	postload_t postload_handler;
 
-	int				mode, modes_supported;
+	int mode, modes_supported;
 
 	struct completion version_ex_done, data_download_done, trigger_done;
 	struct completion init_device_done, reload_start_done, resume_done;
+	struct completion gpio_configuration_done, gpio_set_level_done;
+	struct completion gpio_get_level_done;
+
+	int gpio_get_res;
 
 	int board_id;
-	int led_state;
+
+	u8 *fw_buf;
+	u32 fw_buf_size;
 };
 
 void smscore_set_board_id(struct smscore_device_t *core, int id)
 {
 	core->board_id = id;
-}
-
-int smscore_led_state(struct smscore_device_t *core, int led)
-{
-	if (led >= 0)
-		core->led_state = led;
-	return core->led_state;
 }
 
 int smscore_get_board_id(struct smscore_device_t *core)
@@ -113,9 +123,9 @@ int smscore_get_board_id(struct smscore_
 
 struct smscore_registry_entry_t {
 	struct list_head entry;
-	char			devpath[32];
-	int				mode;
-	enum sms_device_type_st	type;
+	char devpath[32];
+	int mode;
+	enum sms_device_type_st type;
 };
 
 static struct list_head g_smscore_notifyees;
@@ -125,29 +135,22 @@ static struct list_head g_smscore_regist
 static struct list_head g_smscore_registry;
 static struct mutex g_smscore_registrylock;
 
-static int default_mode = 4;
-
-module_param(default_mode, int, 0644);
-MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
-
 static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
 {
 	struct smscore_registry_entry_t *entry;
 	struct list_head *next;
 
 	kmutex_lock(&g_smscore_registrylock);
-	for (next = g_smscore_registry.next;
-	     next != &g_smscore_registry;
-	     next = next->next) {
+	for (next = g_smscore_registry.next; next != &g_smscore_registry; next
+			= next->next) {
 		entry = (struct smscore_registry_entry_t *) next;
 		if (!strcmp(entry->devpath, devpath)) {
 			kmutex_unlock(&g_smscore_registrylock);
 			return entry;
 		}
 	}
-	entry = (struct smscore_registry_entry_t *)
-			kmalloc(sizeof(struct smscore_registry_entry_t),
-				GFP_KERNEL);
+	entry = /* (struct smscore_registry_entry_t *) */kmalloc(
+			sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
 	if (entry) {
 		entry->mode = default_mode;
 		strcpy(entry->devpath, devpath);
@@ -196,8 +199,7 @@ void smscore_registry_setmode(char *devp
 }
 
 static void smscore_registry_settype(char *devpath,
-				     enum sms_device_type_st type)
-{
+		enum sms_device_type_st type) {
 	struct smscore_registry_entry_t *entry;
 
 	entry = smscore_find_registry(devpath);
@@ -207,16 +209,12 @@ static void smscore_registry_settype(cha
 		sms_err("No registry found.");
 }
 
-
 static void list_add_locked(struct list_head *new, struct list_head *head,
-			    spinlock_t *lock)
-{
+		spinlock_t *lock) {
 	unsigned long flags;
 
 	spin_lock_irqsave(lock, flags);
-
 	list_add(new, head);
-
 	spin_unlock_irqrestore(lock, flags);
 }
 
@@ -237,13 +235,12 @@ int smscore_register_hotplug(hotplug_t h
 	kmutex_lock(&g_smscore_deviceslock);
 
 	notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
-			   GFP_KERNEL);
+		GFP_KERNEL);
 	if (notifyee) {
 		/* now notify callback about existing devices */
 		first = &g_smscore_devices;
-		for (next = first->next;
-		     next != first && !rc;
-		     next = next->next) {
+		for (next = first->next; next != first && !rc;
+			next = next->next) {
 			struct smscore_device_t *coredev =
 				(struct smscore_device_t *) next;
 			rc = hotplug(coredev, coredev->device, 1);
@@ -278,7 +275,7 @@ void smscore_unregister_hotplug(hotplug_
 
 	for (next = first->next; next != first;) {
 		struct smscore_device_notifyee_t *notifyee =
-			(struct smscore_device_notifyee_t *) next;
+				(struct smscore_device_notifyee_t *) next;
 		next = next->next;
 
 		if (notifyee->hotplug == hotplug) {
@@ -302,8 +299,7 @@ static void smscore_notify_clients(struc
 }
 
 static int smscore_notify_callbacks(struct smscore_device_t *coredev,
-				    struct device *device, int arrival)
-{
+		struct device *device, int arrival) {
 	struct list_head *next, *first;
 	int rc = 0;
 
@@ -313,7 +309,7 @@ static int smscore_notify_callbacks(stru
 
 	for (next = first->next; next != first; next = next->next) {
 		rc = ((struct smscore_device_notifyee_t *) next)->
-				hotplug(coredev, device, arrival);
+			 hotplug(coredev, device, arrival);
 		if (rc < 0)
 			break;
 	}
@@ -321,12 +317,10 @@ static int smscore_notify_callbacks(stru
 	return rc;
 }
 
-static struct
-smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
-				       dma_addr_t common_buffer_phys)
-{
-	struct smscore_buffer_t *cb =
-		kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
+static struct smscore_buffer_t *smscore_createbuffer(u8 *buffer,
+		void *common_buffer, dma_addr_t common_buffer_phys) {
+	struct smscore_buffer_t *cb = kmalloc(sizeof(struct smscore_buffer_t),
+			GFP_KERNEL);
 	if (!cb) {
 		sms_info("kmalloc(...) failed");
 		return NULL;
@@ -350,8 +344,7 @@ smscore_buffer_t *smscore_createbuffer(u
  * @return 0 on success, <0 on error.
  */
 int smscore_register_device(struct smsdevice_params_t *params,
-			    struct smscore_device_t **coredev)
-{
+		struct smscore_device_t **coredev) {
 	struct smscore_device_t *dev;
 	u8 *buffer;
 
@@ -379,24 +372,25 @@ int smscore_register_device(struct smsde
 	init_completion(&dev->init_device_done);
 	init_completion(&dev->reload_start_done);
 	init_completion(&dev->resume_done);
+	init_completion(&dev->gpio_configuration_done);
+	init_completion(&dev->gpio_set_level_done);
+	init_completion(&dev->gpio_get_level_done);
 
 	/* alloc common buffer */
 	dev->common_buffer_size = params->buffer_size * params->num_buffers;
 	dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
-						&dev->common_buffer_phys,
-						GFP_KERNEL | GFP_DMA);
+			&dev->common_buffer_phys, GFP_KERNEL | GFP_DMA);
 	if (!dev->common_buffer) {
 		smscore_unregister_device(dev);
 		return -ENOMEM;
 	}
 
 	/* prepare dma buffers */
-	for (buffer = dev->common_buffer;
-	     dev->num_buffers < params->num_buffers;
-	     dev->num_buffers++, buffer += params->buffer_size) {
-		struct smscore_buffer_t *cb =
-			smscore_createbuffer(buffer, dev->common_buffer,
-					     dev->common_buffer_phys);
+	for (buffer = dev->common_buffer; dev->num_buffers <
+			params->num_buffers; dev->num_buffers++, buffer
+			+= params->buffer_size) {
+		struct smscore_buffer_t *cb = smscore_createbuffer(buffer,
+				dev->common_buffer, dev->common_buffer_phys);
 		if (!cb) {
 			smscore_unregister_device(dev);
 			return -ENOMEM;
@@ -443,12 +437,16 @@ int smscore_register_device(struct smsde
  */
 int smscore_start_device(struct smscore_device_t *coredev)
 {
-	int rc = smscore_set_device_mode(
-			coredev, smscore_registry_getmode(coredev->devpath));
+	int rc;
+
+#ifdef REQUEST_FIRMWARE_SUPPORTED
+	rc = smscore_set_device_mode(coredev, smscore_registry_getmode(
+			coredev->devpath));
 	if (rc < 0) {
 		sms_info("set device mode faile , rc %d", rc);
 		return rc;
 	}
+#endif
 
 	kmutex_lock(&g_smscore_deviceslock);
 
@@ -462,9 +460,7 @@ int smscore_start_device(struct smscore_
 }
 
 static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
-					void *buffer, size_t size,
-					struct completion *completion)
-{
+		void *buffer, size_t size, struct completion *completion) {
 	int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
 	if (rc < 0) {
 		sms_info("sendrequest returned error %d", rc);
@@ -472,13 +468,11 @@ static int smscore_sendrequest_and_wait(
 	}
 
 	return wait_for_completion_timeout(completion,
-					   msecs_to_jiffies(10000)) ?
-						0 : -ETIME;
+			msecs_to_jiffies(10000)) ? 0 : -ETIME;
 }
 
 static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
-					 void *buffer, size_t size)
-{
+		void *buffer, size_t size) {
 	struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
 	struct SmsMsgHdr_ST *msg;
 	u32 mem_address = firmware->StartAddress;
@@ -486,7 +480,7 @@ static int smscore_load_firmware_family2
 	int rc = 0;
 
 	sms_info("loading FW to addr 0x%x size %d",
-		 mem_address, firmware->Length);
+			mem_address, firmware->Length);
 	if (coredev->preload_handler) {
 		rc = coredev->preload_handler(coredev->context);
 		if (rc < 0)
@@ -501,35 +495,33 @@ static int smscore_load_firmware_family2
 	if (coredev->mode != DEVICE_MODE_NONE) {
 		sms_debug("sending reload command.");
 		SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
-			     sizeof(struct SmsMsgHdr_ST));
-		rc = smscore_sendrequest_and_wait(coredev, msg,
-						  msg->msgLength,
-						  &coredev->reload_start_done);
+				sizeof(struct SmsMsgHdr_ST));
+		rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
+				&coredev->reload_start_done);
 		mem_address = *(u32 *) &payload[20];
 	}
 
 	while (size && rc >= 0) {
 		struct SmsDataDownload_ST *DataMsg =
-			(struct SmsDataDownload_ST *) msg;
-		int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
+				(struct SmsDataDownload_ST *) msg;
+		int payload_size = min((int)size, SMS_MAX_PAYLOAD_SIZE);
 
 		SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
-			     (u16)(sizeof(struct SmsMsgHdr_ST) +
-				      sizeof(u32) + payload_size));
+				(u16) (sizeof(struct SmsMsgHdr_ST) +
+						sizeof(u32) + payload_size));
 
 		DataMsg->MemAddr = mem_address;
 		memcpy(DataMsg->Payload, payload, payload_size);
 
 		if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
-		    (coredev->mode == DEVICE_MODE_NONE))
-			rc = coredev->sendrequest_handler(
-				coredev->context, DataMsg,
-				DataMsg->xMsgHeader.msgLength);
+				(coredev->mode	== DEVICE_MODE_NONE))
+			rc = coredev->sendrequest_handler(coredev->context,
+DataMsg,
+					DataMsg->xMsgHeader. msgLength);
 		else
-			rc = smscore_sendrequest_and_wait(
-				coredev, DataMsg,
-				DataMsg->xMsgHeader.msgLength,
-				&coredev->data_download_done);
+			rc = smscore_sendrequest_and_wait(coredev, DataMsg,
+					DataMsg->xMsgHeader. msgLength,
+					&coredev->data_download_done);
 
 		payload += payload_size;
 		size -= payload_size;
@@ -539,47 +531,45 @@ static int smscore_load_firmware_family2
 	if (rc >= 0) {
 		if (coredev->mode == DEVICE_MODE_NONE) {
 			struct SmsMsgData_ST *TriggerMsg =
-				(struct SmsMsgData_ST *) msg;
+					(struct SmsMsgData_ST *) msg;
 
 			SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
-				     sizeof(struct SmsMsgHdr_ST) +
-				     sizeof(u32) * 5);
+					sizeof(struct SmsMsgHdr_ST) +
+					sizeof(u32) * 5);
 
 			TriggerMsg->msgData[0] = firmware->StartAddress;
-						/* Entry point */
+			/* Entry point */
 			TriggerMsg->msgData[1] = 5; /* Priority */
 			TriggerMsg->msgData[2] = 0x200; /* Stack size */
 			TriggerMsg->msgData[3] = 0; /* Parameter */
 			TriggerMsg->msgData[4] = 4; /* Task ID */
 
 			if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
-				rc = coredev->sendrequest_handler(
-					coredev->context, TriggerMsg,
+				rc = coredev->sendrequest_handler(coredev->
+					context, TriggerMsg,
 					TriggerMsg->xMsgHeader.msgLength);
 				msleep(100);
 			} else
-				rc = smscore_sendrequest_and_wait(
-					coredev, TriggerMsg,
+				rc = smscore_sendrequest_and_wait(coredev,
+					TriggerMsg,
 					TriggerMsg->xMsgHeader.msgLength,
 					&coredev->trigger_done);
 		} else {
 			SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
-				     sizeof(struct SmsMsgHdr_ST));
+					sizeof(struct SmsMsgHdr_ST));
 
-			rc = coredev->sendrequest_handler(coredev->context,
-							  msg, msg->msgLength);
+			rc = coredev->sendrequest_handler(coredev->context, msg,
+					msg->msgLength);
 		}
 		msleep(500);
 	}
 
-	sms_debug("rc=%d, postload=%p ", rc,
-		  coredev->postload_handler);
+	sms_debug("rc=%d, postload=%p ", rc, coredev->postload_handler);
 
 	kfree(msg);
 
 	return ((rc >= 0) && coredev->postload_handler) ?
-		coredev->postload_handler(coredev->context) :
-		rc;
+			coredev->postload_handler(coredev->context) : rc;
 }
 
 /**
@@ -593,15 +583,16 @@ static int smscore_load_firmware_family2
  * @return 0 on success, <0 on error.
  */
 static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
-					   char *filename,
-					   loadfirmware_t loadfirmware_handler)
-{
+		char *filename, loadfirmware_t loadfirmware_handler) {
 	int rc = -ENOENT;
+	u8 *fw_buf;
+	u32 fw_buf_size;
+
+#ifdef REQUEST_FIRMWARE_SUPPORTED
 	const struct firmware *fw;
-	u8 *fw_buffer;
 
-	if (loadfirmware_handler == NULL && !(coredev->device_flags &
-					      SMS_DEVICE_FAMILY2))
+	if (loadfirmware_handler == NULL && !(coredev->device_flags
+			& SMS_DEVICE_FAMILY2))
 		return -EINVAL;
 
 	rc = request_firmware(&fw, filename, coredev->device);
@@ -610,26 +601,36 @@ static int smscore_load_firmware_from_fi
 		return rc;
 	}
 	sms_info("read FW %s, size=%zd", filename, fw->size);
-	fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
-			    GFP_KERNEL | GFP_DMA);
-	if (fw_buffer) {
-		memcpy(fw_buffer, fw->data, fw->size);
+	fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
+				GFP_KERNEL | GFP_DMA);
+	if (!fw_buf) {
+		sms_info("failed to allocate firmware buffer");
+		return -ENOMEM;
+	}
+	memcpy(fw_buf, fw->data, fw->size);
+	fw_buf_size = fw->size;
+#else
+	if (!coredev->fw_buf) {
+		sms_info("missing fw file buffer");
+		return -EINVAL;
+	}
+	fw_buf = coredev->fw_buf;
+	fw_buf_size = coredev->fw_buf_size;
+#endif
 
-		rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
-		      smscore_load_firmware_family2(coredev,
-						    fw_buffer,
-						    fw->size) :
-		      loadfirmware_handler(coredev->context,
-					   fw_buffer, fw->size);
+	rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+		smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
+		: loadfirmware_handler(coredev->context, fw_buf,
+		fw_buf_size);
 
-		kfree(fw_buffer);
-	} else {
-		sms_info("failed to allocate firmware buffer");
-		rc = -ENOMEM;
-	}
+	kfree(fw_buf);
 
+#ifdef REQUEST_FIRMWARE_SUPPORTED
 	release_firmware(fw);
-
+#else
+	coredev->fw_buf = NULL;
+	coredev->fw_buf_size = 0;
+#endif
 	return rc;
 }
 
@@ -665,12 +666,12 @@ void smscore_unregister_device(struct sm
 			break;
 		if (++retry > 10) {
 			sms_info("exiting although "
-				 "not all buffers released.");
+					"not all buffers released.");
 			break;
 		}
 
 		sms_info("waiting for %d buffer(s)",
-			 coredev->num_buffers - num_buffers);
+				coredev->num_buffers - num_buffers);
 		msleep(100);
 	}
 
@@ -678,8 +679,10 @@ void smscore_unregister_device(struct sm
 
 	if (coredev->common_buffer)
 		dma_free_coherent(NULL, coredev->common_buffer_size,
-				  coredev->common_buffer,
-				  coredev->common_buffer_phys);
+			coredev->common_buffer, coredev->common_buffer_phys);
+
+	if (coredev->fw_buf != NULL)
+		kfree(coredev->fw_buf);
 
 	list_del(&coredev->entry);
 	kfree(coredev);
@@ -692,30 +695,29 @@ static int smscore_detect_mode(struct sm
 static int smscore_detect_mode(struct smscore_device_t *coredev)
 {
 	void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
-			       GFP_KERNEL | GFP_DMA);
+			GFP_KERNEL | GFP_DMA);
 	struct SmsMsgHdr_ST *msg =
-		(struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
+			(struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
 	int rc;
 
 	if (!buffer)
 		return -ENOMEM;
 
 	SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
-		     sizeof(struct SmsMsgHdr_ST));
+			sizeof(struct SmsMsgHdr_ST));
 
 	rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
-					  &coredev->version_ex_done);
+			&coredev->version_ex_done);
 	if (rc == -ETIME) {
 		sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
 
 		if (wait_for_completion_timeout(&coredev->resume_done,
-						msecs_to_jiffies(5000))) {
-			rc = smscore_sendrequest_and_wait(
-				coredev, msg, msg->msgLength,
-				&coredev->version_ex_done);
+				msecs_to_jiffies(5000))) {
+			rc = smscore_sendrequest_and_wait(coredev, msg,
+				msg->msgLength, &coredev->version_ex_done);
 			if (rc < 0)
 				sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
-					"second try, rc %d", rc);
+						"second try, rc %d", rc);
 		} else
 			rc = -ETIME;
 	}
@@ -726,28 +728,24 @@ static int smscore_detect_mode(struct sm
 }
 
 static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
-	/*Stellar		NOVA A0		Nova B0		VEGA*/
-	/*DVBT*/
-	{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-	/*DVBH*/
-	{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-	/*TDMB*/
-	{"none", "tdmb_nova_12mhz.inp", "none", "none"},
-	/*DABIP*/
-	{"none", "none", "none", "none"},
-	/*BDA*/
-	{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-	/*ISDBT*/
-	{"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"},
-	/*ISDBTBDA*/
-	{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
-	/*CMMB*/
-	{"none", "none", "none", "cmmb_vega_12mhz.inp"}
-};
+/*Stellar               NOVA A0         Nova B0         VEGA */
+/*DVBT*/
+{ "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
+/*DVBH*/
+{ "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
+/*TDMB*/
+{ "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none" },
+/*DABIP*/{ "none", "none", "none", "none" },
+/*BDA*/
+{ "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
+/*ISDBT*/
+{ "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none" },
+/*ISDBTBDA*/
+{ "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none" },
+/*CMMB*/{ "none", "none", "none", "cmmb_vega_12mhz.inp" } };
 
-static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
-				    int mode, enum sms_device_type_st type)
-{
+static inline char *sms_get_fw_name(struct smscore_device_t *coredev, int mode,
+		enum sms_device_type_st type) {
 	char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
 	return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
 }
@@ -797,48 +795,48 @@ int smscore_set_device_mode(struct smsco
 			fw_filename = sms_get_fw_name(coredev, mode, type);
 
 			rc = smscore_load_firmware_from_file(coredev,
-							     fw_filename, NULL);
+					fw_filename, NULL);
 			if (rc < 0) {
 				sms_warn("error %d loading firmware: %s, "
-					 "trying again with default firmware",
-					 rc, fw_filename);
+					"trying again with default firmware",
+					rc, fw_filename);
 
 				/* try again with the default firmware */
 				fw_filename = smscore_fw_lkup[mode][type];
 				rc = smscore_load_firmware_from_file(coredev,
-							     fw_filename, NULL);
+						fw_filename, NULL);
 
 				if (rc < 0) {
 					sms_warn("error %d loading "
-						 "firmware: %s", rc,
-						 fw_filename);
+							"firmware: %s", rc,
+							fw_filename);
 					return rc;
 				}
 			}
-			sms_log("firmware download success: %s", fw_filename);
+			sms_info("firmware download success: %s", fw_filename);
 		} else
 			sms_info("mode %d supported by running "
-				 "firmware", mode);
+					"firmware", mode);
 
 		buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
-				 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+				SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
 		if (buffer) {
 			struct SmsMsgData_ST *msg =
-				(struct SmsMsgData_ST *)
+					(struct SmsMsgData_ST *)
 					SMS_ALIGN_ADDRESS(buffer);
 
 			SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
-				     sizeof(struct SmsMsgData_ST));
+					sizeof(struct SmsMsgData_ST));
 			msg->msgData[0] = mode;
 
-			rc = smscore_sendrequest_and_wait(
-				coredev, msg, msg->xMsgHeader.msgLength,
-				&coredev->init_device_done);
+			rc = smscore_sendrequest_and_wait(coredev, msg,
+					msg->xMsgHeader. msgLength,
+					&coredev->init_device_done);
 
 			kfree(buffer);
 		} else {
 			sms_err("Could not allocate buffer for "
-				"init device message.");
+					"init device message.");
 			rc = -ENOMEM;
 		}
 	} else {
@@ -851,7 +849,7 @@ int smscore_set_device_mode(struct smsco
 
 		if (coredev->detectmode_handler)
 			coredev->detectmode_handler(coredev->context,
-						    &coredev->mode);
+					&coredev->mode);
 
 		if (coredev->mode != mode && coredev->setmode_handler)
 			rc = coredev->setmode_handler(coredev->context, mode);
@@ -862,8 +860,76 @@ int smscore_set_device_mode(struct smsco
 		coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
 	}
 
-	if (rc != 0)
+	if (rc < 0)
 		sms_err("return error code %d.", rc);
+	return rc;
+}
+
+/**
+ * calls device handler to get fw file name
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param filename pointer to user buffer to fill the file name
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode,
+		char *filename) {
+	int rc = 0;
+	enum sms_device_type_st type;
+	char tmpname[200];
+
+	type = smscore_registry_gettype(coredev->devpath);
+
+#ifdef REQUEST_FIRMWARE_SUPPORTED
+	/* driver not need file system services */
+	tmpname[0] = '\0';
+#else
+	sprintf(tmpname, "%s/%s", DEFAULT_FW_FILE_PATH,
+			smscore_fw_lkup[mode][type]);
+#endif
+	if (copy_to_user(filename, tmpname, strlen(tmpname) + 1)) {
+		sms_err("Failed copy file path to user buffer\n");
+		return -EFAULT;
+	}
+	return rc;
+}
+
+/**
+ * calls device handler to keep fw buff for later use
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param ufwbuf  pointer to user fw buffer
+ * @param size    size in bytes of buffer
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf,
+		int size) {
+	int rc = 0;
+
+	/* free old buffer */
+	if (coredev->fw_buf != NULL) {
+		kfree(coredev->fw_buf);
+		coredev->fw_buf = NULL;
+	}
+
+	coredev->fw_buf = kmalloc(ALIGN(size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL
+			| GFP_DMA);
+	if (!coredev->fw_buf) {
+		sms_err("Failed allocate FW buffer memory\n");
+		return -EFAULT;
+	}
+
+	if (copy_from_user(coredev->fw_buf, ufwbuf, size)) {
+		sms_err("Failed copy FW from user buffer\n");
+		kfree(coredev->fw_buf);
+		return -EFAULT;
+	}
+	coredev->fw_buf_size = size;
+
 	return rc;
 }
 
@@ -890,28 +956,26 @@ int smscore_get_device_mode(struct smsco
  * @param id client id (SMS_DONT_CARE for all id)
  *
  */
-static struct
-smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
-				      int data_type, int id)
-{
+static struct smscore_client_t *smscore_find_client(
+		struct smscore_device_t *coredev, int data_type, int id) {
 	struct smscore_client_t *client = NULL;
 	struct list_head *next, *first;
 	unsigned long flags;
 	struct list_head *firstid, *nextid;
 
-
 	spin_lock_irqsave(&coredev->clientslock, flags);
 	first = &coredev->clients;
-	for (next = first->next;
-	     (next != first) && !client;
-	     next = next->next) {
-		firstid = &((struct smscore_client_t *)next)->idlist;
-		for (nextid = firstid->next;
-		     nextid != firstid;
-		     nextid = nextid->next) {
-			if ((((struct smscore_idlist_t *)nextid)->id == id) &&
-			    (((struct smscore_idlist_t *)nextid)->data_type == data_type ||
-			    (((struct smscore_idlist_t *)nextid)->data_type == 0))) {
+	for (next = first->next; (next != first) && !client;
+			next = next->next) {
+		firstid = &((struct smscore_client_t *) next)->idlist;
+		for (nextid = firstid->next; nextid != firstid;
+				nextid = nextid->next) {
+			if ((((struct smscore_idlist_t *) nextid)->id == id)
+					&& (((struct smscore_idlist_t *)
+						 nextid)->data_type
+						== data_type
+						|| (((struct smscore_idlist_t *)
+						nextid)->data_type == 0))) {
 				client = (struct smscore_client_t *) next;
 				break;
 			}
@@ -931,15 +995,13 @@ smscore_client_t *smscore_find_client(st
  *
  */
 void smscore_onresponse(struct smscore_device_t *coredev,
-			struct smscore_buffer_t *cb)
-{
-	struct SmsMsgHdr_ST *phdr =
-		(struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset);
-	struct smscore_client_t *client =
-		smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
+		struct smscore_buffer_t *cb) {
+	struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
+			+ cb->offset);
+	struct smscore_client_t *client = smscore_find_client(coredev,
+			phdr->msgType, phdr->msgDstId);
 	int rc = -EBUSY;
 
-#if 1
 	static unsigned long last_sample_time; /* = 0; */
 	static int data_total; /* = 0; */
 	unsigned long time_now = jiffies_to_msecs(jiffies);
@@ -949,37 +1011,37 @@ void smscore_onresponse(struct smscore_d
 
 	if (time_now - last_sample_time > 10000) {
 		sms_debug("\ndata rate %d bytes/secs",
-			  (int)((data_total * 1000) /
-				(time_now - last_sample_time)));
+				(int)((data_total * 1000) /
+						(time_now - last_sample_time)));
 
 		last_sample_time = time_now;
 		data_total = 0;
 	}
 
 	data_total += cb->size;
-#endif
 	/* If no client registered for type & id,
 	 * check for control client where type is not registered */
-#if 0
-	if (!client)
-		client = smscore_find_client(coredev, 0, phdr->msgDstId);
-#endif
+	sms_debug("phdr->msgType = %d t size = %d", phdr->msgType, data_total);
+
 	if (client)
 		rc = client->onresponse_handler(client->context, cb);
 
 	if (rc < 0) {
+		sms_debug("rc < 0");
+
 		switch (phdr->msgType) {
-		case MSG_SMS_GET_VERSION_EX_RES:
-		{
+		case MSG_SMS_GET_VERSION_EX_RES: {
 			struct SmsVersionRes_ST *ver =
-				(struct SmsVersionRes_ST *) phdr;
+					(struct SmsVersionRes_ST *) phdr;
 			sms_debug("MSG_SMS_GET_VERSION_EX_RES "
-				  "id %d prots 0x%x ver %d.%d",
-				  ver->FirmwareId, ver->SupportedProtocols,
-				  ver->RomVersionMajor, ver->RomVersionMinor);
+					"id %d prots 0x%x ver %d.%d",
+					ver->FirmwareId,
+					ver->SupportedProtocols,
+					ver->RomVersionMajor,
+					ver->RomVersionMinor);
 
 			coredev->mode = ver->FirmwareId == 255 ?
-				DEVICE_MODE_NONE : ver->FirmwareId;
+					DEVICE_MODE_NONE : ver->FirmwareId;
 			coredev->modes_supported = ver->SupportedProtocols;
 
 			complete(&coredev->version_ex_done);
@@ -1006,11 +1068,28 @@ void smscore_onresponse(struct smscore_d
 		case MSG_SMS_SLEEP_RESUME_COMP_IND:
 			complete(&coredev->resume_done);
 			break;
+		case MSG_SMS_GPIO_CONFIG_EX_RES:
+			sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
+			complete(&coredev->gpio_configuration_done);
+			break;
+		case MSG_SMS_GPIO_SET_LEVEL_RES:
+			sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
+			complete(&coredev->gpio_set_level_done);
+			break;
+		case MSG_SMS_GPIO_GET_LEVEL_RES:
+		{
+			u32 *msgdata = (u32 *) phdr;
+			coredev->gpio_get_res = msgdata[1];
+			sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
+					coredev->gpio_get_res);
+			complete(&coredev->gpio_get_level_done);
+			break;
+		}
 		default:
 #if 0
 			sms_info("no client (%p) or error (%d), "
-				 "type:%d dstid:%d", client, rc,
-				 phdr->msgType, phdr->msgDstId);
+					"type:%d dstid:%d", client, rc,
+					phdr->msgType, phdr->msgDstId);
 #endif
 			break;
 		}
@@ -1052,15 +1131,12 @@ struct smscore_buffer_t *smscore_getbuff
  *
  */
 void smscore_putbuffer(struct smscore_device_t *coredev,
-		       struct smscore_buffer_t *cb)
-{
+		struct smscore_buffer_t *cb) {
 	list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
 }
 
 static int smscore_validate_client(struct smscore_device_t *coredev,
-				   struct smscore_client_t *client,
-				   int data_type, int id)
-{
+		struct smscore_client_t *client, int data_type, int id) {
 	struct smscore_idlist_t *listentry;
 	struct smscore_client_t *registered_client;
 
@@ -1103,9 +1179,8 @@ static int smscore_validate_client(struc
  * @return 0 on success, <0 on error.
  */
 int smscore_register_client(struct smscore_device_t *coredev,
-			    struct smsclient_params_t *params,
-			    struct smscore_client_t **client)
-{
+		struct smsclient_params_t *params,
+				struct smscore_client_t **client) {
 	struct smscore_client_t *newclient;
 	/* check that no other channel with same parameters exists */
 	if (smscore_find_client(coredev, params->data_type,
@@ -1128,10 +1203,10 @@ int smscore_register_client(struct smsco
 	list_add_locked(&newclient->entry, &coredev->clients,
 			&coredev->clientslock);
 	smscore_validate_client(coredev, newclient, params->data_type,
-				params->initial_id);
+			params->initial_id);
 	*client = newclient;
 	sms_debug("%p %d %d", params->context, params->data_type,
-		  params->initial_id);
+			params->initial_id);
 
 	return 0;
 }
@@ -1150,10 +1225,9 @@ void smscore_unregister_client(struct sm
 
 	spin_lock_irqsave(&coredev->clientslock, flags);
 
-
 	while (!list_empty(&client->idlist)) {
 		struct smscore_idlist_t *identry =
-			(struct smscore_idlist_t *) client->idlist.next;
+				(struct smscore_idlist_t *) client->idlist.next;
 		list_del(&identry->entry);
 		kfree(identry);
 	}
@@ -1177,9 +1251,8 @@ void smscore_unregister_client(struct sm
  *
  * @return 0 on success, <0 on error.
  */
-int smsclient_sendrequest(struct smscore_client_t *client,
-			  void *buffer, size_t size)
-{
+int smsclient_sendrequest(struct smscore_client_t *client, void *buffer,
+		size_t size) {
 	struct smscore_device_t *coredev;
 	struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
 	int rc;
@@ -1198,14 +1271,14 @@ int smsclient_sendrequest(struct smscore
 	}
 
 	rc = smscore_validate_client(client->coredev, client, 0,
-				     phdr->msgSrcId);
+			phdr->msgSrcId);
 	if (rc < 0)
 		return rc;
 
 	return coredev->sendrequest_handler(coredev->context, buffer, size);
 }
 
-#if 0
+#ifdef SMS_HOSTLIB_SUBSYS
 /**
  * return the size of large (common) buffer
  *
@@ -1226,104 +1299,262 @@ int smscore_get_common_buffer_size(struc
  *
  * @return 0 on success, <0 on error.
  */
-static int smscore_map_common_buffer(struct smscore_device_t *coredev,
-				     struct vm_area_struct *vma)
+int smscore_map_common_buffer(struct smscore_device_t *coredev,
+		struct vm_area_struct *vma)
 {
 	unsigned long end = vma->vm_end,
-		      start = vma->vm_start,
-		      size = PAGE_ALIGN(coredev->common_buffer_size);
+	start = vma->vm_start,
+	size = PAGE_ALIGN(coredev->common_buffer_size);
 
 	if (!(vma->vm_flags & (VM_READ | VM_SHARED)) ||
-	     (vma->vm_flags & VM_WRITE)) {
+			(vma->vm_flags & VM_WRITE)) {
 		sms_err("invalid vm flags");
 		return -EINVAL;
 	}
 
 	if ((end - start) != size) {
 		sms_err("invalid size %d expected %d",
-			 (int)(end - start), (int) size);
+				(int)(end - start), (int)size);
 		return -EINVAL;
 	}
 
 	if (remap_pfn_range(vma, start,
-			    coredev->common_buffer_phys >> PAGE_SHIFT,
-			    size, pgprot_noncached(vma->vm_page_prot))) {
+			coredev->common_buffer_phys >> PAGE_SHIFT,
+			size, pgprot_noncached(vma->vm_page_prot))) {
 		sms_err("remap_page_range failed");
 		return -EAGAIN;
 	}
 
 	return 0;
 }
-#endif
+#endif /* SMS_HOSTLIB_SUBSYS */
 
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
-			   struct smscore_gpio_config *pinconfig)
-{
-	struct {
-		struct SmsMsgHdr_ST hdr;
-		u32 data[6];
-	} msg;
+static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
+		u32 *pGroupNum, u32 *pGroupCfg) {
 
-	if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-		msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-		msg.hdr.msgDstId = HIF_TASK;
-		msg.hdr.msgFlags = 0;
-		msg.hdr.msgType  = MSG_SMS_GPIO_CONFIG_EX_REQ;
-		msg.hdr.msgLength = sizeof(msg);
+	*pGroupCfg = 1;
 
-		msg.data[0] = pin;
-		msg.data[1] = pinconfig->pullupdown;
+	if (PinNum >= 0 && PinNum <= 1)	{
+		*pTranslatedPinNum = 0;
+		*pGroupNum = 9;
+		*pGroupCfg = 2;
+	} else if (PinNum >= 2 && PinNum <= 6) {
+		*pTranslatedPinNum = 2;
+		*pGroupNum = 0;
+		*pGroupCfg = 2;
+	} else if (PinNum >= 7 && PinNum <= 11) {
+		*pTranslatedPinNum = 7;
+		*pGroupNum = 1;
+	} else if (PinNum >= 12 && PinNum <= 15) {
+		*pTranslatedPinNum = 12;
+		*pGroupNum = 2;
+		*pGroupCfg = 3;
+	} else if (PinNum == 16) {
+		*pTranslatedPinNum = 16;
+		*pGroupNum = 23;
+	} else if (PinNum >= 17 && PinNum <= 24) {
+		*pTranslatedPinNum = 17;
+		*pGroupNum = 3;
+	} else if (PinNum == 25) {
+		*pTranslatedPinNum = 25;
+		*pGroupNum = 6;
+	} else if (PinNum >= 26 && PinNum <= 28) {
+		*pTranslatedPinNum = 26;
+		*pGroupNum = 4;
+	} else if (PinNum == 29) {
+		*pTranslatedPinNum = 29;
+		*pGroupNum = 5;
+		*pGroupCfg = 2;
+	} else if (PinNum == 30) {
+		*pTranslatedPinNum = 30;
+		*pGroupNum = 8;
+	} else if (PinNum == 31) {
+		*pTranslatedPinNum = 31;
+		*pGroupNum = 17;
+	} else
+		return -1;
 
-		/* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
-		msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
+	*pGroupCfg <<= 24;
 
-		switch (pinconfig->outputdriving) {
-		case SMS_GPIO_OUTPUTDRIVING_16mA:
-			msg.data[3] = 7; /* Nova - 16mA */
-			break;
-		case SMS_GPIO_OUTPUTDRIVING_12mA:
-			msg.data[3] = 5; /* Nova - 11mA */
-			break;
-		case SMS_GPIO_OUTPUTDRIVING_8mA:
-			msg.data[3] = 3; /* Nova - 7mA */
-			break;
-		case SMS_GPIO_OUTPUTDRIVING_4mA:
-		default:
-			msg.data[3] = 2; /* Nova - 4mA */
-			break;
-		}
+	return 0;
+}
 
-		msg.data[4] = pinconfig->direction;
-		msg.data[5] = 0;
-	} else /* TODO: SMS_DEVICE_FAMILY1 */
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
+		struct smscore_gpio_config *pGpioConfig) {
+
+	u32 totalLen;
+	u32 TranslatedPinNum;
+	u32 GroupNum;
+	u32 ElectricChar;
+	u32 groupCfg;
+	void *buffer;
+	int rc;
+
+	struct SetGpioMsg {
+		struct SmsMsgHdr_ST xMsgHeader;
+		u32 msgData[6];
+	} *pMsg;
+
+
+	if (PinNum > MAX_GPIO_PIN_NUMBER)
 		return -EINVAL;
 
-	return coredev->sendrequest_handler(coredev->context,
-					    &msg, sizeof(msg));
+	if (pGpioConfig == NULL)
+		return -EINVAL;
+
+	totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
+
+	buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+			GFP_KERNEL | GFP_DMA);
+	if (!buffer)
+		return -ENOMEM;
+
+	pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+	pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+	pMsg->xMsgHeader.msgDstId = HIF_TASK;
+	pMsg->xMsgHeader.msgFlags = 0;
+	pMsg->xMsgHeader.msgLength = (u16) totalLen;
+	pMsg->msgData[0] = PinNum;
+
+	if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
+		pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
+		if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
+				&groupCfg) != 0)
+			return -EINVAL;
+
+		pMsg->msgData[1] = TranslatedPinNum;
+		pMsg->msgData[2] = GroupNum;
+		ElectricChar = (pGpioConfig->PullUpDown)
+				| (pGpioConfig->InputCharacteristics << 2)
+				| (pGpioConfig->OutputSlewRate << 3)
+				| (pGpioConfig->OutputDriving << 4);
+		pMsg->msgData[3] = ElectricChar;
+		pMsg->msgData[4] = pGpioConfig->Direction;
+		pMsg->msgData[5] = groupCfg;
+	} else {
+		pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
+		pMsg->msgData[1] = pGpioConfig->PullUpDown;
+		pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
+		pMsg->msgData[3] = pGpioConfig->OutputDriving;
+		pMsg->msgData[4] = pGpioConfig->Direction;
+		pMsg->msgData[5] = 0;
+	}
+
+	rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+			&coredev->gpio_configuration_done);
+
+	if (rc != 0)
+		if (rc == -ETIME)
+			sms_err("smscore_gpio_configure timeout");
+		else
+			sms_err("smscore_gpio_configure error");
+
+	kfree(buffer);
+
+	return rc;
 }
 
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
-{
-	struct {
-		struct SmsMsgHdr_ST hdr;
-		u32 data[3];
-	} msg;
+int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
+		u8 NewLevel) {
 
-	if (pin > MAX_GPIO_PIN_NUMBER)
+	u32 totalLen;
+	int rc;
+	void *buffer;
+
+	struct SetGpioMsg {
+		struct SmsMsgHdr_ST xMsgHeader;
+		u32 msgData[3]; /* keep it 3 ! */
+	} *pMsg;
+
+	if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
+			(PinNum > MAX_GPIO_PIN_NUMBER))
 		return -EINVAL;
 
-	msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-	msg.hdr.msgDstId = HIF_TASK;
-	msg.hdr.msgFlags = 0;
-	msg.hdr.msgType  = MSG_SMS_GPIO_SET_LEVEL_REQ;
-	msg.hdr.msgLength = sizeof(msg);
+	totalLen = sizeof(struct SmsMsgHdr_ST) +
+			(3 * sizeof(u32)); /* keep it 3 ! */
 
-	msg.data[0] = pin;
-	msg.data[1] = level ? 1 : 0;
-	msg.data[2] = 0;
+	buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+			GFP_KERNEL | GFP_DMA);
+	if (!buffer)
+		return -ENOMEM;
 
-	return coredev->sendrequest_handler(coredev->context,
-					    &msg, sizeof(msg));
+	pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+	pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+	pMsg->xMsgHeader.msgDstId = HIF_TASK;
+	pMsg->xMsgHeader.msgFlags = 0;
+	pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
+	pMsg->xMsgHeader.msgLength = (u16) totalLen;
+	pMsg->msgData[0] = PinNum;
+	pMsg->msgData[1] = NewLevel;
+
+	/* Sent message to SMS */
+	rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+			&coredev->gpio_set_level_done);
+
+	if (rc != 0)
+		if (rc == -ETIME)
+			sms_err("smscore_gpio_set_level timeout");
+		else
+			sms_err("smscore_gpio_set_level error");
+
+	kfree(buffer);
+
+	return rc;
+}
+
+int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+		u8 *level) {
+
+	u32 totalLen;
+	int rc;
+	void *buffer;
+
+	struct SetGpioMsg {
+		struct SmsMsgHdr_ST xMsgHeader;
+		u32 msgData[2];
+	} *pMsg;
+
+
+	if (PinNum > MAX_GPIO_PIN_NUMBER)
+		return -EINVAL;
+
+	totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
+
+	buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+			GFP_KERNEL | GFP_DMA);
+	if (!buffer)
+		return -ENOMEM;
+
+	pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+	pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+	pMsg->xMsgHeader.msgDstId = HIF_TASK;
+	pMsg->xMsgHeader.msgFlags = 0;
+	pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
+	pMsg->xMsgHeader.msgLength = (u16) totalLen;
+	pMsg->msgData[0] = PinNum;
+	pMsg->msgData[1] = 0;
+
+	/* Sent message to SMS */
+	rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+			&coredev->gpio_get_level_done);
+
+	if (rc != 0)
+		if (rc == -ETIME)
+			sms_err("smscore_gpio_get_level timeout");
+		else
+			sms_err("smscore_gpio_get_level error");
+
+	kfree(buffer);
+
+	/* Its a race between other gpio_get_level() and the copy of the single
+	 * global 'coredev->gpio_get_res' to  the function's variable 'level'
+	 */
+	*level = coredev->gpio_get_res;
+
+	return rc;
 }
 
 static int __init smscore_module_init(void)
@@ -1337,25 +1568,125 @@ static int __init smscore_module_init(vo
 	INIT_LIST_HEAD(&g_smscore_registry);
 	kmutex_init(&g_smscore_registrylock);
 
+	/* Register sub system adapter objects */
+
+#ifdef SMS_NET_SUBSYS
+	/* NET Register */
+	rc = smsnet_register();
+	if (rc) {
+		sms_err("Error registering Siano's network client.\n");
+		goto smsnet_error;
+	}
+#endif
+
+#ifdef SMS_HOSTLIB_SUBSYS
+	/* Char interface Register */
+	rc = smschar_register();
+	if (rc) {
+		sms_err("Error registering Siano's char device client.\n");
+		goto smschar_error;
+	}
+#endif
+
+#ifdef SMS_DVB3_SUBSYS
+	/* DVB v.3 Register */
+	rc = smsdvb_register();
+	if (rc) {
+		sms_err("Error registering DVB client.\n");
+		goto smsdvb_error;
+	}
+#endif
+
+	/* Register interfaces objects */
+
+#ifdef SMS_USB_DRV
 	/* USB Register */
 	rc = smsusb_register();
+	if (rc) {
+		sms_err("Error registering USB bus driver.\n");
+		goto sms_bus_drv_error;
+	}
+#endif
 
-	/* DVB Register */
-	rc = smsdvb_register();
+#ifdef SMS_SDIO_DRV
+	/* SDIO Register */
+	rc = smssdio_register();
+	if (rc) {
+		sms_err("Error registering SDIO bus driver.\n");
+		goto sms_bus_drv_error;
+	}
+#endif
 
-	sms_debug("rc %d", rc);
+#ifdef SMS_SPI_PXA310_DRV
+	/* Intel PXA310 SPI Register */
+	rc = smsspi_register();
+	if (rc) {
+		sms_err("Error registering Intel PXA310 SPI bus driver.\n");
+		goto sms_bus_drv_error;
+	}
+#endif
+
+	return rc;
+
+sms_bus_drv_error:
+#ifdef SMS_DVB3_SUBSYS
+	smsdvb_unregister();
+smsdvb_error:
+#endif
+
+#ifdef SMS_HOSTLIB_SUBSYS
+	smschar_unregister();
+smschar_error:
+#endif
+
+#ifdef SMS_NET_SUBSYS
+	smsnet_unregister();
+smsnet_error:
+#endif
+
+	sms_err("rc %d", rc);
+	printk(KERN_INFO "%s, rc %d\n", __func__, rc);
 
 	return rc;
 }
 
 static void __exit smscore_module_exit(void)
 {
+#ifdef SMS_NET_SUBSYS
+	/* Net Unregister */
+	smsnet_unregister();
+#endif
+
+#ifdef SMS_HOSTLIB_SUBSYS
+	/* Char interface Unregister */
+	smschar_unregister();
+#endif
+
+#ifdef SMS_DVB3_SUBSYS
+	/* DVB v.3 unregister */
+	smsdvb_unregister();
+#endif
+
+	/* Unegister interfaces objects */
+#ifdef SMS_USB_DRV
+	/* USB unregister */
+	smsusb_unregister();
+#endif
+
+#ifdef SMS_SDIO_DRV
+	/* SDIO unegister */
+	smssdio_unregister();
+#endif
+#ifdef SMS_SPI_PXA310_DRV
+	/* Intel PXA310 SPI unegister */
+	smsspi_unregister();
+#endif
 
 	kmutex_lock(&g_smscore_deviceslock);
 	while (!list_empty(&g_smscore_notifyees)) {
 		struct smscore_device_notifyee_t *notifyee =
-			(struct smscore_device_notifyee_t *)
-				g_smscore_notifyees.next;
+		(struct smscore_device_notifyee_t *)
+		g_smscore_notifyees.next;
 
 		list_del(&notifyee->entry);
 		kfree(notifyee);
@@ -1365,19 +1696,13 @@ static void __exit smscore_module_exit(v
 	kmutex_lock(&g_smscore_registrylock);
 	while (!list_empty(&g_smscore_registry)) {
 		struct smscore_registry_entry_t *entry =
-			(struct smscore_registry_entry_t *)
-				g_smscore_registry.next;
+		(struct smscore_registry_entry_t *)
+		g_smscore_registry.next;
 
 		list_del(&entry->entry);
 		kfree(entry);
 	}
 	kmutex_unlock(&g_smscore_registrylock);
-
-	/* DVB UnRegister */
-	smsdvb_unregister();
-
-	/* Unregister USB */
-	smsusb_unregister();
 
 	sms_debug("");
 }
@@ -1385,6 +1710,6 @@ module_init(smscore_module_init);
 module_init(smscore_module_init);
 module_exit(smscore_module_exit);
 
-MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
-MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
+MODULE_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
 MODULE_LICENSE("GPL");
diff -r 0d667d493399 -r 1432098ff390 linux/drivers/media/dvb/siano/smscoreapi.h
--- a/linux/drivers/media/dvb/siano/smscoreapi.h	Tue Jan 13 13:59:28 2009 +0200
+++ b/linux/drivers/media/dvb/siano/smscoreapi.h	Tue Jan 13 14:08:17 2009 +0200
@@ -1,26 +1,26 @@
-/*
- *  Driver for the Siano SMS1xxx USB dongle
- *
- *  author: Anatoly Greenblat
- *
- *  Copyright (c), 2005-2008 Siano Mobile Silicon, 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;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+/****************************************************************
 
-#ifndef __smscoreapi_h__
-#define __smscoreapi_h__
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2008, Uri Shkolnik
+
+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, either version 2 of the License, or
+(at your option) any later version.
+
+ 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.  If not, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_CORE_API_H__
+#define __SMS_CORE_API_H__
 
 #include <linux/version.h>
 #include <linux/device.h>
@@ -29,14 +29,15 @@
 #include <linux/scatterlist.h>
 #include <linux/types.h>
 #include <asm/page.h>
+#include <linux/mutex.h>
+#include "compat.h"
 
-#include "compat.h"
+#ifdef SMS_DVB3_SUBSYS
 #include "dmxdev.h"
 #include "dvbdev.h"
 #include "dvb_demux.h"
 #include "dvb_frontend.h"
-
-#include <linux/mutex.h>
+#endif
 
 #define kmutex_init(_p_) mutex_init(_p_)
 #define kmutex_lock(_p_) mutex_lock(_p_)
@@ -54,7 +55,7 @@
 
 #define SMS_DEVICE_FAMILY2					1
 #define SMS_ROM_NO_RESPONSE					2
-#define SMS_DEVICE_NOT_READY				0x8000000
+#define SMS_DEVICE_NOT_READY					0x8000000
 
 enum sms_device_type_st {
 	SMS_STELLAR = 0,
@@ -68,80 +69,80 @@ struct smscore_client_t;
 struct smscore_client_t;
 struct smscore_buffer_t;
 
-typedef int (*hotplug_t)(struct smscore_device_t *coredev,
-			 struct device *device, int arrival);
+typedef int (*hotplug_t) (struct smscore_device_t *coredev,
+			  struct device *device, int arrival);
 
-typedef int (*setmode_t)(void *context, int mode);
-typedef void (*detectmode_t)(void *context, int *mode);
-typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
-typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
-typedef int (*preload_t)(void *context);
-typedef int (*postload_t)(void *context);
+typedef int (*setmode_t) (void *context, int mode);
+typedef void (*detectmode_t) (void *context, int *mode);
+typedef int (*sendrequest_t) (void *context, void *buffer, size_t size);
+typedef int (*loadfirmware_t) (void *context, void *buffer, size_t size);
+typedef int (*preload_t) (void *context);
+typedef int (*postload_t) (void *context);
 
-typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
-typedef void (*onremove_t)(void *context);
+typedef int (*onresponse_t) (void *context, struct smscore_buffer_t *cb);
+typedef void (*onremove_t) (void *context);
 
 struct smscore_buffer_t {
 	/* public members, once passed to clients can be changed freely */
 	struct list_head entry;
-	int				size;
-	int				offset;
+	int size;
+	int offset;
 
 	/* private members, read-only for clients */
-	void			*p;
-	dma_addr_t		phys;
-	unsigned long	offset_in_common;
+	void *p;
+	dma_addr_t phys;
+	unsigned long offset_in_common;
 };
 
 struct smsdevice_params_t {
-	struct device	*device;
+	struct device *device;
 
-	int				buffer_size;
-	int				num_buffers;
+	int buffer_size;
+	int num_buffers;
 
-	char			devpath[32];
-	unsigned long	flags;
+	char devpath[32];
+	unsigned long flags;
 
-	setmode_t		setmode_handler;
-	detectmode_t	detectmode_handler;
-	sendrequest_t	sendrequest_handler;
-	preload_t		preload_handler;
-	postload_t		postload_handler;
+	setmode_t setmode_handler;
+	detectmode_t detectmode_handler;
+	sendrequest_t sendrequest_handler;
+	preload_t preload_handler;
+	postload_t postload_handler;
 
-	void			*context;
+	void *context;
 	enum sms_device_type_st device_type;
 };
 
 struct smsclient_params_t {
-	int				initial_id;
-	int				data_type;
-	onresponse_t	onresponse_handler;
-	onremove_t		onremove_handler;
+	int initial_id;
+	int data_type;
+	onresponse_t onresponse_handler;
+	onremove_t onremove_handler;
 
-	void			*context;
+	void *context;
 };
 
 /* GPIO definitions for antenna frequency domain control (SMS8021) */
-#define SMS_ANTENNA_GPIO_0					1
-#define SMS_ANTENNA_GPIO_1					0
+#define SMS_ANTENNA_GPIO_0				1
+#define SMS_ANTENNA_GPIO_1				0
 
-#define BW_8_MHZ							0
-#define BW_7_MHZ							1
-#define BW_6_MHZ							2
-#define BW_5_MHZ							3
-#define BW_ISDBT_1SEG						4
-#define BW_ISDBT_3SEG						5
+#define BW_8_MHZ					0
+#define BW_7_MHZ					1
+#define BW_6_MHZ					2
+#define BW_5_MHZ					3
+#define BW_ISDBT_1SEG					4
+#define BW_ISDBT_3SEG					5
 
 #define MSG_HDR_FLAG_SPLIT_MSG				4
 
-#define MAX_GPIO_PIN_NUMBER					31
+#define MAX_GPIO_PIN_NUMBER				31
 
-#define HIF_TASK							11
-#define SMS_HOST_LIB						150
+#define HIF_TASK					11
+#define SMS_HOST_LIB					150
 #define DVBT_BDA_CONTROL_MSG_ID				201
 
 #define SMS_MAX_PAYLOAD_SIZE				240
-#define SMS_TUNE_TIMEOUT					500
+#define SMS_TUNE_TIMEOUT				500
 
 #define MSG_SMS_GPIO_CONFIG_REQ				507
 #define MSG_SMS_GPIO_CONFIG_RES				508
@@ -149,39 +150,39 @@ struct smsclient_params_t {
 #define MSG_SMS_GPIO_SET_LEVEL_RES			510
 #define MSG_SMS_GPIO_GET_LEVEL_REQ			511
 #define MSG_SMS_GPIO_GET_LEVEL_RES			512
-#define MSG_SMS_RF_TUNE_REQ					561
-#define MSG_SMS_RF_TUNE_RES					562
+#define MSG_SMS_RF_TUNE_REQ				561
+#define MSG_SMS_RF_TUNE_RES				562
 #define MSG_SMS_INIT_DEVICE_REQ				578
 #define MSG_SMS_INIT_DEVICE_RES				579
 #define MSG_SMS_ADD_PID_FILTER_REQ			601
 #define MSG_SMS_ADD_PID_FILTER_RES			602
-#define MSG_SMS_REMOVE_PID_FILTER_REQ		603
-#define MSG_SMS_REMOVE_PID_FILTER_RES		604
-#define MSG_SMS_DAB_CHANNEL					607
-#define MSG_SMS_GET_PID_FILTER_LIST_REQ		608
-#define MSG_SMS_GET_PID_FILTER_LIST_RES		609
+#define MSG_SMS_REMOVE_PID_FILTER_REQ			603
+#define MSG_SMS_REMOVE_PID_FILTER_RES			604
+#define MSG_SMS_DAB_CHANNEL				607
+#define MSG_SMS_GET_PID_FILTER_LIST_REQ			608
+#define MSG_SMS_GET_PID_FILTER_LIST_RES			609
 #define MSG_SMS_GET_STATISTICS_REQ			615
 #define MSG_SMS_GET_STATISTICS_RES			616
-#define MSG_SMS_SET_ANTENNA_CONFIG_REQ		651
-#define MSG_SMS_SET_ANTENNA_CONFIG_RES		652
-#define MSG_SMS_GET_STATISTICS_EX_REQ		653
-#define MSG_SMS_GET_STATISTICS_EX_RES		654
-#define MSG_SMS_SLEEP_RESUME_COMP_IND		655
+#define MSG_SMS_SET_ANTENNA_CONFIG_REQ			651
+#define MSG_SMS_SET_ANTENNA_CONFIG_RES			652
+#define MSG_SMS_GET_STATISTICS_EX_REQ			653
+#define MSG_SMS_GET_STATISTICS_EX_RES			654
+#define MSG_SMS_SLEEP_RESUME_COMP_IND			655
 #define MSG_SMS_DATA_DOWNLOAD_REQ			660
 #define MSG_SMS_DATA_DOWNLOAD_RES			661
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ		664
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES		665
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ		666
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES		667
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ			664
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES			665
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ			666
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES			667
 #define MSG_SMS_GET_VERSION_EX_REQ			668
 #define MSG_SMS_GET_VERSION_EX_RES			669
-#define MSG_SMS_SET_CLOCK_OUTPUT_REQ		670
+#define MSG_SMS_SET_CLOCK_OUTPUT_REQ			670
 #define MSG_SMS_I2C_SET_FREQ_REQ			685
 #define MSG_SMS_GENERIC_I2C_REQ				687
 #define MSG_SMS_GENERIC_I2C_RES				688
 #define MSG_SMS_DVBT_BDA_DATA				693
-#define MSG_SW_RELOAD_REQ					697
-#define MSG_SMS_DATA_MSG					699
+#define MSG_SW_RELOAD_REQ				697
+#define MSG_SMS_DATA_MSG				699
 #define MSG_SW_RELOAD_START_REQ				702
 #define MSG_SW_RELOAD_START_RES				703
 #define MSG_SW_RELOAD_EXEC_REQ				704
@@ -199,6 +200,16 @@ struct smsclient_params_t {
 #define SMS_INIT_MSG(ptr, type, len) \
 	SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
 
+enum SMS_DVB3_EVENTS {
+	DVB3_EVENT_INIT = 0,
+	DVB3_EVENT_SLEEP,
+	DVB3_EVENT_HOTPLUG,
+	DVB3_EVENT_FE_LOCK,
+	DVB3_EVENT_FE_UNLOCK,
+	DVB3_EVENT_UNC_OK,
+	DVB3_EVENT_UNC_ERR
+};
+
 enum SMS_DEVICE_MODE {
 	DEVICE_MODE_NONE = -1,
 	DEVICE_MODE_DVBT = 0,
@@ -214,121 +225,125 @@ enum SMS_DEVICE_MODE {
 };
 
 struct SmsMsgHdr_ST {
-	u16	msgType;
-	u8	msgSrcId;
-	u8	msgDstId;
-	u16	msgLength; /* Length of entire message, including header */
-	u16	msgFlags;
+	u16 msgType;
+	u8 msgSrcId;
+	u8 msgDstId;
+	u16 msgLength;		/* Length of entire message, including header */
+	u16 msgFlags;
 };
 
 struct SmsMsgData_ST {
-	struct SmsMsgHdr_ST	xMsgHeader;
-	u32			msgData[1];
+	struct SmsMsgHdr_ST xMsgHeader;
+	u32 msgData[1];
 };
 
 struct SmsDataDownload_ST {
-	struct SmsMsgHdr_ST	xMsgHeader;
-	u32			MemAddr;
-	u8			Payload[SMS_MAX_PAYLOAD_SIZE];
+	struct SmsMsgHdr_ST xMsgHeader;
+	u32 MemAddr;
+	u8 Payload[SMS_MAX_PAYLOAD_SIZE];
 };
 
 struct SmsVersionRes_ST {
-	struct SmsMsgHdr_ST	xMsgHeader;
+	struct SmsMsgHdr_ST xMsgHeader;
 
-	u16		ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
-	u8		Step; /* 0 - Step A */
-	u8		MetalFix; /* 0 - Metal 0 */
+	u16 ChipModel;		/* e.g. 0x1102 for SMS-1102 "Nova" */
+	u8 Step;		/* 0 - Step A */
+	u8 MetalFix;		/* 0 - Metal 0 */
 
-	u8		FirmwareId; /* 0xFF ï¿½ ROM, otherwise the
-				     * value indicated by
-				     * SMSHOSTLIB_DEVICE_MODES_E */
-	u8		SupportedProtocols; /* Bitwise OR combination of
-					     * supported protocols */
+	u8 FirmwareId;		/* 0xFF ROM, otherwise the
+				 * value indicated by
+				 * SMSHOSTLIB_DEVICE_MODES_E */
+	u8 SupportedProtocols;	/* Bitwise OR combination of
+				 * supported protocols */
 
-	u8		VersionMajor;
-	u8		VersionMinor;
-	u8		VersionPatch;
-	u8		VersionFieldPatch;
+	u8 VersionMajor;
+	u8 VersionMinor;
+	u8 VersionPatch;
+	u8 VersionFieldPatch;
 
-	u8		RomVersionMajor;
-	u8		RomVersionMinor;
-	u8		RomVersionPatch;
-	u8		RomVersionFieldPatch;
+	u8 RomVersionMajor;
+	u8 RomVersionMinor;
+	u8 RomVersionPatch;
+	u8 RomVersionFieldPatch;
 
-	u8		TextLabel[34];
+	u8 TextLabel[34];
 };
 
 struct SmsFirmware_ST {
-	u32			CheckSum;
-	u32			Length;
-	u32			StartAddress;
-	u8			Payload[1];
+	u32 CheckSum;
+	u32 Length;
+	u32 StartAddress;
+	u8 Payload[1];
 };
 
 struct SMSHOSTLIB_STATISTICS_ST {
-	u32 Reserved; /* Reserved */
+	u32 Reserved;		/* Reserved */
 
 	/* Common parameters */
-	u32 IsRfLocked; /* 0 - not locked, 1 - locked */
-	u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
-	u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+	u32 IsRfLocked;		/* 0 - not locked, 1 - locked */
+	u32 IsDemodLocked;	/* 0 - not locked, 1 - locked */
+	u32 IsExternalLNAOn;	/* 0 - external LNA off, 1 - external LNA on */
 
 	/* Reception quality */
-	s32  SNR; /* dB */
-	u32 BER; /* Post Viterbi BER [1E-5] */
-	u32 FIB_CRC;	/* CRC errors percentage, valid only for DAB */
-	u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A,
-		     * valid only for DVB-T/H */
-	u32 MFER; /* DVB-H frame error rate in percentage,
-		   * 0xFFFFFFFF indicate N/A, valid only for DVB-H */
-	s32  RSSI; /* dBm */
-	s32  InBandPwr; /* In band power in dBM */
-	s32  CarrierOffset; /* Carrier Offset in bin/1024 */
+	s32 SNR;		/* dB */
+	u32 BER;		/* Post Viterbi BER [1E-5] */
+	u32 FIB_CRC;		/* CRC errors percentage, valid only for DAB */
+	u32 TS_PER;		/* Transport stream PER, 0xFFFFFFFF
+				 * indicate N/A, valid only for DVB-T/H */
+	u32 MFER;		/* DVB-H frame error rate in percentage,
+				 * 0xFFFFFFFF indicate N/A, valid
+				 * only for DVB-H */
+	s32 RSSI;		/* dBm */
+	s32 InBandPwr;		/* In band power in dBM */
+	s32 CarrierOffset;	/* Carrier Offset in bin/1024 */
 
 	/* Transmission parameters, valid only for DVB-T/H */
-	u32 Frequency; /* Frequency in Hz */
-	u32 Bandwidth; /* Bandwidth in MHz */
-	u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
-			       * for DVB-T/H FFT mode carriers in Kilos */
-	u32 ModemState; /* from SMS_DvbModemState_ET */
-	u32 GuardInterval; /* Guard Interval, 1 divided by value */
-	u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */
-	u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */
-	u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */
-	u32 Constellation; /* Constellation from SMS_Constellation_ET */
+	u32 Frequency;		/* Frequency in Hz */
+	u32 Bandwidth;		/* Bandwidth in MHz */
+	u32 TransmissionMode;	/* Transmission Mode, for DAB modes 1-4,
+				 * for DVB-T/H FFT mode carriers in Kilos */
+	u32 ModemState;		/* from SMS_DvbModemState_ET */
+	u32 GuardInterval;	/* Guard Interval, 1 divided by value */
+	u32 CodeRate;		/* Code Rate from SMS_DvbModemState_ET */
+	u32 LPCodeRate;		/* Low Priority Code Rate from
+				 * SMS_DvbModemState_ET */
+	u32 Hierarchy;		/* Hierarchy from SMS_Hierarchy_ET */
+	u32 Constellation;	/* Constellation from SMS_Constellation_ET */
 
 	/* Burst parameters, valid only for DVB-H */
-	u32 BurstSize; /* Current burst size in bytes */
-	u32 BurstDuration; /* Current burst duration in mSec */
-	u32 BurstCycleTime; /* Current burst cycle time in mSec */
-	u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec,
-				       * as calculated by demodulator */
-	u32 NumOfRows; /* Number of rows in MPE table */
-	u32 NumOfPaddCols; /* Number of padding columns in MPE table */
-	u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */
+	u32 BurstSize;		/* Current burst size in bytes */
+	u32 BurstDuration;	/* Current burst duration in mSec */
+	u32 BurstCycleTime;	/* Current burst cycle time in mSec */
+	u32 CalculatedBurstCycleTime;	/* Current burst cycle time in mSec,
+					 * as calculated by demodulator */
+	u32 NumOfRows;		/* Number of rows in MPE table */
+	u32 NumOfPaddCols;	/* Number of padding columns in MPE table */
+	u32 NumOfPunctCols;	/* Number of puncturing columns in MPE table */
 	/* Burst parameters */
-	u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
-	u32 TotalTSPackets; /* Total number of transport-stream packets */
-	u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
-				* errors after MPE RS decoding */
-	u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors
-				  * after MPE RS decoding */
+	u32 ErrorTSPackets;	/* Number of erroneous transport-stream
+				 * packets */
+	u32 TotalTSPackets;	/* Total number of transport-stream packets */
+	u32 NumOfValidMpeTlbs;	/* Number of MPE tables which do not include
+				 * errors after MPE RS decoding */
+	u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
+				 * after MPE RS decoding */
 	u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected
 				    * by MPE RS decoding */
 
 	/* Common params */
-	u32 BERErrorCount; /* Number of errornous SYNC bits. */
-	u32 BERBitCount; /* Total number of SYNC bits. */
+	u32 BERErrorCount;	/* Number of errornous SYNC bits. */
+	u32 BERBitCount;	/* Total number of SYNC bits. */
 
 	/* Interface information */
-	u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+	u32 SmsToHostTxErrors;	/* Total number of transmission errors. */
 
 	/* DAB/T-DMB */
-	u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
+	u32 PreBER;		/* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
 
 	/* DVB-H TPS parameters */
-	u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
-		     * if set to 0xFFFFFFFF cell_id not yet recovered */
+	u32 CellId;		/* TPS Cell ID in bits 15..0, bits 31..16 zero;
+				 * if set to 0xFFFFFFFF cell_id not
+				 * yet recovered */
 
 };
 
@@ -338,211 +353,74 @@ struct SmsMsgStatisticsInfo_ST {
 	struct SMSHOSTLIB_STATISTICS_ST Stat;
 
 	/* Split the calc of the SNR in DAB */
-	u32 Signal; /* dB */
-	u32 Noise; /* dB */
+	u32 Signal;		/* dB */
+	u32 Noise;		/* dB */
 
 };
-
-#if 0
-struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
-	/* Per-layer information */
-	u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
-		       * 255 means layer does not exist */
-	u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
-			    * 255 means layer does not exist */
-	u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
-	u32 BERErrorCount; /* Post Viterbi Error Bits Count */
-	u32 BERBitCount; /* Post Viterbi Total Bits Count */
-	u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
-	u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
-	u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
-	u32 TotalTSPackets; /* Total number of transport-stream packets */
-	u32 TILdepthI; /* Time interleaver depth I parameter,
-			* 255 means layer does not exist */
-	u32 NumberOfSegments; /* Number of segments in layer A,
-			       * 255 means layer does not exist */
-	u32 TMCCErrors; /* TMCC errors */
-};
-
-struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
-	u32 StatisticsType; /* Enumerator identifying the type of the
-				* structure.  Values are the same as
-				* SMSHOSTLIB_DEVICE_MODES_E
-				*
-				* This field MUST always be first in any
-				* statistics structure */
-
-	u32 FullSize; /* Total size of the structure returned by the modem.
-		       * If the size requested by the host is smaller than
-		       * FullSize, the struct will be truncated */
-
-	/* Common parameters */
-	u32 IsRfLocked; /* 0 - not locked, 1 - locked */
-	u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
-	u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
-
-	/* Reception quality */
-	s32  SNR; /* dB */
-	s32  RSSI; /* dBm */
-	s32  InBandPwr; /* In band power in dBM */
-	s32  CarrierOffset; /* Carrier Offset in Hz */
-
-	/* Transmission parameters */
-	u32 Frequency; /* Frequency in Hz */
-	u32 Bandwidth; /* Bandwidth in MHz */
-	u32 TransmissionMode; /* ISDB-T transmission mode */
-	u32 ModemState; /* 0 - Acquisition, 1 - Locked */
-	u32 GuardInterval; /* Guard Interval, 1 divided by value */
-	u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
-	u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
-	u32 NumOfLayers; /* Number of ISDB-T layers in the network */
-
-	/* Per-layer information */
-	/* Layers A, B and C */
-	struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST	LayerInfo[3];
-	/* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
-
-	/* Interface information */
-	u32 SmsToHostTxErrors; /* Total number of transmission errors. */
-
-};
-
-struct SMSHOSTLIB_STATISTICS_DVB_ST {
-	u32 StatisticsType; /* Enumerator identifying the type of the
-			     * structure.  Values are the same as
-			     * SMSHOSTLIB_DEVICE_MODES_E
-			     * This field MUST always first in any
-			     * statistics structure */
-
-	u32 FullSize; /* Total size of the structure returned by the modem.
-		       * If the size requested by the host is smaller than
-		       * FullSize, the struct will be truncated */
-	/* Common parameters */
-	u32 IsRfLocked; /* 0 - not locked, 1 - locked */
-	u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
-	u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
-
-	/* Reception quality */
-	s32  SNR; /* dB */
-	u32 BER; /* Post Viterbi BER [1E-5] */
-	u32 BERErrorCount; /* Number of errornous SYNC bits. */
-	u32 BERBitCount; /* Total number of SYNC bits. */
-	u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A */
-	u32 MFER; /* DVB-H frame error rate in percentage,
-		   * 0xFFFFFFFF indicate N/A, valid only for DVB-H */
-	s32  RSSI; /* dBm */
-	s32  InBandPwr; /* In band power in dBM */
-	s32  CarrierOffset; /* Carrier Offset in bin/1024 */
-
-	/* Transmission parameters */
-	u32 Frequency; /* Frequency in Hz */
-	u32 Bandwidth; /* Bandwidth in MHz */
-	u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
-	u32 TransmissionMode; /* FFT mode carriers in Kilos */
-	u32 GuardInterval; /* Guard Interval, 1 divided by value */
-	u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
-	u32 LPCodeRate; /* Low Priority Code Rate from
-			 * SMSHOSTLIB_CODE_RATE_ET */
-	u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
-	u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET */
-
-	/* Burst parameters, valid only for DVB-H */
-	u32 BurstSize; /* Current burst size in bytes */
-	u32 BurstDuration; /* Current burst duration in mSec */
-	u32 BurstCycleTime; /* Current burst cycle time in mSec */
-	u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec,
-				       * as calculated by demodulator */
-	u32 NumOfRows; /* Number of rows in MPE table */
-	u32 NumOfPaddCols; /* Number of padding columns in MPE table */
-	u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */
-
-	u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
-	u32 TotalTSPackets; /* Total number of transport-stream packets */
-
-	u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
-				* errors after MPE RS decoding */
-	u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include
-				  * errors after MPE RS decoding */
-	u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were
-				    * corrected by MPE RS decoding */
-
-	u32 NumMPEReceived; /* DVB-H, Num MPE section received */
-
-	/* DVB-H TPS parameters */
-	u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
-		     * if set to 0xFFFFFFFF cell_id not yet recovered */
-	u32 DvbhSrvIndHP; /* DVB-H service indication info,
-			   * bit 1 - Time Slicing indicator,
-			   * bit 0 - MPE-FEC indicator */
-	u32 DvbhSrvIndLP; /* DVB-H service indication info,
-			   * bit 1 - Time Slicing indicator,
-			   * bit 0 - MPE-FEC indicator */
-
-	/* Interface information */
-	u32 SmsToHostTxErrors; /* Total number of transmission errors. */
-
-};
-
-struct SMSHOSTLIB_I2C_REQ_ST {
-	u32	DeviceAddress; /* I2c device address */
-	u32	WriteCount; /* number of bytes to write */
-	u32	ReadCount; /* number of bytes to read */
-	u8	Data[1];
-};
-
-struct SMSHOSTLIB_I2C_RES_ST {
-	u32	Status; /* non-zero value in case of failure */
-	u32	ReadCount; /* number of bytes read */
-	u8	Data[1];
-};
-#endif
 
 struct smscore_gpio_config {
 #define SMS_GPIO_DIRECTION_INPUT  0
 #define SMS_GPIO_DIRECTION_OUTPUT 1
-	u8 direction;
+	u8 Direction;
 
 #define SMS_GPIO_PULLUPDOWN_NONE     0
 #define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
 #define SMS_GPIO_PULLUPDOWN_PULLUP   2
 #define SMS_GPIO_PULLUPDOWN_KEEPER   3
-	u8 pullupdown;
+	u8 PullUpDown;
 
 #define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL  0
 #define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
-	u8 inputcharacteristics;
+	u8 InputCharacteristics;
 
-#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
-#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
-	u8 outputslewrate;
+#define SMS_GPIO_OUTPUTSLEWRATE_SLOW		0 /* 10xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_FAST		1 /* 10xx */
 
-#define SMS_GPIO_OUTPUTDRIVING_4mA  0
-#define SMS_GPIO_OUTPUTDRIVING_8mA  1
-#define SMS_GPIO_OUTPUTDRIVING_12mA 2
-#define SMS_GPIO_OUTPUTDRIVING_16mA 3
-	u8 outputdriving;
+#define SMS_GPIO_OUTPUTSLEWRATE_0_45_V_NS	0 /* 11xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_0_9_V_NS	1 /* 11xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_1_7_V_NS	2 /* 11xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_3_3_V_NS	3 /* 11xx */
+	u8 OutputSlewRate;
+
+#define SMS_GPIO_OUTPUTDRIVING_S_4mA		0 /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_8mA		1 /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_12mA		2 /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_16mA		3 /* 10xx */
+
+#define SMS_GPIO_OUTPUTDRIVING_1_5mA		0 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_2_8mA		1 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_4mA			2 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_7mA			3 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_10mA			4 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_11mA			5 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_14mA			6 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_16mA			7 /* 11xx */
+	u8 OutputDriving;
 };
+
+#ifdef SMS_DVB3_SUBSYS
 
 struct smsdvb_client_t {
 	struct list_head entry;
 
-	struct smscore_device_t	*coredev;
-	struct smscore_client_t	*smsclient;
+	struct smscore_device_t *coredev;
+	struct smscore_client_t *smsclient;
 
-	struct dvb_adapter	adapter;
-	struct dvb_demux	demux;
-	struct dmxdev		dmxdev;
-	struct dvb_frontend	frontend;
+	struct dvb_adapter adapter;
+	struct dvb_demux demux;
+	struct dmxdev dmxdev;
+	struct dvb_frontend frontend;
 
 	fe_status_t		fe_status;
 	int			fe_ber, fe_snr, fe_unc, fe_signal_strength;
 
-	struct completion	tune_done, stat_done;
+	struct completion tune_done, stat_done;
 
 	/* todo: save freq/band instead whole struct */
 	struct dvb_frontend_parameters fe_params;
 
 };
+#endif /* SMS_DVB3_SUBSYS */
 
 extern void smscore_registry_setmode(char *devpath, int mode);
 extern int smscore_registry_getmode(char *devpath);
@@ -558,13 +436,17 @@ extern int smscore_load_firmware(struct 
 extern int smscore_load_firmware(struct smscore_device_t *coredev,
 				 char *filename,
 				 loadfirmware_t loadfirmware_handler);
-
 extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
 extern int smscore_get_device_mode(struct smscore_device_t *coredev);
 
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode,
+				   char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf,
+				int size);
+
 extern int smscore_register_client(struct smscore_device_t *coredev,
-				    struct smsclient_params_t *params,
-				    struct smscore_client_t **client);
+				   struct smsclient_params_t *params,
+				   struct smscore_client_t **client);
 extern void smscore_unregister_client(struct smscore_client_t *client);
 
 extern int smsclient_sendrequest(struct smscore_client_t *client,
@@ -572,33 +454,54 @@ extern void smscore_onresponse(struct sm
 extern void smscore_onresponse(struct smscore_device_t *coredev,
 			       struct smscore_buffer_t *cb);
 
-#if 0
 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
 extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
-				      struct vm_area_struct *vma);
-#endif
+				     struct vm_area_struct *vma);
 
-extern
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
+extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t
+						  *coredev);
 extern void smscore_putbuffer(struct smscore_device_t *coredev,
 			      struct smscore_buffer_t *cb);
 
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
-			   struct smscore_gpio_config *pinconfig);
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
+		struct smscore_gpio_config *pGpioConfig);
+int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
+		u8 NewLevel);
+int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+		u8 *level);
 
 void smscore_set_board_id(struct smscore_device_t *core, int id);
 int smscore_get_board_id(struct smscore_device_t *core);
 
-int smscore_led_state(struct smscore_device_t *core, int led);
+#ifdef SMS_HOSTLIB_SUBSYS
+extern int smschar_register(void);
+extern void smschar_unregister(void);
+#endif
 
-/* smsdvb.c */
-int smsdvb_register(void);
-void smsdvb_unregister(void);
+#ifdef SMS_NET_SUBSYS
+extern int smsnet_register(void);
+extern void smsnet_unregister(void);
+#endif
 
-/* smsusb.c */
-int smsusb_register(void);
-void smsusb_unregister(void);
+#ifdef SMS_DVB3_SUBSYS
+extern int smsdvb_register(void);
+extern void smsdvb_unregister(void);
+#endif
+
+#ifdef SMS_USB_DRV
+extern int smsusb_register(void);
+extern void smsusb_unregister(void);
+#endif
+
+#ifdef SMS_SDIO_DRV
+extern int smssdio_register(void);
+extern void smssdio_unregister(void);
+#endif
+
+#ifdef SMS_SPI_PXA310_DRV
+extern int smsspi_register(void);
+extern void smsspi_unregister(void);
+#endif
 
 /* ------------------------------------------------------------------------ */
 
@@ -623,5 +526,4 @@ extern int sms_debug;
 #define sms_debug(fmt, arg...) \
 	dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
 
-
-#endif /* __smscoreapi_h__ */
+#endif /* __SMS_CORE_API_H__ */
