V4L/DVB (8272): sms1xxx: move driver from media/mdtv/ to media/dvb/siano/
authorMichael Krufky <mkrufky@linuxtv.org>
Thu, 22 May 2008 21:29:20 +0000 (18:29 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sun, 20 Jul 2008 10:20:47 +0000 (07:20 -0300)
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
14 files changed:
drivers/media/dvb/Kconfig
drivers/media/dvb/Makefile
drivers/media/dvb/siano/Kconfig [new file with mode: 0644]
drivers/media/dvb/siano/Makefile [new file with mode: 0644]
drivers/media/dvb/siano/smscoreapi.c [new file with mode: 0644]
drivers/media/dvb/siano/smscoreapi.h [new file with mode: 0644]
drivers/media/dvb/siano/smsdvb.c [new file with mode: 0644]
drivers/media/dvb/siano/smsusb.c [new file with mode: 0644]
drivers/media/mdtv/Kconfig [deleted file]
drivers/media/mdtv/Makefile [deleted file]
drivers/media/mdtv/smscoreapi.c [deleted file]
drivers/media/mdtv/smscoreapi.h [deleted file]
drivers/media/mdtv/smsdvb.c [deleted file]
drivers/media/mdtv/smsusb.c [deleted file]

index 7b21b49f1945ad56430f6bf16ac99bdaed89f52b..8bc1445bd33bda02d7c4d1bc6e5413aa375b51a7 100644 (file)
@@ -21,6 +21,7 @@ source "drivers/media/dvb/dvb-usb/Kconfig"
 source "drivers/media/dvb/ttusb-budget/Kconfig"
 source "drivers/media/dvb/ttusb-dec/Kconfig"
 source "drivers/media/dvb/cinergyT2/Kconfig"
+source "drivers/media/dvb/siano/Kconfig"
 
 comment "Supported FlexCopII (B2C2) Adapters"
        depends on DVB_CORE && (PCI || USB) && I2C
index a7ad0841e6fc049a662965718373c7bd468ef97f..d6ba4d19520189b1606d7bedc595c26283e75518 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/
+obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
new file mode 100644 (file)
index 0000000..878d48c
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config DVB_SIANO_SMS1XXX
+       tristate "Siano SMS1xxx USB dongle support"
+       depends on DVB_CORE && USB
+       ---help---
+         Choose Y here if you have USB dongle with SMS1xxx chipset.
+
+         Further documentation on this driver can be found on the WWW at
+         <http://www.siano-ms.com/>.
+
+         To compile this driver as a module, choose M here: the
+         module will be called sms1xxx.
+
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
new file mode 100644 (file)
index 0000000..e549c4e
--- /dev/null
@@ -0,0 +1,8 @@
+sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o
+
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
+
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
new file mode 100644 (file)
index 0000000..d3ba1fc
--- /dev/null
@@ -0,0 +1,1158 @@
+/*
+ *  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 3 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include <linux/firmware.h>
+
+#include "smscoreapi.h"
+
+typedef struct _smscore_device_notifyee
+{
+       struct list_head entry;
+       hotplug_t hotplug;
+} smscore_device_notifyee_t;
+
+typedef struct _smscore_client
+{
+       struct list_head entry;
+       smscore_device_t *coredev;
+
+       void                    *context;
+
+       int                             data_type;
+
+       onresponse_t    onresponse_handler;
+       onremove_t              onremove_handler;
+} *psmscore_client_t;
+
+typedef struct _smscore_subclient
+{
+       struct list_head entry;
+       smscore_client_t *client;
+
+       int                             id;
+} smscore_subclient_t;
+
+typedef struct _smscore_device
+{
+       struct list_head entry;
+
+       struct list_head clients;
+       struct list_head subclients;
+       spinlock_t              clientslock;
+
+       struct list_head buffers;
+       spinlock_t              bufferslock;
+       int                             num_buffers;
+
+       void                    *common_buffer;
+       int                             common_buffer_size;
+       dma_addr_t              common_buffer_phys;
+
+       void                    *context;
+       struct device   *device;
+
+       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;
+
+       int                             mode, modes_supported;
+
+       struct completion version_ex_done, data_download_done, trigger_done;
+       struct completion init_device_done, reload_start_done, resume_done;
+} *psmscore_device_t;
+
+typedef struct _smscore_registry_entry
+{
+       struct list_head entry;
+       char                    devpath[32];
+       int                             mode;
+} smscore_registry_entry_t;
+
+struct list_head g_smscore_notifyees;
+struct list_head g_smscore_devices;
+kmutex_t g_smscore_deviceslock;
+
+struct list_head g_smscore_registry;
+kmutex_t g_smscore_registrylock;
+
+static int default_mode = 1;
+module_param(default_mode, int, 0644);
+MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
+
+int smscore_registry_getmode(char* devpath)
+{
+       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)
+       {
+               entry = (smscore_registry_entry_t *) next;
+
+               if (!strcmp(entry->devpath, devpath))
+               {
+                       kmutex_unlock(&g_smscore_registrylock);
+                       return entry->mode;
+               }
+       }
+
+       entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL);
+       if (entry)
+       {
+               entry->mode = default_mode;
+               strcpy(entry->devpath, devpath);
+
+               list_add(&entry->entry, &g_smscore_registry);
+       }
+
+       kmutex_unlock(&g_smscore_registrylock);
+
+       return default_mode;
+}
+
+void smscore_registry_setmode(char* devpath, int mode)
+{
+       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)
+       {
+               entry = (smscore_registry_entry_t *) next;
+
+               if (!strcmp(entry->devpath, devpath))
+               {
+                       entry->mode = mode;
+                       break;
+               }
+       }
+
+       kmutex_unlock(&g_smscore_registrylock);
+}
+
+
+void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(lock, flags);
+
+       list_add(new, head);
+
+       spin_unlock_irqrestore(lock, flags);
+}
+
+/**
+ * register a client callback that called when device plugged in/unplugged
+ * NOTE: if devices exist callback is called immediately for each device
+ *
+ * @param hotplug callback
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_hotplug(hotplug_t hotplug)
+{
+       smscore_device_notifyee_t *notifyee;
+       struct list_head *next, *first;
+       int rc = 0;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL);
+       if (notifyee)
+       {
+               // now notify callback about existing devices
+               first = &g_smscore_devices;
+               for (next = first->next; next != first && !rc; next = next->next)
+               {
+                       smscore_device_t *coredev = (smscore_device_t *) next;
+                       rc = hotplug(coredev, coredev->device, 1);
+               }
+
+               if (rc >= 0)
+               {
+                       notifyee->hotplug = hotplug;
+                       list_add(&notifyee->entry, &g_smscore_notifyees);
+               }
+               else
+                       kfree(notifyee);
+       }
+       else
+               rc = -ENOMEM;
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       return rc;
+}
+
+/**
+ * unregister a client callback that called when device plugged in/unplugged
+ *
+ * @param hotplug callback
+ *
+ */
+void smscore_unregister_hotplug(hotplug_t hotplug)
+{
+       struct list_head *next, *first;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       first = &g_smscore_notifyees;
+
+       for (next = first->next; next != first;)
+       {
+               smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next;
+               next = next->next;
+
+               if (notifyee->hotplug == hotplug)
+               {
+                       list_del(&notifyee->entry);
+                       kfree(notifyee);
+               }
+       }
+
+       kmutex_unlock(&g_smscore_deviceslock);
+}
+
+void smscore_notify_clients(smscore_device_t *coredev)
+{
+       smscore_client_t* client;
+
+       // the client must call smscore_unregister_client from remove handler
+       while (!list_empty(&coredev->clients))
+       {
+               client = (smscore_client_t *) coredev->clients.next;
+               client->onremove_handler(client->context);
+       }
+}
+
+int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival)
+{
+       struct list_head *next, *first;
+       int rc = 0;
+
+       // note: must be called under g_deviceslock
+
+       first = &g_smscore_notifyees;
+
+       for (next = first->next; next != first; next = next->next)
+       {
+               rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival);
+               if (rc < 0)
+                       break;
+       }
+
+       return rc;
+}
+
+smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys)
+{
+       smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL);
+       if (!cb)
+       {
+               printk(KERN_INFO "%s kmalloc(...) failed\n", __FUNCTION__);
+               return NULL;
+       }
+
+       cb->p = buffer;
+       cb->offset_in_common = buffer - (u8*) common_buffer;
+       cb->phys = common_buffer_phys + cb->offset_in_common;
+
+       return cb;
+}
+
+/**
+ * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies
+ * registered hotplugs about new device.
+ *
+ * @param params device pointer to struct with device specific parameters and handlers
+ * @param coredev pointer to a value that receives created coredev object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev)
+{
+       smscore_device_t* dev;
+       u8 *buffer;
+
+       dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL);
+       if (!dev)
+       {
+               printk(KERN_INFO "%s kzalloc(...) failed\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       // init list entry so it could be safe in smscore_unregister_device
+       INIT_LIST_HEAD(&dev->entry);
+
+       // init queues
+       INIT_LIST_HEAD(&dev->clients);
+       INIT_LIST_HEAD(&dev->subclients);
+       INIT_LIST_HEAD(&dev->buffers);
+
+       // init locks
+       spin_lock_init(&dev->clientslock);
+       spin_lock_init(&dev->bufferslock);
+
+       // init completion events
+       init_completion(&dev->version_ex_done);
+       init_completion(&dev->data_download_done);
+       init_completion(&dev->trigger_done);
+       init_completion(&dev->init_device_done);
+       init_completion(&dev->reload_start_done);
+       init_completion(&dev->resume_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);
+       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)
+       {
+               smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys);
+               if (!cb)
+               {
+                       smscore_unregister_device(dev);
+                       return -ENOMEM;
+               }
+
+               smscore_putbuffer(dev, cb);
+       }
+
+       printk(KERN_INFO "%s allocated %d buffers\n", __FUNCTION__, dev->num_buffers);
+
+       dev->mode = DEVICE_MODE_NONE;
+       dev->context = params->context;
+       dev->device = params->device;
+       dev->setmode_handler = params->setmode_handler;
+       dev->detectmode_handler = params->detectmode_handler;
+       dev->sendrequest_handler = params->sendrequest_handler;
+       dev->preload_handler = params->preload_handler;
+       dev->postload_handler = params->postload_handler;
+
+       dev->device_flags = params->flags;
+       strcpy(dev->devpath, params->devpath);
+
+       // add device to devices list
+       kmutex_lock(&g_smscore_deviceslock);
+       list_add(&dev->entry, &g_smscore_devices);
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       *coredev = dev;
+
+       printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev);
+
+       return 0;
+}
+
+/**
+ * sets initial device mode and notifies client hotplugs that device is ready
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_start_device(smscore_device_t *coredev)
+{
+       int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath));
+       if (rc < 0)
+               return rc;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       rc = smscore_notify_callbacks(coredev, coredev->device, 1);
+
+       printk(KERN_INFO "%s device %p started, rc %d\n", __FUNCTION__, coredev, rc);
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       return rc;
+}
+
+int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion)
+{
+       int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
+       if (rc < 0)
+               return rc;
+
+       return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME;
+}
+
+int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size)
+{
+       SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer;
+       SmsMsgHdr_ST *msg;
+       UINT32 mem_address = firmware->StartAddress;
+       u8* payload = firmware->Payload;
+       int rc = 0;
+
+       if (coredev->preload_handler)
+       {
+               rc = coredev->preload_handler(coredev->context);
+               if (rc < 0)
+                       return rc;
+       }
+
+       // PAGE_SIZE buffer shall be enough and dma aligned
+       msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
+       if (!msg)
+               return -ENOMEM;
+
+       if (coredev->mode != DEVICE_MODE_NONE)
+       {
+               SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST));
+               rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done);
+               mem_address = *(UINT32*) &payload[20];
+       }
+
+       while (size && rc >= 0)
+       {
+               SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg;
+               int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
+
+               SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + 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);
+               else
+                       rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done);
+
+               payload += payload_size;
+               size -= payload_size;
+               mem_address += payload_size;
+       }
+
+       if (rc >= 0)
+       {
+               if (coredev->mode == DEVICE_MODE_NONE)
+               {
+                       SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg;
+
+                       SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5);
+
+                       TriggerMsg->msgData[0] = firmware->StartAddress;        // 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, TriggerMsg->xMsgHeader.msgLength);
+                               msleep(100);
+                       }
+                       else
+                               rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done);
+               }
+               else
+               {
+                       SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST));
+
+                       rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength);
+               }
+       }
+
+       printk("%s %d \n", __func__, rc);
+
+       kfree(msg);
+
+       return (rc >= 0 && coredev->postload_handler) ?
+               coredev->postload_handler(coredev->context) :
+               rc;
+}
+
+/**
+ * loads specified firmware into a buffer and calls device loadfirmware_handler
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ * @param filename null-terminated string specifies firmware file name
+ * @param loadfirmware_handler device handler that loads firmware
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler)
+{
+       int rc = -ENOENT;
+
+       const struct firmware *fw;
+       u8* fw_buffer;
+
+       if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2))
+               return -EINVAL;
+
+       rc = request_firmware(&fw, filename, coredev->device);
+       if (rc < 0)
+       {
+               printk(KERN_INFO "%s failed to open \"%s\"\n", __FUNCTION__, filename);
+               return rc;
+       }
+
+       fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA);
+       if (fw_buffer)
+       {
+               memcpy(fw_buffer, fw->data, fw->size);
+
+               rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+                       smscore_load_firmware_family2(coredev, fw_buffer, fw->size) :
+                       loadfirmware_handler(coredev->context, fw_buffer, fw->size);
+
+               kfree(fw_buffer);
+       }
+       else
+       {
+               printk(KERN_INFO "%s failed to allocate firmware buffer\n", __FUNCTION__);
+               rc = -ENOMEM;
+       }
+
+       release_firmware(fw);
+
+       return rc;
+}
+
+/**
+ * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+void smscore_unregister_device(smscore_device_t *coredev)
+{
+       smscore_buffer_t *cb;
+       int num_buffers = 0;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       smscore_notify_clients(coredev);
+       smscore_notify_callbacks(coredev, NULL, 0);
+
+       // at this point all buffers should be back
+       // onresponse must no longer be called
+
+       while (1)
+       {
+               while ((cb = smscore_getbuffer(coredev)))
+               {
+                       kfree(cb);
+                       num_buffers ++;
+               }
+
+               if (num_buffers == coredev->num_buffers)
+                       break;
+
+               printk(KERN_INFO "%s waiting for %d buffer(s)\n", __FUNCTION__, coredev->num_buffers - num_buffers);
+               msleep(100);
+       }
+
+       printk(KERN_INFO "%s freed %d buffers\n", __FUNCTION__, num_buffers);
+
+       if (coredev->common_buffer)
+               dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys);
+
+       list_del(&coredev->entry);
+       kfree(coredev);
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, coredev);
+}
+
+int smscore_detect_mode(smscore_device_t *coredev)
+{
+       void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+       SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
+       int rc;
+
+       if (!buffer)
+               return -ENOMEM;
+
+       SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST));
+
+       rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done);
+       if (rc == -ETIME)
+       {
+               printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __FUNCTION__);
+
+               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);
+                       if (rc < 0)
+                       {
+                               printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __FUNCTION__, rc);
+                       }
+               }
+               else
+                       rc = -ETIME;
+       }
+
+       kfree(buffer);
+
+       return rc;
+}
+
+char *smscore_fw_lkup[] =
+{
+       "dvb_nova_12mhz.inp",
+       "dvb_nova_12mhz.inp",
+       "tdmb_nova.inp",
+       "none",
+       "dvb_nova_12mhz.inp",
+       "isdbt_nova_12mhz.inp",
+       "isdbt_nova_12mhz.inp",
+       "cmmb_nova_12mhz.inp",
+       "none",
+};
+
+/**
+ * calls device handler to change mode of operation
+ * NOTE: stellar/usb may disconnect when changing mode
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ * @param mode requested mode of operation
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_set_device_mode(smscore_device_t *coredev, int mode)
+{
+       void *buffer;
+       int rc = 0;
+
+       if (coredev->device_flags & SMS_DEVICE_FAMILY2)
+       {
+               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER)
+               {
+                       printk(KERN_INFO "%s invalid mode specified %d\n", __FUNCTION__, mode);
+                       return -EINVAL;
+               }
+
+               if (!(coredev->device_flags & SMS_DEVICE_NOT_READY))
+               {
+                       rc = smscore_detect_mode(coredev);
+                       if (rc < 0)
+                               return rc;
+               }
+
+               if (coredev->mode == mode)
+               {
+                       printk(KERN_INFO "%s device mode %d already set\n", __FUNCTION__, mode);
+                       return 0;
+               }
+
+               if (!(coredev->modes_supported & (1 << mode)))
+               {
+                       rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL);
+                       if (rc < 0)
+                               return rc;
+               }
+               else
+               {
+                       printk(KERN_INFO "%s mode %d supported by running firmware\n", __FUNCTION__, mode);
+               }
+
+               buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+               if (buffer)
+               {
+                       SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer);
+
+                       SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST));
+                       msg->msgData[0] = mode;
+
+                       rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done);
+
+                       kfree(buffer);
+               }
+               else
+                       rc = -ENOMEM;
+       }
+       else
+       {
+               if (coredev->detectmode_handler)
+                       coredev->detectmode_handler(coredev->context, &coredev->mode);
+
+               if (coredev->mode != mode && coredev->setmode_handler)
+                       rc = coredev->setmode_handler(coredev->context, mode);
+       }
+
+       smscore_registry_setmode(coredev->devpath, mode);
+
+       if (rc >= 0)
+       {
+               coredev->mode = mode;
+               coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
+       }
+
+       return rc;
+}
+
+/**
+ * calls device handler to get current mode of operation
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ *
+ * @return current mode
+ */
+int smscore_get_device_mode(smscore_device_t *coredev)
+{
+       return coredev->mode;
+}
+
+smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type)
+{
+       smscore_client_t *client = NULL;
+       struct list_head *next, *first;
+       unsigned long flags;
+
+       if (!data_type)
+               return NULL;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+
+       first = &coredev->clients;
+
+       for (next = first->next; next != first; next = next->next)
+       {
+               if (((smscore_client_t*) next)->data_type == data_type)
+               {
+                       client = (smscore_client_t*) next;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+
+       return client;
+}
+
+smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id)
+{
+       smscore_client_t *client = NULL;
+       struct list_head *next, *first;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+
+       first = &coredev->subclients;
+
+       for (next = first->next; next != first; next = next->next)
+       {
+               if (((smscore_subclient_t*) next)->id == id)
+               {
+                       client = ((smscore_subclient_t*) next)->client;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+
+       return client;
+}
+
+/**
+ * find client by response id/type, call clients onresponse handler
+ * return buffer to pool on error
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ * @param cb pointer to response buffer descriptor
+ *
+ */
+void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb)
+{
+       SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset);
+       smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType);
+       int rc = -EBUSY;
+
+       static unsigned long last_sample_time = 0;
+       static int data_total = 0;
+       unsigned long time_now = jiffies_to_msecs(jiffies);
+
+       if (!last_sample_time)
+               last_sample_time = time_now;
+
+       if (time_now - last_sample_time > 10000)
+       {
+               printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time)));
+
+               last_sample_time = time_now;
+               data_total = 0;
+       }
+
+       data_total += cb->size;
+
+       if (!client)
+               client = smscore_getclient_by_id(coredev, phdr->msgDstId);
+
+       if (client)
+               rc = client->onresponse_handler(client->context, cb);
+
+       if (rc < 0)
+       {
+               switch (phdr->msgType)
+               {
+                       case MSG_SMS_GET_VERSION_EX_RES:
+                       {
+                               SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr;
+                               printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __FUNCTION__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor);
+
+                               coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId;
+                               coredev->modes_supported = ver->SupportedProtocols;
+
+                               complete(&coredev->version_ex_done);
+                               break;
+                       }
+
+                       case MSG_SMS_INIT_DEVICE_RES:
+                               printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __FUNCTION__);
+                               complete(&coredev->init_device_done);
+                               break;
+
+                       case MSG_SW_RELOAD_START_RES:
+                               printk("%s: MSG_SW_RELOAD_START_RES\n", __FUNCTION__);
+                               complete(&coredev->reload_start_done);
+                               break;
+
+                       case MSG_SMS_DATA_DOWNLOAD_RES:
+                               complete(&coredev->data_download_done);
+                               break;
+
+                       case MSG_SW_RELOAD_EXEC_RES:
+                               printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __FUNCTION__);
+                               break;
+
+                       case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
+                               printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __FUNCTION__);
+                               complete(&coredev->trigger_done);
+                               break;
+
+                       case MSG_SMS_SLEEP_RESUME_COMP_IND:
+                               complete(&coredev->resume_done);
+                               break;
+
+                       default:
+                               printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __FUNCTION__, client, rc, phdr->msgType, phdr->msgDstId);
+               }
+
+               smscore_putbuffer(coredev, cb);
+       }
+}
+
+/**
+ * return pointer to next free buffer descriptor from core pool
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ *
+ * @return pointer to descriptor on success, NULL on error.
+ */
+smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev)
+{
+       smscore_buffer_t *cb = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->bufferslock, flags);
+
+       if (!list_empty(&coredev->buffers))
+       {
+               cb = (smscore_buffer_t *) coredev->buffers.next;
+               list_del(&cb->entry);
+       }
+
+       spin_unlock_irqrestore(&coredev->bufferslock, flags);
+
+       return cb;
+}
+
+/**
+ * return buffer descriptor to a pool
+ *
+ * @param coredev pointer to a coredev object returned by smscore_register_device
+ * @param cb pointer buffer descriptor
+ *
+ */
+void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb)
+{
+       list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
+}
+
+int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id)
+{
+       smscore_client_t *existing_client;
+       smscore_subclient_t *subclient;
+
+       if (!id)
+               return 0;
+
+       existing_client = smscore_getclient_by_id(coredev, id);
+       if (existing_client == client)
+               return 0;
+
+       if (existing_client)
+               return -EBUSY;
+
+       subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL);
+       if (!subclient)
+               return -ENOMEM;
+
+       subclient->client = client;
+       subclient->id = id;
+
+       list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock);
+
+       return 0;
+}
+
+/**
+ * creates smsclient object, check that id is taken by another client
+ *
+ * @param coredev pointer to a coredev object from clients hotplug
+ * @param initial_id all messages with this id would be sent to this client
+ * @param data_type all messages of this type would be sent to this client
+ * @param onresponse_handler client handler that is called to process incoming messages
+ * @param onremove_handler client handler that is called when device is removed
+ * @param context client-specific context
+ * @param client pointer to a value that receives created smsclient object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client)
+{
+       smscore_client_t* newclient;
+       int rc;
+
+       // check that no other channel with same data type exists
+       if (params->data_type && smscore_getclient_by_type(coredev, params->data_type))
+               return -EEXIST;
+
+       newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL);
+       if (!newclient)
+               return -ENOMEM;
+
+       // check that no other channel with same id exists
+       rc = smscore_validate_client(coredev, newclient, params->initial_id);
+       if (rc < 0)
+       {
+               kfree(newclient);
+               return rc;
+       }
+
+       newclient->coredev = coredev;
+       newclient->data_type = params->data_type;
+       newclient->onresponse_handler = params->onresponse_handler;
+       newclient->onremove_handler = params->onremove_handler;
+       newclient->context = params->context;
+
+       list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock);
+
+       *client = newclient;
+
+       printk(KERN_INFO "%s %p %d %d\n", __FUNCTION__, params->context, params->data_type, params->initial_id);
+
+       return 0;
+}
+
+/**
+ * frees smsclient object and all subclients associated with it
+ *
+ * @param client pointer to smsclient object returned by smscore_register_client
+ *
+ */
+void smscore_unregister_client(smscore_client_t *client)
+{
+       smscore_device_t *coredev = client->coredev;
+       struct list_head *next, *first;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+
+       first = &coredev->subclients;
+
+       for (next = first->next; next != first;)
+       {
+               smscore_subclient_t *subclient = (smscore_subclient_t *) next;
+               next = next->next;
+
+               if (subclient->client == client)
+               {
+                       list_del(&subclient->entry);
+                       kfree(subclient);
+               }
+       }
+
+       printk(KERN_INFO "%s %p %d\n", __FUNCTION__, client->context, client->data_type);
+
+       list_del(&client->entry);
+       kfree(client);
+
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+}
+
+/**
+ * verifies that source id is not taken by another client,
+ * calls device handler to send requests to the device
+ *
+ * @param client pointer to smsclient object returned by smscore_register_client
+ * @param buffer pointer to a request buffer
+ * @param size size (in bytes) of request buffer
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size)
+{
+       smscore_device_t* coredev = client->coredev;
+       SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer;
+
+       // check that no other channel with same id exists
+       int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId);
+       if (rc < 0)
+               return rc;
+
+       return coredev->sendrequest_handler(coredev->context, buffer, size);
+}
+
+/**
+ * return the size of large (common) buffer
+ *
+ * @param coredev pointer to a coredev object from clients hotplug
+ *
+ * @return size (in bytes) of the buffer
+ */
+int smscore_get_common_buffer_size(smscore_device_t *coredev)
+{
+       return coredev->common_buffer_size;
+}
+
+/**
+ * maps common buffer (if supported by platform)
+ *
+ * @param coredev pointer to a coredev object from clients hotplug
+ * @param vma pointer to vma struct from mmap handler
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_map_common_buffer(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);
+
+       if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE))
+       {
+               printk(KERN_INFO "%s invalid vm flags\n", __FUNCTION__);
+               return -EINVAL;
+       }
+
+       if ((end - start) != size)
+       {
+               printk(KERN_INFO "%s invalid size %d expected %d\n", __FUNCTION__, (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)))
+       {
+               printk(KERN_INFO "%s remap_page_range failed\n", __FUNCTION__);
+               return -EAGAIN;
+       }
+
+       return 0;
+}
+
+int smscore_module_init(void)
+{
+       int rc = 0;
+
+       INIT_LIST_HEAD(&g_smscore_notifyees);
+       INIT_LIST_HEAD(&g_smscore_devices);
+       kmutex_init(&g_smscore_deviceslock);
+
+       INIT_LIST_HEAD(&g_smscore_registry);
+       kmutex_init(&g_smscore_registrylock);
+
+       /* USB Register */
+       rc = smsusb_register();
+
+       /* DVB Register */
+       rc = smsdvb_register();
+
+       printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc);
+
+       return rc;
+}
+
+void smscore_module_exit(void)
+{
+
+       kmutex_lock(&g_smscore_deviceslock);
+       while (!list_empty(&g_smscore_notifyees))
+       {
+               smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next;
+
+               list_del(&notifyee->entry);
+               kfree(notifyee);
+       }
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       kmutex_lock(&g_smscore_registrylock);
+       while (!list_empty(&g_smscore_registry))
+       {
+               smscore_registry_entry_t *entry = (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();
+
+       printk(KERN_INFO "%s\n", __FUNCTION__);
+}
+
+module_init(smscore_module_init);
+module_exit(smscore_module_exit);
+
+MODULE_DESCRIPTION("smscore");
+MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
new file mode 100644 (file)
index 0000000..679487d
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+ *  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 3 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__
+
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <asm/page.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include <linux/mutex.h>
+
+typedef struct mutex kmutex_t;
+
+#define kmutex_init(_p_) mutex_init(_p_)
+#define kmutex_lock(_p_) mutex_lock(_p_)
+#define kmutex_trylock(_p_) mutex_trylock(_p_)
+#define kmutex_unlock(_p_) mutex_unlock(_p_)
+
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define SMS_ALLOC_ALIGNMENT                                    128
+#define SMS_DMA_ALIGNMENT                                      16
+#define SMS_ALIGN_ADDRESS(addr) ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
+
+#define SMS_DEVICE_FAMILY2                                     1
+#define SMS_ROM_NO_RESPONSE                                    2
+#define SMS_DEVICE_NOT_READY                           0x8000000
+
+typedef struct _smscore_device smscore_device_t;
+typedef struct _smscore_client smscore_client_t;
+typedef struct _smscore_buffer smscore_buffer_t;
+
+typedef int (*hotplug_t)(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 (*onresponse_t)(void *context, smscore_buffer_t *cb);
+typedef void (*onremove_t)(void *context);
+
+typedef struct _smscore_buffer
+{
+       // public members, once passed to clients can be changed freely
+       struct list_head entry;
+       int                             size;
+       int                             offset;
+
+       // private members, read-only for clients
+       void                    *p;
+       dma_addr_t              phys;
+       unsigned long   offset_in_common;
+} *psmscore_buffer_t;
+
+typedef struct _smsdevice_params
+{
+       struct device   *device;
+
+       int                             buffer_size;
+       int                             num_buffers;
+
+       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;
+
+       void                    *context;
+} smsdevice_params_t;
+
+typedef struct _smsclient_params
+{
+       int                             initial_id;
+       int                             data_type;
+       onresponse_t    onresponse_handler;
+       onremove_t              onremove_handler;
+
+       void                    *context;
+} smsclient_params_t;
+
+// GPIO definitions for antenna frequency domain control (SMS8021)
+#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 MSG_HDR_FLAG_SPLIT_MSG                         4
+
+#define MAX_GPIO_PIN_NUMBER                                    31
+
+#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 MSG_SMS_GPIO_CONFIG_REQ                                507
+#define MSG_SMS_GPIO_CONFIG_RES                                508
+#define MSG_SMS_GPIO_SET_LEVEL_REQ                     509
+#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_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_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_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_GET_VERSION_EX_REQ                     668
+#define MSG_SMS_GET_VERSION_EX_RES                     669
+#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_START_REQ                                702
+#define MSG_SW_RELOAD_START_RES                                703
+#define MSG_SW_RELOAD_EXEC_REQ                         704
+#define MSG_SW_RELOAD_EXEC_RES                         705
+#define MSG_SMS_SPI_INT_LINE_SET_REQ           710
+#define MSG_SMS_ISDBT_TUNE_REQ                         776
+#define MSG_SMS_ISDBT_TUNE_RES                         777
+
+#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
+       (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
+       (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
+} while (0)
+#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
+
+typedef enum
+{
+       DEVICE_MODE_NONE = -1,
+       DEVICE_MODE_DVBT = 0,
+       DEVICE_MODE_DVBH,
+       DEVICE_MODE_DAB_TDMB,
+       DEVICE_MODE_DAB_TDMB_DABIP,
+       DEVICE_MODE_DVBT_BDA,
+       DEVICE_MODE_ISDBT,
+       DEVICE_MODE_ISDBT_BDA,
+       DEVICE_MODE_CMMB,
+       DEVICE_MODE_RAW_TUNER,
+       DEVICE_MODE_MAX,
+} SMS_DEVICE_MODE;
+
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef int INT32;
+
+typedef struct SmsMsgHdr_S
+{
+       UINT16  msgType;
+       UINT8   msgSrcId;
+       UINT8   msgDstId;
+       UINT16  msgLength;      // Length is of the entire message, including header
+       UINT16  msgFlags;
+} SmsMsgHdr_ST;
+
+typedef struct SmsMsgData_S
+{
+       SmsMsgHdr_ST    xMsgHeader;
+       UINT32                  msgData[1];
+} SmsMsgData_ST;
+
+typedef struct SmsDataDownload_S
+{
+       SmsMsgHdr_ST    xMsgHeader;
+       UINT32                  MemAddr;
+       UINT8                   Payload[SMS_MAX_PAYLOAD_SIZE];
+} SmsDataDownload_ST;
+
+typedef struct SmsVersionRes_S
+{
+       SmsMsgHdr_ST    xMsgHeader;
+
+       UINT16                  ChipModel;                    // e.g. 0x1102 for SMS-1102 "Nova"
+       UINT8                   Step;                         // 0 - Step A
+       UINT8                   MetalFix;                     // 0 - Metal 0
+
+       UINT8                   FirmwareId;                   // 0xFF ï¿½ ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E
+       UINT8                   SupportedProtocols;           // Bitwise OR combination of supported protocols
+
+       UINT8                   VersionMajor;
+       UINT8                   VersionMinor;
+       UINT8                   VersionPatch;
+       UINT8                   VersionFieldPatch;
+
+       UINT8                   RomVersionMajor;
+       UINT8                   RomVersionMinor;
+       UINT8                   RomVersionPatch;
+       UINT8                   RomVersionFieldPatch;
+
+       UINT8                   TextLabel[34];
+} SmsVersionRes_ST;
+
+typedef struct SmsFirmware_S
+{
+       UINT32                  CheckSum;
+       UINT32                  Length;
+       UINT32                  StartAddress;
+       UINT8                   Payload[1];
+} SmsFirmware_ST;
+
+typedef struct SMSHOSTLIB_STATISTICS_S
+{
+       UINT32 Reserved;                                //!< Reserved
+
+       /// Common parameters
+       UINT32 IsRfLocked;                              //!< 0 - not locked, 1 - locked
+       UINT32 IsDemodLocked;                   //!< 0 - not locked, 1 - locked
+       UINT32 IsExternalLNAOn;                 //!< 0 - external LNA off, 1 - external LNA on
+
+       /// Reception quality
+       INT32  SNR;                                             //!< dB
+       UINT32 BER;                                             //!< Post Viterbi BER [1E-5]
+       UINT32 FIB_CRC;                                 //!< CRC errors percentage, valid only for DAB
+       UINT32 TS_PER;                                  //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H
+       UINT32 MFER;                                    //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H
+       INT32  RSSI;                                    //!< dBm
+       INT32  InBandPwr;                               //!< In band power in dBM
+       INT32  CarrierOffset;                   //!< Carrier Offset in bin/1024
+
+       /// Transmission parameters
+       UINT32 Frequency;                               //!< Frequency in Hz
+       UINT32 Bandwidth;                               //!< Bandwidth in MHz, valid only for DVB-T/H
+       UINT32 TransmissionMode;                //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos
+       UINT32 ModemState;                              //!< from SMS_DvbModemState_ET , valid only for DVB-T/H
+       UINT32 GuardInterval;                   //!< Guard Interval, 1 divided by value , valid only for DVB-T/H
+       UINT32 CodeRate;                                //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H
+       UINT32 LPCodeRate;                              //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H
+       UINT32 Hierarchy;                               //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H
+       UINT32 Constellation;                   //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H
+
+       /// Burst parameters, valid only for DVB-H
+       UINT32 BurstSize;                               //!< Current burst size in bytes, valid only for DVB-H
+       UINT32 BurstDuration;                   //!< Current burst duration in mSec, valid only for DVB-H
+       UINT32 BurstCycleTime;                  //!< Current burst cycle time in mSec, valid only for DVB-H
+       UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H
+       UINT32 NumOfRows;                               //!< Number of rows in MPE table, valid only for DVB-H
+       UINT32 NumOfPaddCols;                   //!< Number of padding columns in MPE table, valid only for DVB-H
+       UINT32 NumOfPunctCols;                  //!< Number of puncturing columns in MPE table, valid only for DVB-H
+       UINT32 ErrorTSPackets;                  //!< Number of erroneous transport-stream packets
+       UINT32 TotalTSPackets;                  //!< Total number of transport-stream packets
+       UINT32 NumOfValidMpeTlbs;               //!< Number of MPE tables which do not include errors after MPE RS decoding
+       UINT32 NumOfInvalidMpeTlbs;             //!< Number of MPE tables which include errors after MPE RS decoding
+       UINT32 NumOfCorrectedMpeTlbs;   //!< Number of MPE tables which were corrected by MPE RS decoding
+       /// Common params
+       UINT32 BERErrorCount;                   //!< Number of errornous SYNC bits.
+       UINT32 BERBitCount;                             //!< Total number of SYNC bits.
+
+       /// Interface information
+       UINT32 SmsToHostTxErrors;               //!< Total number of transmission errors.
+
+       /// DAB/T-DMB
+       UINT32 PreBER;                                  //!< DAB/T-DMB only: Pre Viterbi BER [1E-5]
+
+       /// DVB-H TPS parameters
+       UINT32 CellId;                                  //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered
+
+} SMSHOSTLIB_STATISTICS_ST;
+
+typedef struct
+{
+       UINT32 RequestResult;
+
+       SMSHOSTLIB_STATISTICS_ST Stat;
+
+       // Split the calc of the SNR in DAB
+       UINT32 Signal;                          //!< dB
+       UINT32 Noise;                           //!< dB
+
+} SmsMsgStatisticsInfo_ST;
+
+typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S
+{
+       // Per-layer information
+       UINT32 CodeRate;                        //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist
+       UINT32 Constellation;           //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist
+       UINT32 BER;                                     //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A
+       UINT32 BERErrorCount;           //!< Post Viterbi Error Bits Count
+       UINT32 BERBitCount;                     //!< Post Viterbi Total Bits Count
+       UINT32 PreBER;                          //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A
+       UINT32 TS_PER;                          //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A
+       UINT32 ErrorTSPackets;          //!< Number of erroneous transport-stream packets
+       UINT32 TotalTSPackets;          //!< Total number of transport-stream packets
+       UINT32 TILdepthI;                       //!< Time interleaver depth I parameter, 255 means layer does not exist
+       UINT32 NumberOfSegments;        //!< Number of segments in layer A, 255 means layer does not exist
+       UINT32 TMCCErrors;                      //!< TMCC errors
+} SMSHOSTLIB_ISDBT_LAYER_STAT_ST;
+
+typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S
+{
+       UINT32 StatisticsType;                  //!< Enumerator identifying the type of the structure.  Values are the same as SMSHOSTLIB_DEVICE_MODES_E
+                                                                       //!< This fiels MUST always first in any statistics structure
+
+       UINT32 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
+       UINT32 IsRfLocked;                              //!< 0 - not locked, 1 - locked
+       UINT32 IsDemodLocked;                   //!< 0 - not locked, 1 - locked
+       UINT32 IsExternalLNAOn;                 //!< 0 - external LNA off, 1 - external LNA on
+
+       // Reception quality
+       INT32  SNR;                                             //!< dB
+       INT32  RSSI;                                    //!< dBm
+       INT32  InBandPwr;                               //!< In band power in dBM
+       INT32  CarrierOffset;                   //!< Carrier Offset in Hz
+
+       // Transmission parameters
+       UINT32 Frequency;                               //!< Frequency in Hz
+       UINT32 Bandwidth;                               //!< Bandwidth in MHz
+       UINT32 TransmissionMode;                //!< ISDB-T transmission mode
+       UINT32 ModemState;                              //!< 0 - Acquisition, 1 - Locked
+       UINT32 GuardInterval;                   //!< Guard Interval, 1 divided by value
+       UINT32 SystemType;                              //!< ISDB-T system type (ISDB-T / ISDB-Tsb)
+       UINT32 PartialReception;                //!< TRUE - partial reception, FALSE otherwise
+       UINT32 NumOfLayers;                             //!< Number of ISDB-T layers in the network
+
+       // Per-layer information
+       // Layers A, B and C
+       SMSHOSTLIB_ISDBT_LAYER_STAT_ST  LayerInfo[3];   //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST
+
+       // Interface information
+       UINT32 SmsToHostTxErrors;               //!< Total number of transmission errors.
+
+} SMSHOSTLIB_STATISTICS_ISDBT_ST;
+
+typedef struct SMSHOSTLIB_STATISTICS_DVB_S
+{
+       UINT32 StatisticsType;                  //!< Enumerator identifying the type of the structure.  Values are the same as SMSHOSTLIB_DEVICE_MODES_E
+                                                               //!< This fiels MUST always first in any statistics structure
+
+       UINT32 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
+       UINT32 IsRfLocked;                              //!< 0 - not locked, 1 - locked
+       UINT32 IsDemodLocked;                   //!< 0 - not locked, 1 - locked
+       UINT32 IsExternalLNAOn;                 //!< 0 - external LNA off, 1 - external LNA on
+
+       // Reception quality
+       INT32  SNR;                                             //!< dB
+       UINT32 BER;                                             //!< Post Viterbi BER [1E-5]
+       UINT32 BERErrorCount;                   //!< Number of errornous SYNC bits.
+       UINT32 BERBitCount;                             //!< Total number of SYNC bits.
+       UINT32 TS_PER;                                  //!< Transport stream PER, 0xFFFFFFFF indicate N/A
+       UINT32 MFER;                                    //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H
+       INT32  RSSI;                                    //!< dBm
+       INT32  InBandPwr;                               //!< In band power in dBM
+       INT32  CarrierOffset;                   //!< Carrier Offset in bin/1024
+
+       // Transmission parameters
+       UINT32 Frequency;                               //!< Frequency in Hz
+       UINT32 Bandwidth;                               //!< Bandwidth in MHz
+       UINT32 ModemState;                              //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET
+       UINT32 TransmissionMode;                //!< FFT mode carriers in Kilos
+       UINT32 GuardInterval;                   //!< Guard Interval, 1 divided by value
+       UINT32 CodeRate;                                //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET
+       UINT32 LPCodeRate;                              //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET
+       UINT32 Hierarchy;                               //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET
+       UINT32 Constellation;                   //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET
+
+       // Burst parameters, valid only for DVB-H
+       UINT32 BurstSize;                               //!< Current burst size in bytes, valid only for DVB-H
+       UINT32 BurstDuration;                   //!< Current burst duration in mSec, valid only for DVB-H
+       UINT32 BurstCycleTime;                  //!< Current burst cycle time in mSec, valid only for DVB-H
+       UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H
+       UINT32 NumOfRows;                               //!< Number of rows in MPE table, valid only for DVB-H
+       UINT32 NumOfPaddCols;                   //!< Number of padding columns in MPE table, valid only for DVB-H
+       UINT32 NumOfPunctCols;                  //!< Number of puncturing columns in MPE table, valid only for DVB-H
+       UINT32 ErrorTSPackets;                  //!< Number of erroneous transport-stream packets
+       UINT32 TotalTSPackets;                  //!< Total number of transport-stream packets
+       UINT32 NumOfValidMpeTlbs;               //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H
+       UINT32 NumOfInvalidMpeTlbs;             //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H
+       UINT32 NumOfCorrectedMpeTlbs;   //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H
+       UINT32 NumMPEReceived;                  //!< DVB-H, Num MPE section received
+
+       // DVB-H TPS parameters
+       UINT32 CellId;                                  //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered
+       UINT32 DvbhSrvIndHP;                    //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator
+       UINT32 DvbhSrvIndLP;                    //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator
+
+       // Interface information
+       UINT32 SmsToHostTxErrors;               //!< Total number of transmission errors.
+
+} SMSHOSTLIB_STATISTICS_DVB_ST;
+
+typedef struct SMSHOSTLIB_GPIO_CONFIG_S
+{
+       UINT8   Direction;                              //!< GPIO direction: Input - 0, Output - 1
+       UINT8   PullUpDown;                             //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3
+       UINT8   InputCharacteristics;   //!< Input Characteristics: Normal - 0, Schmitt trigger - 1
+       UINT8   OutputSlewRate;                 //!< Output Slew Rate:  Fast slew rate - 0, Slow slew rate - 1
+       UINT8   OutputDriving;                  //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3
+} SMSHOSTLIB_GPIO_CONFIG_ST;
+
+typedef struct SMSHOSTLIB_I2C_REQ_S
+{
+       UINT32  DeviceAddress;                  // I2c device address
+       UINT32  WriteCount;                             // number of bytes to write
+       UINT32  ReadCount;                              // number of bytes to read
+       UINT8   Data[1];
+} SMSHOSTLIB_I2C_REQ_ST;
+
+typedef struct SMSHOSTLIB_I2C_RES_S
+{
+       UINT32  Status;                                 // non-zero value in case of failure
+       UINT32  ReadCount;                              // number of bytes read
+       UINT8   Data[1];
+} SMSHOSTLIB_I2C_RES_ST;
+
+typedef struct _smsdvb_client
+{
+       struct list_head entry;
+
+       smscore_device_t        *coredev;
+       smscore_client_t        *smsclient;
+
+       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_signal_strength;
+
+       struct completion       tune_done, stat_done;
+
+       // todo: save freq/band instead whole struct
+       struct dvb_frontend_parameters fe_params;
+
+} smsdvb_client_t;
+
+extern void smscore_registry_setmode(char *devpath, int mode);
+extern int smscore_registry_getmode(char *devpath);
+
+extern int smscore_register_hotplug(hotplug_t hotplug);
+extern void smscore_unregister_hotplug(hotplug_t hotplug);
+
+extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev);
+extern void smscore_unregister_device(smscore_device_t *coredev);
+
+extern int smscore_start_device(smscore_device_t *coredev);
+extern int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler);
+
+extern int smscore_set_device_mode(smscore_device_t *coredev, int mode);
+extern int smscore_get_device_mode(smscore_device_t *coredev);
+
+extern int smscore_register_client(smscore_device_t *coredev, smsclient_params_t* params, smscore_client_t **client);
+extern void smscore_unregister_client(smscore_client_t *client);
+
+extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size);
+extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb);
+
+extern int smscore_get_common_buffer_size(smscore_device_t *coredev);
+extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma);
+
+extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev);
+extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb);
+
+/* smsdvb.c */
+int smsdvb_register(void);
+void smsdvb_unregister(void);
+
+/* smsusb.c */
+int smsusb_register(void);
+void smsusb_unregister(void);
+
+#endif // __smscoreapi_h__
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
new file mode 100644 (file)
index 0000000..e1a14a8
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ *  Driver for the Siano SMS10xx 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 3 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "smscoreapi.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct list_head g_smsdvb_clients;
+kmutex_t g_smsdvb_clientslock;
+
+int smsdvb_onresponse(void *context, smscore_buffer_t *cb)
+{
+       smsdvb_client_t *client = (smsdvb_client_t *) context;
+       SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8*) cb->p) + cb->offset);
+
+       switch(phdr->msgType)
+       {
+               case MSG_SMS_DVBT_BDA_DATA:
+                       dvb_dmx_swfilter(&client->demux, (u8*)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST));
+                       break;
+
+               case MSG_SMS_RF_TUNE_RES:
+                       complete(&client->tune_done);
+                       break;
+
+               case MSG_SMS_GET_STATISTICS_RES:
+               {
+                       SmsMsgStatisticsInfo_ST* p = (SmsMsgStatisticsInfo_ST*)(phdr + 1);
+
+                       if (p->Stat.IsDemodLocked)
+                       {
+                               client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+                               client->fe_snr = p->Stat.SNR;
+                               client->fe_ber = p->Stat.BER;
+
+                               if (p->Stat.InBandPwr < -95)
+                                       client->fe_signal_strength = 0;
+                               else if (p->Stat.InBandPwr > -29)
+                                       client->fe_signal_strength = 100;
+                               else
+                                       client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2;
+                       }
+                       else
+                       {
+                               client->fe_status = 0;
+                               client->fe_snr =
+                               client->fe_ber =
+                               client->fe_signal_strength = 0;
+                       }
+
+                       complete(&client->stat_done);
+                       break;
+               }
+       }
+
+       smscore_putbuffer(client->coredev, cb);
+
+       return 0;
+}
+
+void smsdvb_unregister_client(smsdvb_client_t* client)
+{
+       // must be called under clientslock
+
+       list_del(&client->entry);
+
+       smscore_unregister_client(client->smsclient);
+       dvb_unregister_frontend(&client->frontend);
+       dvb_dmxdev_release(&client->dmxdev);
+       dvb_dmx_release(&client->demux);
+       dvb_unregister_adapter(&client->adapter);
+       kfree(client);
+}
+
+void smsdvb_onremove(void *context)
+{
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       smsdvb_unregister_client((smsdvb_client_t*) context);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+static int smsdvb_start_feed(struct dvb_demux_feed *feed)
+{
+       smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux);
+       SmsMsgData_ST PidMsg;
+
+       printk("%s add pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid);
+
+       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+       PidMsg.xMsgHeader.msgFlags = 0;
+       PidMsg.xMsgHeader.msgType  = MSG_SMS_ADD_PID_FILTER_REQ;
+       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+       PidMsg.msgData[0] = feed->pid;
+
+       return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
+{
+       smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux);
+       SmsMsgData_ST PidMsg;
+
+       printk("%s remove pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid);
+
+       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+       PidMsg.xMsgHeader.msgFlags = 0;
+       PidMsg.xMsgHeader.msgType  = MSG_SMS_REMOVE_PID_FILTER_REQ;
+       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+       PidMsg.msgData[0] = feed->pid;
+
+       return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, void* buffer, size_t size, struct completion *completion)
+{
+       int rc = smsclient_sendrequest(client->smsclient, buffer, size);
+       if (rc < 0)
+               return rc;
+
+       return wait_for_completion_timeout(completion, msecs_to_jiffies(2000)) ? 0 : -ETIME;
+}
+
+static int smsdvb_send_statistics_request(smsdvb_client_t *client)
+{
+       SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 };
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done);
+}
+
+static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
+       int rc = smsdvb_send_statistics_request(client);
+
+       if (!rc)
+               *stat = client->fe_status;
+
+       return rc;
+}
+
+static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
+       int rc = smsdvb_send_statistics_request(client);
+
+       if (!rc)
+               *ber = client->fe_ber;
+
+       return rc;
+}
+
+static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
+       int rc = smsdvb_send_statistics_request(client);
+
+       if (!rc)
+               *strength = client->fe_signal_strength;
+
+       return rc;
+}
+
+static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
+       int rc = smsdvb_send_statistics_request(client);
+
+       if (!rc)
+               *snr = client->fe_snr;
+
+       return rc;
+}
+
+static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
+{
+       printk("%s\n", __FUNCTION__);
+
+       tune->min_delay_ms = 400;
+       tune->step_size = 250000;
+       tune->max_drift = 0;
+       return 0;
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
+
+       struct
+       {
+               SmsMsgHdr_ST    Msg;
+               u32                             Data[3];
+       } Msg;
+
+       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
+       Msg.Msg.msgDstId  = HIF_TASK;
+       Msg.Msg.msgFlags  = 0;
+       Msg.Msg.msgType   = MSG_SMS_RF_TUNE_REQ;
+       Msg.Msg.msgLength = sizeof(Msg);
+       Msg.Data[0] = fep->frequency;
+       Msg.Data[2] = 12000000;
+
+       printk("%s freq %d band %d\n", __FUNCTION__, fep->frequency, fep->u.ofdm.bandwidth);
+
+       switch(fep->u.ofdm.bandwidth)
+       {
+               case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break;
+               case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break;
+               case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break;
+//             case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break;
+               case BANDWIDTH_AUTO: return -EOPNOTSUPP;
+               default: return -EINVAL;
+       }
+
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done);
+}
+
+static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
+
+       printk("%s\n", __FUNCTION__);
+
+       // todo:
+       memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters));
+       return 0;
+}
+
+static void smsdvb_release(struct dvb_frontend *fe)
+{
+       // do nothing
+}
+
+static struct dvb_frontend_ops smsdvb_fe_ops = {
+       .info = {
+               .name                           = "Siano Mobile Digital SMS10xx",
+               .type                           = FE_OFDM,
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
+               .frequency_stepsize     = 250000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                               FE_CAN_TRANSMISSION_MODE_AUTO |
+                               FE_CAN_GUARD_INTERVAL_AUTO |
+                               FE_CAN_RECOVER |
+                               FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = smsdvb_release,
+
+       .set_frontend = smsdvb_set_frontend,
+       .get_frontend = smsdvb_get_frontend,
+       .get_tune_settings = smsdvb_get_tune_settings,
+
+       .read_status = smsdvb_read_status,
+       .read_ber = smsdvb_read_ber,
+       .read_signal_strength = smsdvb_read_signal_strength,
+       .read_snr = smsdvb_read_snr,
+};
+
+int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival)
+{
+       smsclient_params_t params;
+       smsdvb_client_t* client;
+       int rc;
+
+       // device removal handled by onremove callback
+       if (!arrival)
+               return 0;
+
+       if (smscore_get_device_mode(coredev) != 4)
+       {
+               rc = smscore_set_device_mode(coredev, 4);
+               if (rc < 0)
+                       return rc;
+       }
+
+       client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL);
+       if (!client)
+       {
+               printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       // register dvb adapter
+       rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr);
+       if (rc < 0)
+       {
+               printk("%s dvb_register_adapter() failed %d\n", __func__, rc);
+               goto adapter_error;
+       }
+
+       // init dvb demux
+       client->demux.dmx.capabilities = DMX_TS_FILTERING;
+       client->demux.filternum = 32; // todo: nova ???
+       client->demux.feednum = 32;
+       client->demux.start_feed = smsdvb_start_feed;
+       client->demux.stop_feed = smsdvb_stop_feed;
+
+       rc = dvb_dmx_init(&client->demux);
+       if (rc < 0)
+       {
+               printk("%s dvb_dmx_init failed %d\n\n", __FUNCTION__, rc);
+               goto dvbdmx_error;
+       }
+
+       // init dmxdev
+       client->dmxdev.filternum = 32;
+       client->dmxdev.demux = &client->demux.dmx;
+       client->dmxdev.capabilities = 0;
+
+       rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
+       if (rc < 0)
+       {
+               printk("%s dvb_dmxdev_init failed %d\n", __FUNCTION__, rc);
+               goto dmxdev_error;
+       }
+
+       // init and register frontend
+       memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops));
+
+       rc = dvb_register_frontend(&client->adapter, &client->frontend);
+       if (rc < 0)
+       {
+               printk("%s frontend registration failed %d\n", __FUNCTION__, rc);
+               goto frontend_error;
+       }
+
+       params.initial_id = 0;
+       params.data_type = MSG_SMS_DVBT_BDA_DATA;
+       params.onresponse_handler = smsdvb_onresponse;
+       params.onremove_handler = smsdvb_onremove;
+       params.context = client;
+
+       rc = smscore_register_client(coredev, &params, &client->smsclient);
+       if (rc < 0)
+       {
+               printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc);
+               goto client_error;
+       }
+
+       client->coredev = coredev;
+
+       init_completion(&client->tune_done);
+       init_completion(&client->stat_done);
+
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       list_add(&client->entry, &g_smsdvb_clients);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+
+       printk(KERN_INFO "%s success\n", __FUNCTION__);
+
+       return 0;
+
+client_error:
+       dvb_unregister_frontend(&client->frontend);
+
+frontend_error:
+       dvb_dmxdev_release(&client->dmxdev);
+
+dmxdev_error:
+       dvb_dmx_release(&client->demux);
+
+dvbdmx_error:
+       dvb_unregister_adapter(&client->adapter);
+
+adapter_error:
+       kfree(client);
+       return rc;
+}
+
+int smsdvb_register(void)
+{
+       int rc;
+
+       INIT_LIST_HEAD(&g_smsdvb_clients);
+       kmutex_init(&g_smsdvb_clientslock);
+
+       rc = smscore_register_hotplug(smsdvb_hotplug);
+
+       printk(KERN_INFO "%s\n", __FUNCTION__);
+
+       return rc;
+}
+
+void smsdvb_unregister(void)
+{
+       smscore_unregister_hotplug(smsdvb_hotplug);
+
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       while (!list_empty(&g_smsdvb_clients))
+               smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+
+}
+
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
new file mode 100644 (file)
index 0000000..20aa878
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ *  Driver for the Siano SMS10xx 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 3 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+
+#include "smscoreapi.h"
+
+#define USB1_BUFFER_SIZE               0x1000
+#define USB2_BUFFER_SIZE               0x4000
+
+#define MAX_BUFFERS            50
+#define MAX_URBS               10
+
+typedef struct _smsusb_device smsusb_device_t;
+
+typedef struct _smsusb_urb
+{
+       smscore_buffer_t *cb;
+       smsusb_device_t *dev;
+
+       struct urb              urb;
+} smsusb_urb_t;
+
+typedef struct _smsusb_device
+{
+       struct usb_device* udev;
+       smscore_device_t *coredev;
+
+       smsusb_urb_t    surbs[MAX_URBS];
+
+       int                             response_alignment;
+       int                             buffer_size;
+} *psmsusb_device_t;
+
+int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb);
+
+void smsusb_onresponse(struct urb *urb)
+{
+       smsusb_urb_t *surb = (smsusb_urb_t *) urb->context;
+       smsusb_device_t *dev = surb->dev;
+
+       if (urb->status < 0)
+       {
+               printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length);
+               return;
+       }
+
+       if (urb->actual_length > 0)
+       {
+               SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p;
+
+               if (urb->actual_length >= phdr->msgLength)
+               {
+                       surb->cb->size = phdr->msgLength;
+
+                       if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG))
+                       {
+                               surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3);
+
+                               // sanity check
+                               if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length)
+                               {
+                                       printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length);
+                                       goto exit_and_resubmit;
+                               }
+
+                               // move buffer pointer and copy header to its new location
+                               memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST));
+                       }
+                       else
+                               surb->cb->offset = 0;
+
+                       smscore_onresponse(dev->coredev, surb->cb);
+                       surb->cb = NULL;
+               }
+               else
+               {
+                       printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length);
+               }
+       }
+
+exit_and_resubmit:
+       smsusb_submit_urb(dev, surb);
+}
+
+int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb)
+{
+       if (!surb->cb)
+       {
+               surb->cb = smscore_getbuffer(dev->coredev);
+               if (!surb->cb)
+               {
+                       printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__);
+                       return -ENOMEM;
+               }
+       }
+
+       usb_fill_bulk_urb(
+               &surb->urb,
+               dev->udev,
+               usb_rcvbulkpipe(dev->udev, 0x81),
+               surb->cb->p,
+               dev->buffer_size,
+               smsusb_onresponse,
+               surb
+       );
+       surb->urb.transfer_dma = surb->cb->phys;
+       surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       return usb_submit_urb(&surb->urb, GFP_ATOMIC);
+}
+
+void smsusb_stop_streaming(smsusb_device_t* dev)
+{
+       int i;
+
+       for (i = 0; i < MAX_URBS; i ++)
+       {
+               usb_kill_urb(&dev->surbs[i].urb);
+
+               if (dev->surbs[i].cb)
+               {
+                       smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
+                       dev->surbs[i].cb = NULL;
+               }
+       }
+}
+
+int smsusb_start_streaming(smsusb_device_t* dev)
+{
+       int i, rc;
+
+       for (i = 0; i < MAX_URBS; i ++)
+       {
+               rc = smsusb_submit_urb(dev, &dev->surbs[i]);
+               if (rc < 0)
+               {
+                       printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__);
+                       smsusb_stop_streaming(dev);
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+int smsusb_sendrequest(void *context, void *buffer, size_t size)
+{
+       smsusb_device_t* dev = (smsusb_device_t*) context;
+       int dummy;
+
+       return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000);
+}
+
+char *smsusb1_fw_lkup[] =
+{
+       "dvbt_stellar_usb.inp",
+       "dvbh_stellar_usb.inp",
+       "tdmb_stellar_usb.inp",
+       "none",
+       "dvbt_bda_stellar_usb.inp",
+};
+
+int smsusb1_load_firmware(struct usb_device *udev, int id)
+{
+       const struct firmware *fw;
+       u8* fw_buffer;
+       int rc, dummy;
+
+       if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA)
+       {
+               printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id);
+               return -EINVAL;
+       }
+
+       rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev);
+       if (rc < 0)
+       {
+               printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id);
+               return rc;
+       }
+
+       fw_buffer = kmalloc(fw->size, GFP_KERNEL);
+       if (fw_buffer)
+       {
+               memcpy(fw_buffer, fw->data, fw->size);
+
+               rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000);
+
+               printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc);
+
+               kfree(fw_buffer);
+       }
+       else
+       {
+               printk(KERN_INFO "failed to allocate firmware buffer\n");
+               rc = -ENOMEM;
+       }
+
+       release_firmware(fw);
+
+       return rc;
+}
+
+void smsusb1_detectmode(void *context, int *mode)
+{
+       char *product_string = ((smsusb_device_t *) context)->udev->product;
+
+       *mode = DEVICE_MODE_NONE;
+
+       if (!product_string)
+       {
+               product_string = "none";
+               printk("%s product string not found\n", __FUNCTION__);
+       }
+       else
+       {
+               if (strstr(product_string, "DVBH"))
+                       *mode = 1;
+               else if (strstr(product_string, "BDA"))
+                       *mode = 4;
+               else if (strstr(product_string, "DVBT"))
+                       *mode = 0;
+               else if (strstr(product_string, "TDMB"))
+                       *mode = 2;
+       }
+
+       printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string);
+}
+
+int smsusb1_setmode(void *context, int mode)
+{
+       SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 };
+
+       if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA)
+       {
+               printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode);
+               return -EINVAL;
+       }
+
+       return smsusb_sendrequest(context, &Msg, sizeof(Msg));
+}
+
+void smsusb_term_device(struct usb_interface *intf)
+{
+       smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf);
+
+       if (dev)
+       {
+               smsusb_stop_streaming(dev);
+
+               // unregister from smscore
+               if (dev->coredev)
+                       smscore_unregister_device(dev->coredev);
+
+               kfree(dev);
+
+               printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev);
+       }
+
+       usb_set_intfdata(intf, NULL);
+}
+
+int smsusb_init_device(struct usb_interface *intf)
+{
+       smsdevice_params_t params;
+       smsusb_device_t* dev;
+       int i, rc;
+
+       // create device object
+       dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL);
+       if (!dev)
+       {
+               printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       memset(&params, 0, sizeof(params));
+       usb_set_intfdata(intf, dev);
+       dev->udev = interface_to_usbdev(intf);
+
+       switch (dev->udev->descriptor.idProduct)
+       {
+               case 0x100:
+                       dev->buffer_size = USB1_BUFFER_SIZE;
+
+                       params.setmode_handler = smsusb1_setmode;
+                       params.detectmode_handler = smsusb1_detectmode;
+                       break;
+
+               default:
+                       dev->buffer_size = USB2_BUFFER_SIZE;
+                       dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST);
+
+                       params.flags |= SMS_DEVICE_FAMILY2;
+                       break;
+       }
+
+       params.device = &dev->udev->dev;
+       params.buffer_size = dev->buffer_size;
+       params.num_buffers = MAX_BUFFERS;
+       params.sendrequest_handler = smsusb_sendrequest;
+       params.context = dev;
+       snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath);
+
+       // register in smscore
+       rc = smscore_register_device(&params, &dev->coredev);
+       if (rc < 0)
+       {
+               printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc);
+               smsusb_term_device(intf);
+               return rc;
+       }
+
+       // initialize urbs
+       for (i = 0; i < MAX_URBS; i ++)
+       {
+               dev->surbs[i].dev = dev;
+               usb_init_urb(&dev->surbs[i].urb);
+       }
+
+       rc = smsusb_start_streaming(dev);
+       if (rc < 0)
+       {
+               printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__);
+               smsusb_term_device(intf);
+               return rc;
+       }
+
+       rc = smscore_start_device(dev->coredev);
+       if (rc < 0)
+       {
+               printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__);
+               smsusb_term_device(intf);
+               return rc;
+       }
+
+       printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev);
+
+       return rc;
+}
+
+int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       char devpath[32];
+       int i, rc;
+
+       if (intf->num_altsetting > 0)
+       {
+               rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
+               if (rc < 0)
+               {
+                       printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc);
+                       return rc;
+               }
+       }
+
+       printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber);
+       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++)
+               printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
+
+       if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0)
+       {
+               printk(KERN_INFO "rom interface 0 is not used\n");
+               return -ENODEV;
+       }
+
+       if (intf->cur_altsetting->desc.bInterfaceNumber == 1)
+       {
+               snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath);
+               return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath));
+       }
+
+       return smsusb_init_device(intf);
+}
+
+void smsusb_disconnect(struct usb_interface *intf)
+{
+       smsusb_term_device(intf);
+}
+
+static struct usb_device_id smsusb_id_table [] = {
+       { USB_DEVICE(0x187F, 0x0010) },
+       { USB_DEVICE(0x187F, 0x0100) },
+       { USB_DEVICE(0x187F, 0x0200) },
+       { }             /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, smsusb_id_table);
+
+static struct usb_driver smsusb_driver = {
+       .name                   = "smsusb",
+       .probe                  = smsusb_probe,
+       .disconnect     = smsusb_disconnect,
+       .id_table               = smsusb_id_table,
+};
+
+int smsusb_register(void)
+{
+       int rc = usb_register(&smsusb_driver);
+       if (rc)
+               printk(KERN_INFO "usb_register failed. Error number %d\n", rc);
+
+       printk(KERN_INFO "%s\n", __FUNCTION__);
+
+       return rc;
+}
+
+void smsusb_unregister(void)
+{
+       /* Regular USB Cleanup */
+       usb_deregister(&smsusb_driver);
+       printk(KERN_INFO "%s\n", __FUNCTION__);
+}
+
diff --git a/drivers/media/mdtv/Kconfig b/drivers/media/mdtv/Kconfig
deleted file mode 100644 (file)
index a7faca0..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Mobile Digital TV device configuration
-#
-
-config MDTV_SIANO_STELLAR_USB
-       tristate "Siano SMS10xx USB dongle support"
-       default m
-       ---help---
-         Choose Y here if you have USB dongle with SMS10xx chipset.
-
-         Further documentation on this driver can be found on the WWW at
-         <http://www.siano-ms.com/>.
-
-         To compile this driver as a module, choose M here: the
-         modules will be called smschar and smsnet.
-
diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile
deleted file mode 100644 (file)
index 16b9c48..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-smscore-objs := smscoreapi.o smsusb.o smsdvb.o
-
-obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smscore.o
-
-EXTRA_CFLAGS += -Idrivers/media/video
-EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
-EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
-
-EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
-
diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c
deleted file mode 100644 (file)
index b261fe2..0000000
+++ /dev/null
@@ -1,1178 +0,0 @@
-
-/*
- *  Driver for the Siano SMS10xx USB dongle
- *
- *  Copyright (c) 2008 <TODO: INSERT ALL COPYRIGHT OWNERS and MAINT. NAMES HERE>
- *
- *  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, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*!
-
-       \file           smscoreapi.c
-
-       \brief          Siano core API module
-                               This file contains implementation for the interface to sms core component
-
-    \par               Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
-
-    \par               This program is free software; you can redistribute it and/or modify
-                       it under the terms of the GNU General Public License version 3 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.
-
-       \author         Anatoly Greenblat
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#include <linux/firmware.h>
-
-#include "smscoreapi.h"
-
-typedef struct _smscore_device_notifyee
-{
-       struct list_head entry;
-       hotplug_t hotplug;
-} smscore_device_notifyee_t;
-
-typedef struct _smscore_client
-{
-       struct list_head entry;
-       smscore_device_t *coredev;
-
-       void                    *context;
-
-       int                             data_type;
-
-       onresponse_t    onresponse_handler;
-       onremove_t              onremove_handler;
-} *psmscore_client_t;
-
-typedef struct _smscore_subclient
-{
-       struct list_head entry;
-       smscore_client_t *client;
-
-       int                             id;
-} smscore_subclient_t;
-
-typedef struct _smscore_device
-{
-       struct list_head entry;
-
-       struct list_head clients;
-       struct list_head subclients;
-       spinlock_t              clientslock;
-
-       struct list_head buffers;
-       spinlock_t              bufferslock;
-       int                             num_buffers;
-
-       void                    *common_buffer;
-       int                             common_buffer_size;
-       dma_addr_t              common_buffer_phys;
-
-       void                    *context;
-       struct device   *device;
-
-       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;
-
-       int                             mode, modes_supported;
-
-       struct completion version_ex_done, data_download_done, trigger_done;
-       struct completion init_device_done, reload_start_done, resume_done;
-} *psmscore_device_t;
-
-typedef struct _smscore_registry_entry
-{
-       struct list_head entry;
-       char                    devpath[32];
-       int                             mode;
-} smscore_registry_entry_t;
-
-struct list_head g_smscore_notifyees;
-struct list_head g_smscore_devices;
-kmutex_t g_smscore_deviceslock;
-
-struct list_head g_smscore_registry;
-kmutex_t g_smscore_registrylock;
-
-static int default_mode = 1;
-module_param(default_mode, int, 0644);
-MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
-
-int smscore_registry_getmode(char* devpath)
-{
-       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)
-       {
-               entry = (smscore_registry_entry_t *) next;
-
-               if (!strcmp(entry->devpath, devpath))
-               {
-                       kmutex_unlock(&g_smscore_registrylock);
-                       return entry->mode;
-               }
-       }
-
-       entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL);
-       if (entry)
-       {
-               entry->mode = default_mode;
-               strcpy(entry->devpath, devpath);
-
-               list_add(&entry->entry, &g_smscore_registry);
-       }
-
-       kmutex_unlock(&g_smscore_registrylock);
-
-       return default_mode;
-}
-
-void smscore_registry_setmode(char* devpath, int mode)
-{
-       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)
-       {
-               entry = (smscore_registry_entry_t *) next;
-
-               if (!strcmp(entry->devpath, devpath))
-               {
-                       entry->mode = mode;
-                       break;
-               }
-       }
-
-       kmutex_unlock(&g_smscore_registrylock);
-}
-
-
-void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(lock, flags);
-
-       list_add(new, head);
-
-       spin_unlock_irqrestore(lock, flags);
-}
-
-/**
- * register a client callback that called when device plugged in/unplugged
- * NOTE: if devices exist callback is called immediately for each device
- *
- * @param hotplug callback
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_hotplug(hotplug_t hotplug)
-{
-       smscore_device_notifyee_t *notifyee;
-       struct list_head *next, *first;
-       int rc = 0;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL);
-       if (notifyee)
-       {
-               // now notify callback about existing devices
-               first = &g_smscore_devices;
-               for (next = first->next; next != first && !rc; next = next->next)
-               {
-                       smscore_device_t *coredev = (smscore_device_t *) next;
-                       rc = hotplug(coredev, coredev->device, 1);
-               }
-
-               if (rc >= 0)
-               {
-                       notifyee->hotplug = hotplug;
-                       list_add(&notifyee->entry, &g_smscore_notifyees);
-               }
-               else
-                       kfree(notifyee);
-       }
-       else
-               rc = -ENOMEM;
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       return rc;
-}
-
-/**
- * unregister a client callback that called when device plugged in/unplugged
- *
- * @param hotplug callback
- *
- */
-void smscore_unregister_hotplug(hotplug_t hotplug)
-{
-       struct list_head *next, *first;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       first = &g_smscore_notifyees;
-
-       for (next = first->next; next != first;)
-       {
-               smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next;
-               next = next->next;
-
-               if (notifyee->hotplug == hotplug)
-               {
-                       list_del(&notifyee->entry);
-                       kfree(notifyee);
-               }
-       }
-
-       kmutex_unlock(&g_smscore_deviceslock);
-}
-
-void smscore_notify_clients(smscore_device_t *coredev)
-{
-       smscore_client_t* client;
-
-       // the client must call smscore_unregister_client from remove handler
-       while (!list_empty(&coredev->clients))
-       {
-               client = (smscore_client_t *) coredev->clients.next;
-               client->onremove_handler(client->context);
-       }
-}
-
-int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival)
-{
-       struct list_head *next, *first;
-       int rc = 0;
-
-       // note: must be called under g_deviceslock
-
-       first = &g_smscore_notifyees;
-
-       for (next = first->next; next != first; next = next->next)
-       {
-               rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival);
-               if (rc < 0)
-                       break;
-       }
-
-       return rc;
-}
-
-smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys)
-{
-       smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL);
-       if (!cb)
-       {
-               printk(KERN_INFO "%s kmalloc(...) failed\n", __FUNCTION__);
-               return NULL;
-       }
-
-       cb->p = buffer;
-       cb->offset_in_common = buffer - (u8*) common_buffer;
-       cb->phys = common_buffer_phys + cb->offset_in_common;
-
-       return cb;
-}
-
-/**
- * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies
- * registered hotplugs about new device.
- *
- * @param params device pointer to struct with device specific parameters and handlers
- * @param coredev pointer to a value that receives created coredev object
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev)
-{
-       smscore_device_t* dev;
-       u8 *buffer;
-
-       dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL);
-       if (!dev)
-       {
-               printk(KERN_INFO "%s kzalloc(...) failed\n", __FUNCTION__);
-               return -ENOMEM;
-       }
-
-       // init list entry so it could be safe in smscore_unregister_device
-       INIT_LIST_HEAD(&dev->entry);
-
-       // init queues
-       INIT_LIST_HEAD(&dev->clients);
-       INIT_LIST_HEAD(&dev->subclients);
-       INIT_LIST_HEAD(&dev->buffers);
-
-       // init locks
-       spin_lock_init(&dev->clientslock);
-       spin_lock_init(&dev->bufferslock);
-
-       // init completion events
-       init_completion(&dev->version_ex_done);
-       init_completion(&dev->data_download_done);
-       init_completion(&dev->trigger_done);
-       init_completion(&dev->init_device_done);
-       init_completion(&dev->reload_start_done);
-       init_completion(&dev->resume_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);
-       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)
-       {
-               smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys);
-               if (!cb)
-               {
-                       smscore_unregister_device(dev);
-                       return -ENOMEM;
-               }
-
-               smscore_putbuffer(dev, cb);
-       }
-
-       printk(KERN_INFO "%s allocated %d buffers\n", __FUNCTION__, dev->num_buffers);
-
-       dev->mode = DEVICE_MODE_NONE;
-       dev->context = params->context;
-       dev->device = params->device;
-       dev->setmode_handler = params->setmode_handler;
-       dev->detectmode_handler = params->detectmode_handler;
-       dev->sendrequest_handler = params->sendrequest_handler;
-       dev->preload_handler = params->preload_handler;
-       dev->postload_handler = params->postload_handler;
-
-       dev->device_flags = params->flags;
-       strcpy(dev->devpath, params->devpath);
-
-       // add device to devices list
-       kmutex_lock(&g_smscore_deviceslock);
-       list_add(&dev->entry, &g_smscore_devices);
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       *coredev = dev;
-
-       printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev);
-
-       return 0;
-}
-
-/**
- * sets initial device mode and notifies client hotplugs that device is ready
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_start_device(smscore_device_t *coredev)
-{
-       int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath));
-       if (rc < 0)
-               return rc;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       rc = smscore_notify_callbacks(coredev, coredev->device, 1);
-
-       printk(KERN_INFO "%s device %p started, rc %d\n", __FUNCTION__, coredev, rc);
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       return rc;
-}
-
-int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion)
-{
-       int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
-       if (rc < 0)
-               return rc;
-
-       return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME;
-}
-
-int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size)
-{
-       SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer;
-       SmsMsgHdr_ST *msg;
-       UINT32 mem_address = firmware->StartAddress;
-       u8* payload = firmware->Payload;
-       int rc = 0;
-
-       if (coredev->preload_handler)
-       {
-               rc = coredev->preload_handler(coredev->context);
-               if (rc < 0)
-                       return rc;
-       }
-
-       // PAGE_SIZE buffer shall be enough and dma aligned
-       msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
-       if (!msg)
-               return -ENOMEM;
-
-       if (coredev->mode != DEVICE_MODE_NONE)
-       {
-               SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST));
-               rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done);
-               mem_address = *(UINT32*) &payload[20];
-       }
-
-       while (size && rc >= 0)
-       {
-               SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg;
-               int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
-
-               SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + 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);
-               else
-                       rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done);
-
-               payload += payload_size;
-               size -= payload_size;
-               mem_address += payload_size;
-       }
-
-       if (rc >= 0)
-       {
-               if (coredev->mode == DEVICE_MODE_NONE)
-               {
-                       SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg;
-
-                       SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5);
-
-                       TriggerMsg->msgData[0] = firmware->StartAddress;        // 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, TriggerMsg->xMsgHeader.msgLength);
-                               msleep(100);
-                       }
-                       else
-                               rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done);
-               }
-               else
-               {
-                       SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST));
-
-                       rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength);
-               }
-       }
-
-       printk("%s %d \n", __func__, rc);
-
-       kfree(msg);
-
-       return (rc >= 0 && coredev->postload_handler) ?
-               coredev->postload_handler(coredev->context) :
-               rc;
-}
-
-/**
- * loads specified firmware into a buffer and calls device loadfirmware_handler
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- * @param filename null-terminated string specifies firmware file name
- * @param loadfirmware_handler device handler that loads firmware
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler)
-{
-       int rc = -ENOENT;
-
-       const struct firmware *fw;
-       u8* fw_buffer;
-
-       if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2))
-               return -EINVAL;
-
-       rc = request_firmware(&fw, filename, coredev->device);
-       if (rc < 0)
-       {
-               printk(KERN_INFO "%s failed to open \"%s\"\n", __FUNCTION__, filename);
-               return rc;
-       }
-
-       fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA);
-       if (fw_buffer)
-       {
-               memcpy(fw_buffer, fw->data, fw->size);
-
-               rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
-                       smscore_load_firmware_family2(coredev, fw_buffer, fw->size) :
-                       loadfirmware_handler(coredev->context, fw_buffer, fw->size);
-
-               kfree(fw_buffer);
-       }
-       else
-       {
-               printk(KERN_INFO "%s failed to allocate firmware buffer\n", __FUNCTION__);
-               rc = -ENOMEM;
-       }
-
-       release_firmware(fw);
-
-       return rc;
-}
-
-/**
- * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- *
- * @return 0 on success, <0 on error.
- */
-void smscore_unregister_device(smscore_device_t *coredev)
-{
-       smscore_buffer_t *cb;
-       int num_buffers = 0;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       smscore_notify_clients(coredev);
-       smscore_notify_callbacks(coredev, NULL, 0);
-
-       // at this point all buffers should be back
-       // onresponse must no longer be called
-
-       while (1)
-       {
-               while ((cb = smscore_getbuffer(coredev)))
-               {
-                       kfree(cb);
-                       num_buffers ++;
-               }
-
-               if (num_buffers == coredev->num_buffers)
-                       break;
-
-               printk(KERN_INFO "%s waiting for %d buffer(s)\n", __FUNCTION__, coredev->num_buffers - num_buffers);
-               msleep(100);
-       }
-
-       printk(KERN_INFO "%s freed %d buffers\n", __FUNCTION__, num_buffers);
-
-       if (coredev->common_buffer)
-               dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys);
-
-       list_del(&coredev->entry);
-       kfree(coredev);
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, coredev);
-}
-
-int smscore_detect_mode(smscore_device_t *coredev)
-{
-       void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
-       SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
-       int rc;
-
-       if (!buffer)
-               return -ENOMEM;
-
-       SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST));
-
-       rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done);
-       if (rc == -ETIME)
-       {
-               printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __FUNCTION__);
-
-               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);
-                       if (rc < 0)
-                       {
-                               printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __FUNCTION__, rc);
-                       }
-               }
-               else
-                       rc = -ETIME;
-       }
-
-       kfree(buffer);
-
-       return rc;
-}
-
-char *smscore_fw_lkup[] =
-{
-       "dvb_nova_12mhz.inp",
-       "dvb_nova_12mhz.inp",
-       "tdmb_nova.inp",
-       "none",
-       "dvb_nova_12mhz.inp",
-       "isdbt_nova_12mhz.inp",
-       "isdbt_nova_12mhz.inp",
-       "cmmb_nova_12mhz.inp",
-       "none",
-};
-
-/**
- * calls device handler to change mode of operation
- * NOTE: stellar/usb may disconnect when changing mode
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- * @param mode requested mode of operation
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_set_device_mode(smscore_device_t *coredev, int mode)
-{
-       void *buffer;
-       int rc = 0;
-
-       if (coredev->device_flags & SMS_DEVICE_FAMILY2)
-       {
-               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER)
-               {
-                       printk(KERN_INFO "%s invalid mode specified %d\n", __FUNCTION__, mode);
-                       return -EINVAL;
-               }
-
-               if (!(coredev->device_flags & SMS_DEVICE_NOT_READY))
-               {
-                       rc = smscore_detect_mode(coredev);
-                       if (rc < 0)
-                               return rc;
-               }
-
-               if (coredev->mode == mode)
-               {
-                       printk(KERN_INFO "%s device mode %d already set\n", __FUNCTION__, mode);
-                       return 0;
-               }
-
-               if (!(coredev->modes_supported & (1 << mode)))
-               {
-                       rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL);
-                       if (rc < 0)
-                               return rc;
-               }
-               else
-               {
-                       printk(KERN_INFO "%s mode %d supported by running firmware\n", __FUNCTION__, mode);
-               }
-
-               buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
-               if (buffer)
-               {
-                       SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer);
-
-                       SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST));
-                       msg->msgData[0] = mode;
-
-                       rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done);
-
-                       kfree(buffer);
-               }
-               else
-                       rc = -ENOMEM;
-       }
-       else
-       {
-               if (coredev->detectmode_handler)
-                       coredev->detectmode_handler(coredev->context, &coredev->mode);
-
-               if (coredev->mode != mode && coredev->setmode_handler)
-                       rc = coredev->setmode_handler(coredev->context, mode);
-       }
-
-       smscore_registry_setmode(coredev->devpath, mode);
-
-       if (rc >= 0)
-       {
-               coredev->mode = mode;
-               coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
-       }
-
-       return rc;
-}
-
-/**
- * calls device handler to get current mode of operation
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- *
- * @return current mode
- */
-int smscore_get_device_mode(smscore_device_t *coredev)
-{
-       return coredev->mode;
-}
-
-smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type)
-{
-       smscore_client_t *client = NULL;
-       struct list_head *next, *first;
-       unsigned long flags;
-
-       if (!data_type)
-               return NULL;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-
-       first = &coredev->clients;
-
-       for (next = first->next; next != first; next = next->next)
-       {
-               if (((smscore_client_t*) next)->data_type == data_type)
-               {
-                       client = (smscore_client_t*) next;
-                       break;
-               }
-       }
-
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-
-       return client;
-}
-
-smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id)
-{
-       smscore_client_t *client = NULL;
-       struct list_head *next, *first;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-
-       first = &coredev->subclients;
-
-       for (next = first->next; next != first; next = next->next)
-       {
-               if (((smscore_subclient_t*) next)->id == id)
-               {
-                       client = ((smscore_subclient_t*) next)->client;
-                       break;
-               }
-       }
-
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-
-       return client;
-}
-
-/**
- * find client by response id/type, call clients onresponse handler
- * return buffer to pool on error
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- * @param cb pointer to response buffer descriptor
- *
- */
-void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb)
-{
-       SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset);
-       smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType);
-       int rc = -EBUSY;
-
-       static unsigned long last_sample_time = 0;
-       static int data_total = 0;
-       unsigned long time_now = jiffies_to_msecs(jiffies);
-
-       if (!last_sample_time)
-               last_sample_time = time_now;
-
-       if (time_now - last_sample_time > 10000)
-       {
-               printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time)));
-
-               last_sample_time = time_now;
-               data_total = 0;
-       }
-
-       data_total += cb->size;
-
-       if (!client)
-               client = smscore_getclient_by_id(coredev, phdr->msgDstId);
-
-       if (client)
-               rc = client->onresponse_handler(client->context, cb);
-
-       if (rc < 0)
-       {
-               switch (phdr->msgType)
-               {
-                       case MSG_SMS_GET_VERSION_EX_RES:
-                       {
-                               SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr;
-                               printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __FUNCTION__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor);
-
-                               coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId;
-                               coredev->modes_supported = ver->SupportedProtocols;
-
-                               complete(&coredev->version_ex_done);
-                               break;
-                       }
-
-                       case MSG_SMS_INIT_DEVICE_RES:
-                               printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __FUNCTION__);
-                               complete(&coredev->init_device_done);
-                               break;
-
-                       case MSG_SW_RELOAD_START_RES:
-                               printk("%s: MSG_SW_RELOAD_START_RES\n", __FUNCTION__);
-                               complete(&coredev->reload_start_done);
-                               break;
-
-                       case MSG_SMS_DATA_DOWNLOAD_RES:
-                               complete(&coredev->data_download_done);
-                               break;
-
-                       case MSG_SW_RELOAD_EXEC_RES:
-                               printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __FUNCTION__);
-                               break;
-
-                       case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
-                               printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __FUNCTION__);
-                               complete(&coredev->trigger_done);
-                               break;
-
-                       case MSG_SMS_SLEEP_RESUME_COMP_IND:
-                               complete(&coredev->resume_done);
-                               break;
-
-                       default:
-                               printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __FUNCTION__, client, rc, phdr->msgType, phdr->msgDstId);
-               }
-
-               smscore_putbuffer(coredev, cb);
-       }
-}
-
-/**
- * return pointer to next free buffer descriptor from core pool
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- *
- * @return pointer to descriptor on success, NULL on error.
- */
-smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev)
-{
-       smscore_buffer_t *cb = NULL;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->bufferslock, flags);
-
-       if (!list_empty(&coredev->buffers))
-       {
-               cb = (smscore_buffer_t *) coredev->buffers.next;
-               list_del(&cb->entry);
-       }
-
-       spin_unlock_irqrestore(&coredev->bufferslock, flags);
-
-       return cb;
-}
-
-/**
- * return buffer descriptor to a pool
- *
- * @param coredev pointer to a coredev object returned by smscore_register_device
- * @param cb pointer buffer descriptor
- *
- */
-void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb)
-{
-       list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
-}
-
-int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id)
-{
-       smscore_client_t *existing_client;
-       smscore_subclient_t *subclient;
-
-       if (!id)
-               return 0;
-
-       existing_client = smscore_getclient_by_id(coredev, id);
-       if (existing_client == client)
-               return 0;
-
-       if (existing_client)
-               return -EBUSY;
-
-       subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL);
-       if (!subclient)
-               return -ENOMEM;
-
-       subclient->client = client;
-       subclient->id = id;
-
-       list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock);
-
-       return 0;
-}
-
-/**
- * creates smsclient object, check that id is taken by another client
- *
- * @param coredev pointer to a coredev object from clients hotplug
- * @param initial_id all messages with this id would be sent to this client
- * @param data_type all messages of this type would be sent to this client
- * @param onresponse_handler client handler that is called to process incoming messages
- * @param onremove_handler client handler that is called when device is removed
- * @param context client-specific context
- * @param client pointer to a value that receives created smsclient object
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client)
-{
-       smscore_client_t* newclient;
-       int rc;
-
-       // check that no other channel with same data type exists
-       if (params->data_type && smscore_getclient_by_type(coredev, params->data_type))
-               return -EEXIST;
-
-       newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL);
-       if (!newclient)
-               return -ENOMEM;
-
-       // check that no other channel with same id exists
-       rc = smscore_validate_client(coredev, newclient, params->initial_id);
-       if (rc < 0)
-       {
-               kfree(newclient);
-               return rc;
-       }
-
-       newclient->coredev = coredev;
-       newclient->data_type = params->data_type;
-       newclient->onresponse_handler = params->onresponse_handler;
-       newclient->onremove_handler = params->onremove_handler;
-       newclient->context = params->context;
-
-       list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock);
-
-       *client = newclient;
-
-       printk(KERN_INFO "%s %p %d %d\n", __FUNCTION__, params->context, params->data_type, params->initial_id);
-
-       return 0;
-}
-
-/**
- * frees smsclient object and all subclients associated with it
- *
- * @param client pointer to smsclient object returned by smscore_register_client
- *
- */
-void smscore_unregister_client(smscore_client_t *client)
-{
-       smscore_device_t *coredev = client->coredev;
-       struct list_head *next, *first;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-
-       first = &coredev->subclients;
-
-       for (next = first->next; next != first;)
-       {
-               smscore_subclient_t *subclient = (smscore_subclient_t *) next;
-               next = next->next;
-
-               if (subclient->client == client)
-               {
-                       list_del(&subclient->entry);
-                       kfree(subclient);
-               }
-       }
-
-       printk(KERN_INFO "%s %p %d\n", __FUNCTION__, client->context, client->data_type);
-
-       list_del(&client->entry);
-       kfree(client);
-
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-}
-
-/**
- * verifies that source id is not taken by another client,
- * calls device handler to send requests to the device
- *
- * @param client pointer to smsclient object returned by smscore_register_client
- * @param buffer pointer to a request buffer
- * @param size size (in bytes) of request buffer
- *
- * @return 0 on success, <0 on error.
- */
-int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size)
-{
-       smscore_device_t* coredev = client->coredev;
-       SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer;
-
-       // check that no other channel with same id exists
-       int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId);
-       if (rc < 0)
-               return rc;
-
-       return coredev->sendrequest_handler(coredev->context, buffer, size);
-}
-
-/**
- * return the size of large (common) buffer
- *
- * @param coredev pointer to a coredev object from clients hotplug
- *
- * @return size (in bytes) of the buffer
- */
-int smscore_get_common_buffer_size(smscore_device_t *coredev)
-{
-       return coredev->common_buffer_size;
-}
-
-/**
- * maps common buffer (if supported by platform)
- *
- * @param coredev pointer to a coredev object from clients hotplug
- * @param vma pointer to vma struct from mmap handler
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_map_common_buffer(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);
-
-       if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE))
-       {
-               printk(KERN_INFO "%s invalid vm flags\n", __FUNCTION__);
-               return -EINVAL;
-       }
-
-       if ((end - start) != size)
-       {
-               printk(KERN_INFO "%s invalid size %d expected %d\n", __FUNCTION__, (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)))
-       {
-               printk(KERN_INFO "%s remap_page_range failed\n", __FUNCTION__);
-               return -EAGAIN;
-       }
-
-       return 0;
-}
-
-int smscore_module_init(void)
-{
-       int rc = 0;
-
-       INIT_LIST_HEAD(&g_smscore_notifyees);
-       INIT_LIST_HEAD(&g_smscore_devices);
-       kmutex_init(&g_smscore_deviceslock);
-
-       INIT_LIST_HEAD(&g_smscore_registry);
-       kmutex_init(&g_smscore_registrylock);
-
-       /* USB Register */
-       rc = smsusb_register();
-
-       /* DVB Register */
-       rc = smsdvb_register();
-
-       printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc);
-
-       return rc;
-}
-
-void smscore_module_exit(void)
-{
-
-       kmutex_lock(&g_smscore_deviceslock);
-       while (!list_empty(&g_smscore_notifyees))
-       {
-               smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next;
-
-               list_del(&notifyee->entry);
-               kfree(notifyee);
-       }
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       kmutex_lock(&g_smscore_registrylock);
-       while (!list_empty(&g_smscore_registry))
-       {
-               smscore_registry_entry_t *entry = (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();
-
-       printk(KERN_INFO "%s\n", __FUNCTION__);
-}
-
-module_init(smscore_module_init);
-module_exit(smscore_module_exit);
-
-MODULE_DESCRIPTION("smscore");
-MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h
deleted file mode 100644 (file)
index 53c1d35..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- *  Driver for the Siano SMS10xx USB dongle
- *
- *  Copyright (c) 2008 <TODO: INSERT ALL COPYRIGHT OWNERS and MAINT. NAMES HERE>
- *
- *  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, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __smscoreapi_h__
-#define __smscoreapi_h__
-
-#include <linux/version.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <asm/scatterlist.h>
-#include <asm/page.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-
-#include <linux/mutex.h>
-
-typedef struct mutex kmutex_t;
-
-#define kmutex_init(_p_) mutex_init(_p_)
-#define kmutex_lock(_p_) mutex_lock(_p_)
-#define kmutex_trylock(_p_) mutex_trylock(_p_)
-#define kmutex_unlock(_p_) mutex_unlock(_p_)
-
-
-#ifndef min
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#define SMS_ALLOC_ALIGNMENT                                    128
-#define SMS_DMA_ALIGNMENT                                      16
-#define SMS_ALIGN_ADDRESS(addr) ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
-
-#define SMS_DEVICE_FAMILY2                                     1
-#define SMS_ROM_NO_RESPONSE                                    2
-#define SMS_DEVICE_NOT_READY                           0x8000000
-
-typedef struct _smscore_device smscore_device_t;
-typedef struct _smscore_client smscore_client_t;
-typedef struct _smscore_buffer smscore_buffer_t;
-
-typedef int (*hotplug_t)(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 (*onresponse_t)(void *context, smscore_buffer_t *cb);
-typedef void (*onremove_t)(void *context);
-
-typedef struct _smscore_buffer
-{
-       // public members, once passed to clients can be changed freely
-       struct list_head entry;
-       int                             size;
-       int                             offset;
-
-       // private members, read-only for clients
-       void                    *p;
-       dma_addr_t              phys;
-       unsigned long   offset_in_common;
-} *psmscore_buffer_t;
-
-typedef struct _smsdevice_params
-{
-       struct device   *device;
-
-       int                             buffer_size;
-       int                             num_buffers;
-
-       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;
-
-       void                    *context;
-} smsdevice_params_t;
-
-typedef struct _smsclient_params
-{
-       int                             initial_id;
-       int                             data_type;
-       onresponse_t    onresponse_handler;
-       onremove_t              onremove_handler;
-
-       void                    *context;
-} smsclient_params_t;
-
-// GPIO definitions for antenna frequency domain control (SMS8021)
-#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 MSG_HDR_FLAG_SPLIT_MSG                         4
-
-#define MAX_GPIO_PIN_NUMBER                                    31
-
-#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 MSG_SMS_GPIO_CONFIG_REQ                                507
-#define MSG_SMS_GPIO_CONFIG_RES                                508
-#define MSG_SMS_GPIO_SET_LEVEL_REQ                     509
-#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_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_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_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_GET_VERSION_EX_REQ                     668
-#define MSG_SMS_GET_VERSION_EX_RES                     669
-#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_START_REQ                                702
-#define MSG_SW_RELOAD_START_RES                                703
-#define MSG_SW_RELOAD_EXEC_REQ                         704
-#define MSG_SW_RELOAD_EXEC_RES                         705
-#define MSG_SMS_SPI_INT_LINE_SET_REQ           710
-#define MSG_SMS_ISDBT_TUNE_REQ                         776
-#define MSG_SMS_ISDBT_TUNE_RES                         777
-
-#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
-       (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
-       (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
-} while (0)
-#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
-
-typedef enum
-{
-       DEVICE_MODE_NONE = -1,
-       DEVICE_MODE_DVBT = 0,
-       DEVICE_MODE_DVBH,
-       DEVICE_MODE_DAB_TDMB,
-       DEVICE_MODE_DAB_TDMB_DABIP,
-       DEVICE_MODE_DVBT_BDA,
-       DEVICE_MODE_ISDBT,
-       DEVICE_MODE_ISDBT_BDA,
-       DEVICE_MODE_CMMB,
-       DEVICE_MODE_RAW_TUNER,
-       DEVICE_MODE_MAX,
-} SMS_DEVICE_MODE;
-
-typedef unsigned char UINT8;
-typedef unsigned short UINT16;
-typedef unsigned int UINT32;
-typedef int INT32;
-
-typedef struct SmsMsgHdr_S
-{
-       UINT16  msgType;
-       UINT8   msgSrcId;
-       UINT8   msgDstId;
-       UINT16  msgLength;      // Length is of the entire message, including header
-       UINT16  msgFlags;
-} SmsMsgHdr_ST;
-
-typedef struct SmsMsgData_S
-{
-       SmsMsgHdr_ST    xMsgHeader;
-       UINT32                  msgData[1];
-} SmsMsgData_ST;
-
-typedef struct SmsDataDownload_S
-{
-       SmsMsgHdr_ST    xMsgHeader;
-       UINT32                  MemAddr;
-       UINT8                   Payload[SMS_MAX_PAYLOAD_SIZE];
-} SmsDataDownload_ST;
-
-typedef struct SmsVersionRes_S
-{
-       SmsMsgHdr_ST    xMsgHeader;
-
-       UINT16                  ChipModel;                    // e.g. 0x1102 for SMS-1102 "Nova"
-       UINT8                   Step;                         // 0 - Step A
-       UINT8                   MetalFix;                     // 0 - Metal 0
-
-       UINT8                   FirmwareId;                   // 0xFF ï¿½ ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E
-       UINT8                   SupportedProtocols;           // Bitwise OR combination of supported protocols
-
-       UINT8                   VersionMajor;
-       UINT8                   VersionMinor;
-       UINT8                   VersionPatch;
-       UINT8                   VersionFieldPatch;
-
-       UINT8                   RomVersionMajor;
-       UINT8                   RomVersionMinor;
-       UINT8                   RomVersionPatch;
-       UINT8                   RomVersionFieldPatch;
-
-       UINT8                   TextLabel[34];
-} SmsVersionRes_ST;
-
-typedef struct SmsFirmware_S
-{
-       UINT32                  CheckSum;
-       UINT32                  Length;
-       UINT32                  StartAddress;
-       UINT8                   Payload[1];
-} SmsFirmware_ST;
-
-typedef struct SMSHOSTLIB_STATISTICS_S
-{
-       UINT32 Reserved;                                //!< Reserved
-
-       /// Common parameters
-       UINT32 IsRfLocked;                              //!< 0 - not locked, 1 - locked
-       UINT32 IsDemodLocked;                   //!< 0 - not locked, 1 - locked
-       UINT32 IsExternalLNAOn;                 //!< 0 - external LNA off, 1 - external LNA on
-
-       /// Reception quality
-       INT32  SNR;                                             //!< dB
-       UINT32 BER;                                             //!< Post Viterbi BER [1E-5]
-       UINT32 FIB_CRC;                                 //!< CRC errors percentage, valid only for DAB
-       UINT32 TS_PER;                                  //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H
-       UINT32 MFER;                                    //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H
-       INT32  RSSI;                                    //!< dBm
-       INT32  InBandPwr;                               //!< In band power in dBM
-       INT32  CarrierOffset;                   //!< Carrier Offset in bin/1024
-
-       /// Transmission parameters
-       UINT32 Frequency;                               //!< Frequency in Hz
-       UINT32 Bandwidth;                               //!< Bandwidth in MHz, valid only for DVB-T/H
-       UINT32 TransmissionMode;                //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos
-       UINT32 ModemState;                              //!< from SMS_DvbModemState_ET , valid only for DVB-T/H
-       UINT32 GuardInterval;                   //!< Guard Interval, 1 divided by value , valid only for DVB-T/H
-       UINT32 CodeRate;                                //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H
-       UINT32 LPCodeRate;                              //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H
-       UINT32 Hierarchy;                               //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H
-       UINT32 Constellation;                   //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H
-
-       /// Burst parameters, valid only for DVB-H
-       UINT32 BurstSize;                               //!< Current burst size in bytes, valid only for DVB-H
-       UINT32 BurstDuration;                   //!< Current burst duration in mSec, valid only for DVB-H
-       UINT32 BurstCycleTime;                  //!< Current burst cycle time in mSec, valid only for DVB-H
-       UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H
-       UINT32 NumOfRows;                               //!< Number of rows in MPE table, valid only for DVB-H
-       UINT32 NumOfPaddCols;                   //!< Number of padding columns in MPE table, valid only for DVB-H
-       UINT32 NumOfPunctCols;                  //!< Number of puncturing columns in MPE table, valid only for DVB-H
-       UINT32 ErrorTSPackets;                  //!< Number of erroneous transport-stream packets
-       UINT32 TotalTSPackets;                  //!< Total number of transport-stream packets
-       UINT32 NumOfValidMpeTlbs;               //!< Number of MPE tables which do not include errors after MPE RS decoding
-       UINT32 NumOfInvalidMpeTlbs;             //!< Number of MPE tables which include errors after MPE RS decoding
-       UINT32 NumOfCorrectedMpeTlbs;   //!< Number of MPE tables which were corrected by MPE RS decoding
-       /// Common params
-       UINT32 BERErrorCount;                   //!< Number of errornous SYNC bits.
-       UINT32 BERBitCount;                             //!< Total number of SYNC bits.
-
-       /// Interface information
-       UINT32 SmsToHostTxErrors;               //!< Total number of transmission errors.
-
-       /// DAB/T-DMB
-       UINT32 PreBER;                                  //!< DAB/T-DMB only: Pre Viterbi BER [1E-5]
-
-       /// DVB-H TPS parameters
-       UINT32 CellId;                                  //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered
-
-} SMSHOSTLIB_STATISTICS_ST;
-
-typedef struct
-{
-       UINT32 RequestResult;
-
-       SMSHOSTLIB_STATISTICS_ST Stat;
-
-       // Split the calc of the SNR in DAB
-       UINT32 Signal;                          //!< dB
-       UINT32 Noise;                           //!< dB
-
-} SmsMsgStatisticsInfo_ST;
-
-typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S
-{
-       // Per-layer information
-       UINT32 CodeRate;                        //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist
-       UINT32 Constellation;           //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist
-       UINT32 BER;                                     //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A
-       UINT32 BERErrorCount;           //!< Post Viterbi Error Bits Count
-       UINT32 BERBitCount;                     //!< Post Viterbi Total Bits Count
-       UINT32 PreBER;                          //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A
-       UINT32 TS_PER;                          //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A
-       UINT32 ErrorTSPackets;          //!< Number of erroneous transport-stream packets
-       UINT32 TotalTSPackets;          //!< Total number of transport-stream packets
-       UINT32 TILdepthI;                       //!< Time interleaver depth I parameter, 255 means layer does not exist
-       UINT32 NumberOfSegments;        //!< Number of segments in layer A, 255 means layer does not exist
-       UINT32 TMCCErrors;                      //!< TMCC errors
-} SMSHOSTLIB_ISDBT_LAYER_STAT_ST;
-
-typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S
-{
-       UINT32 StatisticsType;                  //!< Enumerator identifying the type of the structure.  Values are the same as SMSHOSTLIB_DEVICE_MODES_E
-                                                                       //!< This fiels MUST always first in any statistics structure
-
-       UINT32 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
-       UINT32 IsRfLocked;                              //!< 0 - not locked, 1 - locked
-       UINT32 IsDemodLocked;                   //!< 0 - not locked, 1 - locked
-       UINT32 IsExternalLNAOn;                 //!< 0 - external LNA off, 1 - external LNA on
-
-       // Reception quality
-       INT32  SNR;                                             //!< dB
-       INT32  RSSI;                                    //!< dBm
-       INT32  InBandPwr;                               //!< In band power in dBM
-       INT32  CarrierOffset;                   //!< Carrier Offset in Hz
-
-       // Transmission parameters
-       UINT32 Frequency;                               //!< Frequency in Hz
-       UINT32 Bandwidth;                               //!< Bandwidth in MHz
-       UINT32 TransmissionMode;                //!< ISDB-T transmission mode
-       UINT32 ModemState;                              //!< 0 - Acquisition, 1 - Locked
-       UINT32 GuardInterval;                   //!< Guard Interval, 1 divided by value
-       UINT32 SystemType;                              //!< ISDB-T system type (ISDB-T / ISDB-Tsb)
-       UINT32 PartialReception;                //!< TRUE - partial reception, FALSE otherwise
-       UINT32 NumOfLayers;                             //!< Number of ISDB-T layers in the network
-
-       // Per-layer information
-       // Layers A, B and C
-       SMSHOSTLIB_ISDBT_LAYER_STAT_ST  LayerInfo[3];   //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST
-
-       // Interface information
-       UINT32 SmsToHostTxErrors;               //!< Total number of transmission errors.
-
-} SMSHOSTLIB_STATISTICS_ISDBT_ST;
-
-typedef struct SMSHOSTLIB_STATISTICS_DVB_S
-{
-       UINT32 StatisticsType;                  //!< Enumerator identifying the type of the structure.  Values are the same as SMSHOSTLIB_DEVICE_MODES_E
-                                                               //!< This fiels MUST always first in any statistics structure
-
-       UINT32 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
-       UINT32 IsRfLocked;                              //!< 0 - not locked, 1 - locked
-       UINT32 IsDemodLocked;                   //!< 0 - not locked, 1 - locked
-       UINT32 IsExternalLNAOn;                 //!< 0 - external LNA off, 1 - external LNA on
-
-       // Reception quality
-       INT32  SNR;                                             //!< dB
-       UINT32 BER;                                             //!< Post Viterbi BER [1E-5]
-       UINT32 BERErrorCount;                   //!< Number of errornous SYNC bits.
-       UINT32 BERBitCount;                             //!< Total number of SYNC bits.
-       UINT32 TS_PER;                                  //!< Transport stream PER, 0xFFFFFFFF indicate N/A
-       UINT32 MFER;                                    //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H
-       INT32  RSSI;                                    //!< dBm
-       INT32  InBandPwr;                               //!< In band power in dBM
-       INT32  CarrierOffset;                   //!< Carrier Offset in bin/1024
-
-       // Transmission parameters
-       UINT32 Frequency;                               //!< Frequency in Hz
-       UINT32 Bandwidth;                               //!< Bandwidth in MHz
-       UINT32 ModemState;                              //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET
-       UINT32 TransmissionMode;                //!< FFT mode carriers in Kilos
-       UINT32 GuardInterval;                   //!< Guard Interval, 1 divided by value
-       UINT32 CodeRate;                                //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET
-       UINT32 LPCodeRate;                              //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET
-       UINT32 Hierarchy;                               //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET
-       UINT32 Constellation;                   //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET
-
-       // Burst parameters, valid only for DVB-H
-       UINT32 BurstSize;                               //!< Current burst size in bytes, valid only for DVB-H
-       UINT32 BurstDuration;                   //!< Current burst duration in mSec, valid only for DVB-H
-       UINT32 BurstCycleTime;                  //!< Current burst cycle time in mSec, valid only for DVB-H
-       UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H
-       UINT32 NumOfRows;                               //!< Number of rows in MPE table, valid only for DVB-H
-       UINT32 NumOfPaddCols;                   //!< Number of padding columns in MPE table, valid only for DVB-H
-       UINT32 NumOfPunctCols;                  //!< Number of puncturing columns in MPE table, valid only for DVB-H
-       UINT32 ErrorTSPackets;                  //!< Number of erroneous transport-stream packets
-       UINT32 TotalTSPackets;                  //!< Total number of transport-stream packets
-       UINT32 NumOfValidMpeTlbs;               //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H
-       UINT32 NumOfInvalidMpeTlbs;             //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H
-       UINT32 NumOfCorrectedMpeTlbs;   //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H
-       UINT32 NumMPEReceived;                  //!< DVB-H, Num MPE section received
-
-       // DVB-H TPS parameters
-       UINT32 CellId;                                  //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered
-       UINT32 DvbhSrvIndHP;                    //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator
-       UINT32 DvbhSrvIndLP;                    //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator
-
-       // Interface information
-       UINT32 SmsToHostTxErrors;               //!< Total number of transmission errors.
-
-} SMSHOSTLIB_STATISTICS_DVB_ST;
-
-typedef struct SMSHOSTLIB_GPIO_CONFIG_S
-{
-       UINT8   Direction;                              //!< GPIO direction: Input - 0, Output - 1
-       UINT8   PullUpDown;                             //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3
-       UINT8   InputCharacteristics;   //!< Input Characteristics: Normal - 0, Schmitt trigger - 1
-       UINT8   OutputSlewRate;                 //!< Output Slew Rate:  Fast slew rate - 0, Slow slew rate - 1
-       UINT8   OutputDriving;                  //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3
-} SMSHOSTLIB_GPIO_CONFIG_ST;
-
-typedef struct SMSHOSTLIB_I2C_REQ_S
-{
-       UINT32  DeviceAddress;                  // I2c device address
-       UINT32  WriteCount;                             // number of bytes to write
-       UINT32  ReadCount;                              // number of bytes to read
-       UINT8   Data[1];
-} SMSHOSTLIB_I2C_REQ_ST;
-
-typedef struct SMSHOSTLIB_I2C_RES_S
-{
-       UINT32  Status;                                 // non-zero value in case of failure
-       UINT32  ReadCount;                              // number of bytes read
-       UINT8   Data[1];
-} SMSHOSTLIB_I2C_RES_ST;
-
-typedef struct _smsdvb_client
-{
-       struct list_head entry;
-
-       smscore_device_t        *coredev;
-       smscore_client_t        *smsclient;
-
-       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_signal_strength;
-
-       struct completion       tune_done, stat_done;
-
-       // todo: save freq/band instead whole struct
-       struct dvb_frontend_parameters fe_params;
-
-} smsdvb_client_t;
-
-extern void smscore_registry_setmode(char *devpath, int mode);
-extern int smscore_registry_getmode(char *devpath);
-
-extern int smscore_register_hotplug(hotplug_t hotplug);
-extern void smscore_unregister_hotplug(hotplug_t hotplug);
-
-extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev);
-extern void smscore_unregister_device(smscore_device_t *coredev);
-
-extern int smscore_start_device(smscore_device_t *coredev);
-extern int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler);
-
-extern int smscore_set_device_mode(smscore_device_t *coredev, int mode);
-extern int smscore_get_device_mode(smscore_device_t *coredev);
-
-extern int smscore_register_client(smscore_device_t *coredev, smsclient_params_t* params, smscore_client_t **client);
-extern void smscore_unregister_client(smscore_client_t *client);
-
-extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size);
-extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb);
-
-extern int smscore_get_common_buffer_size(smscore_device_t *coredev);
-extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma);
-
-extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev);
-extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb);
-
-/* smsdvb.c */
-int smsdvb_register(void);
-void smsdvb_unregister(void);
-
-/* smsusb.c */
-int smsusb_register(void);
-void smsusb_unregister(void);
-
-#endif // __smscoreapi_h__
diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c
deleted file mode 100644 (file)
index f56658c..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- *  Driver for the Siano SMS10xx USB dongle
- *
- *  Copyright (c) 2008 <TODO: INSERT ALL COPYRIGHT OWNERS and MAINT. NAMES HERE>
- *
- *  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, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "smscoreapi.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct list_head g_smsdvb_clients;
-kmutex_t g_smsdvb_clientslock;
-
-int smsdvb_onresponse(void *context, smscore_buffer_t *cb)
-{
-       smsdvb_client_t *client = (smsdvb_client_t *) context;
-       SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8*) cb->p) + cb->offset);
-
-       switch(phdr->msgType)
-       {
-               case MSG_SMS_DVBT_BDA_DATA:
-                       dvb_dmx_swfilter(&client->demux, (u8*)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST));
-                       break;
-
-               case MSG_SMS_RF_TUNE_RES:
-                       complete(&client->tune_done);
-                       break;
-
-               case MSG_SMS_GET_STATISTICS_RES:
-               {
-                       SmsMsgStatisticsInfo_ST* p = (SmsMsgStatisticsInfo_ST*)(phdr + 1);
-
-                       if (p->Stat.IsDemodLocked)
-                       {
-                               client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-                               client->fe_snr = p->Stat.SNR;
-                               client->fe_ber = p->Stat.BER;
-
-                               if (p->Stat.InBandPwr < -95)
-                                       client->fe_signal_strength = 0;
-                               else if (p->Stat.InBandPwr > -29)
-                                       client->fe_signal_strength = 100;
-                               else
-                                       client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2;
-                       }
-                       else
-                       {
-                               client->fe_status = 0;
-                               client->fe_snr =
-                               client->fe_ber =
-                               client->fe_signal_strength = 0;
-                       }
-
-                       complete(&client->stat_done);
-                       break;
-               }
-       }
-
-       smscore_putbuffer(client->coredev, cb);
-
-       return 0;
-}
-
-void smsdvb_unregister_client(smsdvb_client_t* client)
-{
-       // must be called under clientslock
-
-       list_del(&client->entry);
-
-       smscore_unregister_client(client->smsclient);
-       dvb_unregister_frontend(&client->frontend);
-       dvb_dmxdev_release(&client->dmxdev);
-       dvb_dmx_release(&client->demux);
-       dvb_unregister_adapter(&client->adapter);
-       kfree(client);
-}
-
-void smsdvb_onremove(void *context)
-{
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       smsdvb_unregister_client((smsdvb_client_t*) context);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-static int smsdvb_start_feed(struct dvb_demux_feed *feed)
-{
-       smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux);
-       SmsMsgData_ST PidMsg;
-
-       printk("%s add pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid);
-
-       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
-       PidMsg.xMsgHeader.msgFlags = 0;
-       PidMsg.xMsgHeader.msgType  = MSG_SMS_ADD_PID_FILTER_REQ;
-       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
-       PidMsg.msgData[0] = feed->pid;
-
-       return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
-{
-       smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux);
-       SmsMsgData_ST PidMsg;
-
-       printk("%s remove pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid);
-
-       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
-       PidMsg.xMsgHeader.msgFlags = 0;
-       PidMsg.xMsgHeader.msgType  = MSG_SMS_REMOVE_PID_FILTER_REQ;
-       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
-       PidMsg.msgData[0] = feed->pid;
-
-       return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, void* buffer, size_t size, struct completion *completion)
-{
-       int rc = smsclient_sendrequest(client->smsclient, buffer, size);
-       if (rc < 0)
-               return rc;
-
-       return wait_for_completion_timeout(completion, msecs_to_jiffies(2000)) ? 0 : -ETIME;
-}
-
-static int smsdvb_send_statistics_request(smsdvb_client_t *client)
-{
-       SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 };
-       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done);
-}
-
-static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
-       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
-       int rc = smsdvb_send_statistics_request(client);
-
-       if (!rc)
-               *stat = client->fe_status;
-
-       return rc;
-}
-
-static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
-       int rc = smsdvb_send_statistics_request(client);
-
-       if (!rc)
-               *ber = client->fe_ber;
-
-       return rc;
-}
-
-static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
-       int rc = smsdvb_send_statistics_request(client);
-
-       if (!rc)
-               *strength = client->fe_signal_strength;
-
-       return rc;
-}
-
-static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
-       int rc = smsdvb_send_statistics_request(client);
-
-       if (!rc)
-               *snr = client->fe_snr;
-
-       return rc;
-}
-
-static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
-{
-       printk("%s\n", __FUNCTION__);
-
-       tune->min_delay_ms = 400;
-       tune->step_size = 250000;
-       tune->max_drift = 0;
-       return 0;
-}
-
-static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
-{
-       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
-
-       struct
-       {
-               SmsMsgHdr_ST    Msg;
-               u32                             Data[3];
-       } Msg;
-
-       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
-       Msg.Msg.msgDstId  = HIF_TASK;
-       Msg.Msg.msgFlags  = 0;
-       Msg.Msg.msgType   = MSG_SMS_RF_TUNE_REQ;
-       Msg.Msg.msgLength = sizeof(Msg);
-       Msg.Data[0] = fep->frequency;
-       Msg.Data[2] = 12000000;
-
-       printk("%s freq %d band %d\n", __FUNCTION__, fep->frequency, fep->u.ofdm.bandwidth);
-
-       switch(fep->u.ofdm.bandwidth)
-       {
-               case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break;
-               case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break;
-               case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break;
-//             case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break;
-               case BANDWIDTH_AUTO: return -EOPNOTSUPP;
-               default: return -EINVAL;
-       }
-
-       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done);
-}
-
-static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
-{
-       smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend);
-
-       printk("%s\n", __FUNCTION__);
-
-       // todo:
-       memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters));
-       return 0;
-}
-
-static void smsdvb_release(struct dvb_frontend *fe)
-{
-       // do nothing
-}
-
-static struct dvb_frontend_ops smsdvb_fe_ops = {
-       .info = {
-               .name                           = "Siano Mobile Digital SMS10xx",
-               .type                           = FE_OFDM,
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
-               .frequency_stepsize     = 250000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                               FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-                               FE_CAN_TRANSMISSION_MODE_AUTO |
-                               FE_CAN_GUARD_INTERVAL_AUTO |
-                               FE_CAN_RECOVER |
-                               FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = smsdvb_release,
-
-       .set_frontend = smsdvb_set_frontend,
-       .get_frontend = smsdvb_get_frontend,
-       .get_tune_settings = smsdvb_get_tune_settings,
-
-       .read_status = smsdvb_read_status,
-       .read_ber = smsdvb_read_ber,
-       .read_signal_strength = smsdvb_read_signal_strength,
-       .read_snr = smsdvb_read_snr,
-};
-
-int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival)
-{
-       smsclient_params_t params;
-       smsdvb_client_t* client;
-       int rc;
-
-       // device removal handled by onremove callback
-       if (!arrival)
-               return 0;
-
-       if (smscore_get_device_mode(coredev) != 4)
-       {
-               rc = smscore_set_device_mode(coredev, 4);
-               if (rc < 0)
-                       return rc;
-       }
-
-       client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL);
-       if (!client)
-       {
-               printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__);
-               return -ENOMEM;
-       }
-
-       // register dvb adapter
-       rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr);
-       if (rc < 0)
-       {
-               printk("%s dvb_register_adapter() failed %d\n", __func__, rc);
-               goto adapter_error;
-       }
-
-       // init dvb demux
-       client->demux.dmx.capabilities = DMX_TS_FILTERING;
-       client->demux.filternum = 32; // todo: nova ???
-       client->demux.feednum = 32;
-       client->demux.start_feed = smsdvb_start_feed;
-       client->demux.stop_feed = smsdvb_stop_feed;
-
-       rc = dvb_dmx_init(&client->demux);
-       if (rc < 0)
-       {
-               printk("%s dvb_dmx_init failed %d\n\n", __FUNCTION__, rc);
-               goto dvbdmx_error;
-       }
-
-       // init dmxdev
-       client->dmxdev.filternum = 32;
-       client->dmxdev.demux = &client->demux.dmx;
-       client->dmxdev.capabilities = 0;
-
-       rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
-       if (rc < 0)
-       {
-               printk("%s dvb_dmxdev_init failed %d\n", __FUNCTION__, rc);
-               goto dmxdev_error;
-       }
-
-       // init and register frontend
-       memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops));
-
-       rc = dvb_register_frontend(&client->adapter, &client->frontend);
-       if (rc < 0)
-       {
-               printk("%s frontend registration failed %d\n", __FUNCTION__, rc);
-               goto frontend_error;
-       }
-
-       params.initial_id = 0;
-       params.data_type = MSG_SMS_DVBT_BDA_DATA;
-       params.onresponse_handler = smsdvb_onresponse;
-       params.onremove_handler = smsdvb_onremove;
-       params.context = client;
-
-       rc = smscore_register_client(coredev, &params, &client->smsclient);
-       if (rc < 0)
-       {
-               printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc);
-               goto client_error;
-       }
-
-       client->coredev = coredev;
-
-       init_completion(&client->tune_done);
-       init_completion(&client->stat_done);
-
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       list_add(&client->entry, &g_smsdvb_clients);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-
-       printk(KERN_INFO "%s success\n", __FUNCTION__);
-
-       return 0;
-
-client_error:
-       dvb_unregister_frontend(&client->frontend);
-
-frontend_error:
-       dvb_dmxdev_release(&client->dmxdev);
-
-dmxdev_error:
-       dvb_dmx_release(&client->demux);
-
-dvbdmx_error:
-       dvb_unregister_adapter(&client->adapter);
-
-adapter_error:
-       kfree(client);
-       return rc;
-}
-
-int smsdvb_register(void)
-{
-       int rc;
-
-       INIT_LIST_HEAD(&g_smsdvb_clients);
-       kmutex_init(&g_smsdvb_clientslock);
-
-       rc = smscore_register_hotplug(smsdvb_hotplug);
-
-       printk(KERN_INFO "%s\n", __FUNCTION__);
-
-       return rc;
-}
-
-void smsdvb_unregister(void)
-{
-       smscore_unregister_hotplug(smsdvb_hotplug);
-
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       while (!list_empty(&g_smsdvb_clients))
-               smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-
-}
-
diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c
deleted file mode 100644 (file)
index c0f77a3..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- *  Driver for the Siano SMS10xx USB dongle
- *
- *  Copyright (c) 2008 <TODO: INSERT ALL COPYRIGHT OWNERS and MAINT. NAMES HERE>
- *
- *  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, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-
-#include "smscoreapi.h"
-
-#define USB1_BUFFER_SIZE               0x1000
-#define USB2_BUFFER_SIZE               0x4000
-
-#define MAX_BUFFERS            50
-#define MAX_URBS               10
-
-typedef struct _smsusb_device smsusb_device_t;
-
-typedef struct _smsusb_urb
-{
-       smscore_buffer_t *cb;
-       smsusb_device_t *dev;
-
-       struct urb              urb;
-} smsusb_urb_t;
-
-typedef struct _smsusb_device
-{
-       struct usb_device* udev;
-       smscore_device_t *coredev;
-
-       smsusb_urb_t    surbs[MAX_URBS];
-
-       int                             response_alignment;
-       int                             buffer_size;
-} *psmsusb_device_t;
-
-int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb);
-
-void smsusb_onresponse(struct urb *urb)
-{
-       smsusb_urb_t *surb = (smsusb_urb_t *) urb->context;
-       smsusb_device_t *dev = surb->dev;
-
-       if (urb->status < 0)
-       {
-               printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length);
-               return;
-       }
-
-       if (urb->actual_length > 0)
-       {
-               SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p;
-
-               if (urb->actual_length >= phdr->msgLength)
-               {
-                       surb->cb->size = phdr->msgLength;
-
-                       if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG))
-                       {
-                               surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3);
-
-                               // sanity check
-                               if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length)
-                               {
-                                       printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length);
-                                       goto exit_and_resubmit;
-                               }
-
-                               // move buffer pointer and copy header to its new location
-                               memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST));
-                       }
-                       else
-                               surb->cb->offset = 0;
-
-                       smscore_onresponse(dev->coredev, surb->cb);
-                       surb->cb = NULL;
-               }
-               else
-               {
-                       printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length);
-               }
-       }
-
-exit_and_resubmit:
-       smsusb_submit_urb(dev, surb);
-}
-
-int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb)
-{
-       if (!surb->cb)
-       {
-               surb->cb = smscore_getbuffer(dev->coredev);
-               if (!surb->cb)
-               {
-                       printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__);
-                       return -ENOMEM;
-               }
-       }
-
-       usb_fill_bulk_urb(
-               &surb->urb,
-               dev->udev,
-               usb_rcvbulkpipe(dev->udev, 0x81),
-               surb->cb->p,
-               dev->buffer_size,
-               smsusb_onresponse,
-               surb
-       );
-       surb->urb.transfer_dma = surb->cb->phys;
-       surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       return usb_submit_urb(&surb->urb, GFP_ATOMIC);
-}
-
-void smsusb_stop_streaming(smsusb_device_t* dev)
-{
-       int i;
-
-       for (i = 0; i < MAX_URBS; i ++)
-       {
-               usb_kill_urb(&dev->surbs[i].urb);
-
-               if (dev->surbs[i].cb)
-               {
-                       smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
-                       dev->surbs[i].cb = NULL;
-               }
-       }
-}
-
-int smsusb_start_streaming(smsusb_device_t* dev)
-{
-       int i, rc;
-
-       for (i = 0; i < MAX_URBS; i ++)
-       {
-               rc = smsusb_submit_urb(dev, &dev->surbs[i]);
-               if (rc < 0)
-               {
-                       printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__);
-                       smsusb_stop_streaming(dev);
-                       break;
-               }
-       }
-
-       return rc;
-}
-
-int smsusb_sendrequest(void *context, void *buffer, size_t size)
-{
-       smsusb_device_t* dev = (smsusb_device_t*) context;
-       int dummy;
-
-       return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000);
-}
-
-char *smsusb1_fw_lkup[] =
-{
-       "dvbt_stellar_usb.inp",
-       "dvbh_stellar_usb.inp",
-       "tdmb_stellar_usb.inp",
-       "none",
-       "dvbt_bda_stellar_usb.inp",
-};
-
-int smsusb1_load_firmware(struct usb_device *udev, int id)
-{
-       const struct firmware *fw;
-       u8* fw_buffer;
-       int rc, dummy;
-
-       if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA)
-       {
-               printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id);
-               return -EINVAL;
-       }
-
-       rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev);
-       if (rc < 0)
-       {
-               printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id);
-               return rc;
-       }
-
-       fw_buffer = kmalloc(fw->size, GFP_KERNEL);
-       if (fw_buffer)
-       {
-               memcpy(fw_buffer, fw->data, fw->size);
-
-               rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000);
-
-               printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc);
-
-               kfree(fw_buffer);
-       }
-       else
-       {
-               printk(KERN_INFO "failed to allocate firmware buffer\n");
-               rc = -ENOMEM;
-       }
-
-       release_firmware(fw);
-
-       return rc;
-}
-
-void smsusb1_detectmode(void *context, int *mode)
-{
-       char *product_string = ((smsusb_device_t *) context)->udev->product;
-
-       *mode = DEVICE_MODE_NONE;
-
-       if (!product_string)
-       {
-               product_string = "none";
-               printk("%s product string not found\n", __FUNCTION__);
-       }
-       else
-       {
-               if (strstr(product_string, "DVBH"))
-                       *mode = 1;
-               else if (strstr(product_string, "BDA"))
-                       *mode = 4;
-               else if (strstr(product_string, "DVBT"))
-                       *mode = 0;
-               else if (strstr(product_string, "TDMB"))
-                       *mode = 2;
-       }
-
-       printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string);
-}
-
-int smsusb1_setmode(void *context, int mode)
-{
-       SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 };
-
-       if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA)
-       {
-               printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode);
-               return -EINVAL;
-       }
-
-       return smsusb_sendrequest(context, &Msg, sizeof(Msg));
-}
-
-void smsusb_term_device(struct usb_interface *intf)
-{
-       smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf);
-
-       if (dev)
-       {
-               smsusb_stop_streaming(dev);
-
-               // unregister from smscore
-               if (dev->coredev)
-                       smscore_unregister_device(dev->coredev);
-
-               kfree(dev);
-
-               printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev);
-       }
-
-       usb_set_intfdata(intf, NULL);
-}
-
-int smsusb_init_device(struct usb_interface *intf)
-{
-       smsdevice_params_t params;
-       smsusb_device_t* dev;
-       int i, rc;
-
-       // create device object
-       dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL);
-       if (!dev)
-       {
-               printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__);
-               return -ENOMEM;
-       }
-
-       memset(&params, 0, sizeof(params));
-       usb_set_intfdata(intf, dev);
-       dev->udev = interface_to_usbdev(intf);
-
-       switch (dev->udev->descriptor.idProduct)
-       {
-               case 0x100:
-                       dev->buffer_size = USB1_BUFFER_SIZE;
-
-                       params.setmode_handler = smsusb1_setmode;
-                       params.detectmode_handler = smsusb1_detectmode;
-                       break;
-
-               default:
-                       dev->buffer_size = USB2_BUFFER_SIZE;
-                       dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST);
-
-                       params.flags |= SMS_DEVICE_FAMILY2;
-                       break;
-       }
-
-       params.device = &dev->udev->dev;
-       params.buffer_size = dev->buffer_size;
-       params.num_buffers = MAX_BUFFERS;
-       params.sendrequest_handler = smsusb_sendrequest;
-       params.context = dev;
-       snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath);
-
-       // register in smscore
-       rc = smscore_register_device(&params, &dev->coredev);
-       if (rc < 0)
-       {
-               printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc);
-               smsusb_term_device(intf);
-               return rc;
-       }
-
-       // initialize urbs
-       for (i = 0; i < MAX_URBS; i ++)
-       {
-               dev->surbs[i].dev = dev;
-               usb_init_urb(&dev->surbs[i].urb);
-       }
-
-       rc = smsusb_start_streaming(dev);
-       if (rc < 0)
-       {
-               printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__);
-               smsusb_term_device(intf);
-               return rc;
-       }
-
-       rc = smscore_start_device(dev->coredev);
-       if (rc < 0)
-       {
-               printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__);
-               smsusb_term_device(intf);
-               return rc;
-       }
-
-       printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev);
-
-       return rc;
-}
-
-int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       char devpath[32];
-       int i, rc;
-
-       if (intf->num_altsetting > 0)
-       {
-               rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
-               if (rc < 0)
-               {
-                       printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc);
-                       return rc;
-               }
-       }
-
-       printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber);
-       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++)
-               printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
-
-       if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0)
-       {
-               printk(KERN_INFO "rom interface 0 is not used\n");
-               return -ENODEV;
-       }
-
-       if (intf->cur_altsetting->desc.bInterfaceNumber == 1)
-       {
-               snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath);
-               return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath));
-       }
-
-       return smsusb_init_device(intf);
-}
-
-void smsusb_disconnect(struct usb_interface *intf)
-{
-       smsusb_term_device(intf);
-}
-
-static struct usb_device_id smsusb_id_table [] = {
-       { USB_DEVICE(0x187F, 0x0010) },
-       { USB_DEVICE(0x187F, 0x0100) },
-       { USB_DEVICE(0x187F, 0x0200) },
-       { }             /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, smsusb_id_table);
-
-static struct usb_driver smsusb_driver = {
-       .name                   = "smsusb",
-       .probe                  = smsusb_probe,
-       .disconnect     = smsusb_disconnect,
-       .id_table               = smsusb_id_table,
-};
-
-int smsusb_register(void)
-{
-       int rc = usb_register(&smsusb_driver);
-       if (rc)
-               printk(KERN_INFO "usb_register failed. Error number %d\n", rc);
-
-       printk(KERN_INFO "%s\n", __FUNCTION__);
-
-       return rc;
-}
-
-void smsusb_unregister(void)
-{
-       /* Regular USB Cleanup */
-       usb_deregister(&smsusb_driver);
-       printk(KERN_INFO "%s\n", __FUNCTION__);
-}
-
This page took 0.08654 seconds and 5 git commands to generate.