1 /****************************************************************
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2008, Uri Shkolnik
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ****************************************************************/
22 #include <linux/kernel.h>
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/delay.h>
29 #include <linux/uaccess.h>
31 #include <asm/semaphore.h>
33 #include <linux/firmware.h>
34 #include <asm/byteorder.h>
36 #include "smscoreapi.h"
37 #include "smsendian.h"
38 #include "sms-cards.h"
39 #include <mach/gpio.h>
40 #include <linux/slab.h>
42 #define MAX_GPIO_PIN_NUMBER 31
44 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
45 //#define REQUEST_FIRMWARE_SUPPORTED
46 #undef REQUEST_FIRMWARE_SUPPORTED
47 //#define DEFAULT_FW_FILE_PATH "/opl/usr/firmware/"
48 #define DEFAULT_FW_FILE_PATH "/etc/firmware/"
50 //#define DEFAULT_FW_FILE_PATH "/lib/firmware"
51 //#define DEFAULT_FW_FILE_PATH "/opl/usr/firmware/"
52 #define DEFAULT_FW_FILE_PATH "/etc/firmware/"
57 int sms_debug =0; //hzb 0526
59 char g_LbResBuf[256]={0};
61 volatile bool g_libdownload = false;
62 module_param_named(debug, sms_debug, int, 0644);
63 MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
65 //static int default_mode = 4;
66 static int default_mode = DEVICE_MODE_CMMB;
69 extern int g_IsTokenEnable;
70 extern int g_IsTokenOwned;
71 extern struct semaphore HalfDuplexSemaphore;
74 module_param(default_mode, int, 0644);
75 MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
77 struct smscore_device_notifyee_t {
78 struct list_head entry;
82 struct smscore_idlist_t {
83 struct list_head entry;
88 struct smscore_client_t {
89 struct list_head entry;
90 struct smscore_device_t *coredev;
92 struct list_head idlist;
93 onresponse_t onresponse_handler;
94 onremove_t onremove_handler;
97 struct smscore_device_t {
98 struct list_head entry;
100 struct list_head clients;
101 struct list_head subclients;
102 spinlock_t clientslock;
104 struct list_head buffers;
105 spinlock_t bufferslock;
109 int common_buffer_size;
110 dma_addr_t common_buffer_phys;
113 struct device *device;
116 unsigned long device_flags;
118 setmode_t setmode_handler;
119 detectmode_t detectmode_handler;
120 sendrequest_t sendrequest_handler;
121 preload_t preload_handler;
122 postload_t postload_handler;
124 int mode, modes_supported;
126 struct completion version_ex_done, data_download_done, trigger_done;
127 struct completion init_device_done, reload_start_done, resume_done;
128 struct completion gpio_configuration_done, gpio_set_level_done;
129 struct completion gpio_get_level_done;
131 struct completion loopback_res_done;
140 wait_queue_head_t buffer_mng_waitq;
147 static struct smscore_device_t* panic_core_dev = NULL ;
149 void smscore_panic_print(void)
153 printk("common_buffer_size = [0x%x]\n", panic_core_dev-> common_buffer_size) ;
154 printk("common_buffer start addr= [0x%x]\n",(unsigned int) panic_core_dev->common_buffer ) ;
155 printk("common_buffer end addr= [0x%x]\n",
156 (unsigned int) (panic_core_dev->common_buffer + panic_core_dev-> common_buffer_size -1)) ;
157 printk("common_buffer_phys start addr = [0x%x]\n",(unsigned int) panic_core_dev->common_buffer_phys) ;
158 printk("common_buffer_phys end addr = [0x%x]\n",
159 (unsigned int) ( panic_core_dev->common_buffer_phys+ panic_core_dev-> common_buffer_size -1)) ;
166 int AdrLoopbackTest( struct smscore_device_t *coredev );
168 void smscore_set_board_id(struct smscore_device_t *core, int id)
173 int smscore_get_board_id(struct smscore_device_t *core)
175 return core->board_id;
178 struct smscore_registry_entry_t {
179 struct list_head entry;
182 enum sms_device_type_st type;
185 static struct list_head g_smscore_notifyees;
186 static struct list_head g_smscore_devices;
187 static struct mutex g_smscore_deviceslock;
188 static struct list_head g_smscore_registry;
189 static struct mutex g_smscore_registrylock;
191 static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
193 struct smscore_registry_entry_t *entry;
194 struct list_head *next;
196 kmutex_lock(&g_smscore_registrylock);
197 for (next = g_smscore_registry.next; next != &g_smscore_registry; next
199 entry = (struct smscore_registry_entry_t *) next;
200 if (!strcmp(entry->devpath, devpath)) {
201 kmutex_unlock(&g_smscore_registrylock);
205 entry = /* (struct smscore_registry_entry_t *) */kmalloc(
206 sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
208 entry->mode = default_mode;
209 if(strlen(devpath) >= 32)
211 sms_err(" strlen(devpath) >= 32\n");
214 strcpy(entry->devpath, devpath);
215 list_add(&entry->entry, &g_smscore_registry);
217 sms_err("failed to create smscore_registry.");
218 kmutex_unlock(&g_smscore_registrylock);
222 int smscore_registry_getmode(char *devpath)
224 struct smscore_registry_entry_t *entry;
226 entry = smscore_find_registry(devpath);
230 sms_err("No registry found.");
235 static enum sms_device_type_st smscore_registry_gettype(char *devpath)
237 struct smscore_registry_entry_t *entry;
239 entry = smscore_find_registry(devpath);
243 sms_err("No registry found.");
248 void smscore_registry_setmode(char *devpath, int mode)
250 struct smscore_registry_entry_t *entry;
252 entry = smscore_find_registry(devpath);
256 sms_err("No registry found.");
259 static void smscore_registry_settype(char *devpath,
260 enum sms_device_type_st type) {
261 struct smscore_registry_entry_t *entry;
263 entry = smscore_find_registry(devpath);
267 sms_err("No registry found.");
270 static void list_add_locked(struct list_head *new, struct list_head *head,
274 spin_lock_irqsave(lock, flags);
276 spin_unlock_irqrestore(lock, flags);
280 * register a client callback that called when device plugged in/unplugged
281 * NOTE: if devices exist callback is called immediately for each device
283 * @param hotplug callback
285 * @return 0 on success, <0 on error.
287 int smscore_register_hotplug(hotplug_t hotplug)
289 struct smscore_device_notifyee_t *notifyee;
290 struct list_head *next, *first;
293 sms_info(" entering... smscore_register_hotplug \n");
294 kmutex_lock(&g_smscore_deviceslock);
296 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
299 /* now notify callback about existing devices */
300 first = &g_smscore_devices;
301 for (next = first->next; next != first && !rc;
303 struct smscore_device_t *coredev =
304 (struct smscore_device_t *) next;
305 rc = hotplug(coredev, coredev->device, 1);
309 notifyee->hotplug = hotplug;
310 list_add(¬ifyee->entry, &g_smscore_notifyees);
316 kmutex_unlock(&g_smscore_deviceslock);
322 * unregister a client callback that called when device plugged in/unplugged
324 * @param hotplug callback
327 void smscore_unregister_hotplug(hotplug_t hotplug)
329 struct list_head *next, *first;
331 kmutex_lock(&g_smscore_deviceslock);
333 first = &g_smscore_notifyees;
335 for (next = first->next; next != first;) {
336 struct smscore_device_notifyee_t *notifyee =
337 (struct smscore_device_notifyee_t *) next;
340 if (notifyee->hotplug == hotplug) {
341 list_del(¬ifyee->entry);
346 kmutex_unlock(&g_smscore_deviceslock);
349 static void smscore_notify_clients(struct smscore_device_t *coredev)
351 struct smscore_client_t *client;
353 /* the client must call smscore_unregister_client from remove handler */
354 while (!list_empty(&coredev->clients)) {
355 client = (struct smscore_client_t *) coredev->clients.next;
356 client->onremove_handler(client->context);
360 static int smscore_notify_callbacks(struct smscore_device_t *coredev,
361 struct device *device, int arrival) {
362 struct list_head *next, *first;
365 /* note: must be called under g_deviceslock */
367 first = &g_smscore_notifyees;
369 for (next = first->next; next != first; next = next->next) {
370 rc = ((struct smscore_device_notifyee_t *) next)->
371 hotplug(coredev, device, arrival);
379 static struct smscore_buffer_t *smscore_createbuffer(u8 *buffer,
380 void *common_buffer, dma_addr_t common_buffer_phys) {
381 struct smscore_buffer_t *cb = kmalloc(sizeof(struct smscore_buffer_t),
384 sms_info("kmalloc(...) failed");
389 cb->offset_in_common = buffer - (u8 *) common_buffer;
390 cb->phys = common_buffer_phys + cb->offset_in_common;
396 * creates coredev object for a device, prepares buffers,
397 * creates buffer mappings, notifies registered hotplugs about new device.
399 * @param params device pointer to struct with device specific parameters
401 * @param coredev pointer to a value that receives created coredev object
403 * @return 0 on success, <0 on error.
405 int smscore_register_device(struct smsdevice_params_t *params,
406 struct smscore_device_t **coredev) {
407 struct smscore_device_t *dev;
410 sms_info(" entering....smscore_register_device \n");
411 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
413 sms_info("kzalloc(...) failed");
417 /* init list entry so it could be safe in smscore_unregister_device */
418 INIT_LIST_HEAD(&dev->entry);
421 INIT_LIST_HEAD(&dev->clients);
422 INIT_LIST_HEAD(&dev->buffers);
425 spin_lock_init(&dev->clientslock);
426 spin_lock_init(&dev->bufferslock);
428 /* init completion events */
429 init_completion(&dev->version_ex_done);
430 init_completion(&dev->data_download_done);
431 init_completion(&dev->trigger_done);
432 init_completion(&dev->init_device_done);
433 init_completion(&dev->reload_start_done);
434 init_completion(&dev->resume_done);
435 init_completion(&dev->gpio_configuration_done);
436 init_completion(&dev->gpio_set_level_done);
437 init_completion(&dev->gpio_get_level_done);
439 init_completion(&dev->loopback_res_done);
440 init_waitqueue_head(&dev->buffer_mng_waitq);
442 /* alloc common buffer */
443 sms_info(" entering...alloc common buffer \n");
444 dev->common_buffer_size = params->buffer_size * params->num_buffers;
446 dev->common_buffer = kmalloc(dev->common_buffer_size, GFP_KERNEL|GFP_DMA);
447 dev->common_buffer_phys = __pa(dev->common_buffer);
448 sms_debug("dev->common_buffer_phys=0x%x",dev->common_buffer_phys);
450 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
451 &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA);
454 if (!dev->common_buffer) {
455 smscore_unregister_device(dev);
460 /* prepare dma buffers */
461 sms_info(" entering...prepare dma buffers \n");
464 for (buffer = dev->common_buffer ; dev->num_buffers <
465 params->num_buffers ; dev->num_buffers++, buffer
466 += params->buffer_size) {
467 struct smscore_buffer_t *cb = smscore_createbuffer(buffer,
468 dev->common_buffer, dev->common_buffer_phys);
470 smscore_unregister_device(dev);
474 smscore_putbuffer(dev, cb);
477 sms_info("allocated %d buffers", dev->num_buffers);
479 dev->mode = DEVICE_MODE_NONE;
480 dev->context = params->context;
481 dev->device = params->device;
482 dev->setmode_handler = params->setmode_handler;
483 dev->detectmode_handler = params->detectmode_handler;
484 dev->sendrequest_handler = params->sendrequest_handler;
485 dev->preload_handler = params->preload_handler;
486 dev->postload_handler = params->postload_handler;
488 dev->device_flags = params->flags;
489 strcpy(dev->devpath, params->devpath);
491 smscore_registry_settype(dev->devpath, params->device_type);
493 /* add device to devices list */
494 kmutex_lock(&g_smscore_deviceslock);
495 list_add(&dev->entry, &g_smscore_devices);
496 kmutex_unlock(&g_smscore_deviceslock);
499 panic_core_dev = dev ;
500 sms_info("device %p created", dev);
506 * sets initial device mode and notifies client hotplugs that device is ready
508 * @param coredev pointer to a coredev object returned by
509 * smscore_register_device
511 * @return 0 on success, <0 on error.
513 int smscore_start_device(struct smscore_device_t *coredev)
517 #ifdef REQUEST_FIRMWARE_SUPPORTED
518 rc = smscore_set_device_mode(coredev, smscore_registry_getmode(
521 sms_info("set device mode faile , rc %d", rc);
526 kmutex_lock(&g_smscore_deviceslock);
528 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
530 sms_info("device %p started, rc %d", coredev, rc);
532 kmutex_unlock(&g_smscore_deviceslock);
537 static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
538 void *buffer, size_t size, struct completion *completion) {
539 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
541 sms_info("sendrequest returned error %d", rc);
545 return wait_for_completion_timeout(completion,
546 msecs_to_jiffies(30000)) ? 0 : -ETIME;//10000
549 static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
550 void *buffer, size_t size) {
551 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
552 struct SmsMsgHdr_ST *msg;
554 u8 *payload = firmware->Payload;
557 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
558 firmware->Length = le32_to_cpu(firmware->Length);
560 mem_address = firmware->StartAddress;
562 sms_info("loading FW to addr 0x%x size %d",
563 mem_address, firmware->Length);
564 if (coredev->preload_handler) {
565 rc = coredev->preload_handler(coredev->context);
568 sms_err("sms preload handler fail !!!");
573 sms_info("preload handle after");
576 /* PAGE_SIZE buffer shall be enough and dma aligned */
577 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
581 //while (1)//hzb test 0527
584 //if (coredev->mode != DEVICE_MODE_NONE) //hzb test 0527
586 sms_info("sending MSG_SMS_GET_VERSION_EX_REQ command.");
587 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
588 sizeof(struct SmsMsgHdr_ST));
589 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
590 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
591 &coredev->version_ex_done);
592 // mem_address = *(u32 *) &payload[20];
593 sms_info("sms get version req ret=0x%x",rc);
598 g_libdownload = true;
601 while (size && rc >= 0) {
602 struct SmsDataDownload_ST *DataMsg =
603 (struct SmsDataDownload_ST *) msg;
604 int payload_size = min((int)size, SMS_MAX_PAYLOAD_SIZE);
606 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
607 (u16) (sizeof(struct SmsMsgHdr_ST) +
608 sizeof(u32) + payload_size));
610 DataMsg->MemAddr = mem_address;
611 memcpy(DataMsg->Payload, payload, payload_size);
613 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
614 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
615 (coredev->mode == DEVICE_MODE_NONE))
616 rc = coredev->sendrequest_handler(coredev->context,DataMsg,DataMsg->xMsgHeader.msgLength);
620 // complete(&coredev->data_download_done);
622 // g_libdownload = false;
625 rc = smscore_sendrequest_and_wait(coredev, DataMsg,DataMsg->xMsgHeader.msgLength,&coredev->data_download_done);
627 payload += payload_size;
628 size -= payload_size;
629 mem_address += payload_size;
631 sms_debug("size=%d \n", size);
634 sms_info("transfer over!!!!!!!!!!!!!!!!!!\n");
637 complete(&coredev->data_download_done);
639 g_libdownload = false;
641 // ¼ÓÈëÑÓʱ£¬·ÀÖ¹³õʼ»¯Ê§°Ü£¬ZYC
643 //printk("firmware is downloaded\n!!!!");
646 sms_info("firmware is loaded over 1111111111\n");
647 if (coredev->mode == DEVICE_MODE_NONE) {
648 struct SmsMsgData_ST *TriggerMsg =
649 (struct SmsMsgData_ST *) msg;
651 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
652 sizeof(struct SmsMsgHdr_ST) +
655 TriggerMsg->msgData[0] = firmware->StartAddress;
657 TriggerMsg->msgData[1] = 5; /* Priority */
658 TriggerMsg->msgData[2] = 0x200; /* Stack size */
659 TriggerMsg->msgData[3] = 0; /* Parameter */
660 TriggerMsg->msgData[4] = 4; /* Task ID */
662 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
663 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
665 sms_info("firmware is loaded over , but no response,222222222\n");
666 rc = coredev->sendrequest_handler(coredev->
668 TriggerMsg->xMsgHeader.msgLength);
671 rc = smscore_sendrequest_and_wait(coredev,
673 TriggerMsg->xMsgHeader.msgLength,
674 &coredev->trigger_done);
676 sms_info("firmware is loaded over , but mode is none,333333333333\n");
678 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
679 sizeof(struct SmsMsgHdr_ST));
680 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
681 rc = coredev->sendrequest_handler(coredev->context, msg,
688 sms_info("firmware is not loaded over , it is wrong,4444444444444\n");
690 sms_debug("rc=%d, postload=%p ", rc, coredev->postload_handler);
694 return ((rc >= 0) && coredev->postload_handler) ?
695 coredev->postload_handler(coredev->context) : rc;
699 * loads specified firmware into a buffer and calls device loadfirmware_handler
701 * @param coredev pointer to a coredev object returned by
702 * smscore_register_device
703 * @param filename null-terminated string specifies firmware file name
704 * @param loadfirmware_handler device handler that loads firmware
706 * @return 0 on success, <0 on error.
708 static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
709 char *filename, loadfirmware_t loadfirmware_handler) {
714 #ifdef REQUEST_FIRMWARE_SUPPORTED
715 const struct firmware *fw;
717 if (loadfirmware_handler == NULL && !(coredev->device_flags
718 & SMS_DEVICE_FAMILY2))
721 rc = request_firmware(&fw, filename, coredev->device);
723 sms_info("failed to open \"%s\"", filename);
726 sms_info("read FW %s, size=%zd", filename, fw->size);
727 fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
728 GFP_KERNEL | GFP_DMA);
730 sms_info("failed to allocate firmware buffer");
733 memcpy(fw_buf, fw->data, fw->size);
734 fw_buf_size = fw->size;
736 if (!coredev->fw_buf) {
737 sms_info("missing fw file buffer");
740 fw_buf = coredev->fw_buf;
741 fw_buf_size = coredev->fw_buf_size;
743 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
744 smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
745 : /*loadfirmware_handler(coredev->context, fw_buf,
746 fw_buf_size);*/printk(" error - should not be here\n");
749 #ifdef REQUEST_FIRMWARE_SUPPORTED
750 release_firmware(fw);
752 coredev->fw_buf = NULL;
753 coredev->fw_buf_size = 0;
759 * notifies all clients registered with the device, notifies hotplugs,
760 * frees all buffers and coredev object
762 * @param coredev pointer to a coredev object returned by
763 * smscore_register_device
765 * @return 0 on success, <0 on error.
767 void smscore_unregister_device(struct smscore_device_t *coredev)
769 struct smscore_buffer_t *cb;
773 kmutex_lock(&g_smscore_deviceslock);
775 smscore_notify_clients(coredev);
776 smscore_notify_callbacks(coredev, NULL, 0);
778 /* at this point all buffers should be back
779 * onresponse must no longer be called */
782 while(!list_empty(&coredev->buffers))
784 cb = (struct smscore_buffer_t *) coredev->buffers.next;
785 list_del(&cb->entry);
789 if (num_buffers == coredev->num_buffers )
792 sms_info("exiting although "
793 "not all buffers released.");
797 sms_info("waiting for %d buffer(s)",
798 coredev->num_buffers - num_buffers);
802 sms_info("freed %d buffers", num_buffers);
804 if(coredev->common_buffer)
807 kfree(coredev->common_buffer);
809 dma_free_coherent(NULL, coredev->common_buffer_size,coredev->common_buffer, coredev->common_buffer_phys);
812 if (coredev->fw_buf != NULL)
813 kfree(coredev->fw_buf);
815 list_del(&coredev->entry);
817 panic_core_dev = NULL ;
818 kmutex_unlock(&g_smscore_deviceslock);
820 sms_info("device %p destroyed", coredev);
823 static int smscore_detect_mode(struct smscore_device_t *coredev)
825 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
826 GFP_KERNEL | GFP_DMA);
827 struct SmsMsgHdr_ST *msg =
828 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
834 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
835 sizeof(struct SmsMsgHdr_ST));
837 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
838 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
839 &coredev->version_ex_done);
841 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
843 if (wait_for_completion_timeout(&coredev->resume_done,
844 msecs_to_jiffies(5000))) {
845 rc = smscore_sendrequest_and_wait(coredev, msg,
846 msg->msgLength, &coredev->version_ex_done);
848 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
849 "second try, rc %d", rc);
859 static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
860 /*Stellar NOVA A0 Nova B0 VEGA */
862 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
864 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
866 { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none" },
867 /*DABIP*/{ "none", "none", "none", "none" },
869 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
871 { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none" },
873 { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none" },
874 /*CMMB*/{ "none", "none", "none", "cmmb_vega_12mhz.inp" } };
876 static inline char *sms_get_fw_name(struct smscore_device_t *coredev, int mode,
877 enum sms_device_type_st type) {
878 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
879 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
883 int smscore_reset_device_drvs(struct smscore_device_t *coredev)
887 sms_debug("currnet device mode to %d", coredev->mode);
888 coredev->mode = DEVICE_MODE_NONE;
889 coredev->device_flags = SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY |
897 * calls device handler to change mode of operation
898 * NOTE: stellar/usb may disconnect when changing mode
900 * @param coredev pointer to a coredev object returned by
901 * smscore_register_device
902 * @param mode requested mode of operation
904 * @return 0 on success, <0 on error.
906 int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
910 enum sms_device_type_st type;
913 sms_info("set device mode to %d", mode);
914 //sms_debug("current device mode, device flags, modes_supported to %d", coredev->mode, coredev->device_flags, coredev->modes_supported);
916 sms_debug("set device mode to %d", mode);
917 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
918 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
919 sms_err("invalid mode specified %d", mode);
923 smscore_registry_setmode(coredev->devpath, mode);
925 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
926 rc = smscore_detect_mode(coredev);
928 sms_err("mode detect failed %d", rc);
933 if (coredev->mode == mode) {
934 sms_info("device mode %d already set", mode);
938 if (!(coredev->modes_supported & (1 << mode))) {
941 type = smscore_registry_gettype(coredev->devpath);
942 fw_filename = sms_get_fw_name(coredev, mode, type);
944 if(NULL == fw_filename)
946 sms_err("wrong filename");
950 rc = smscore_load_firmware_from_file(coredev,
953 sms_warn("error %d loading firmware: %s, "
954 "trying again with default firmware",
957 /* try again with the default firmware */
958 fw_filename = smscore_fw_lkup[mode][type];
959 rc = smscore_load_firmware_from_file(coredev,
963 sms_warn("error %d loading "
969 sms_info("firmware download success: %s", fw_filename);
971 sms_info("mode %d supported by running "
974 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
975 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
977 struct SmsMsgData_ST *msg =
978 (struct SmsMsgData_ST *)
979 SMS_ALIGN_ADDRESS(buffer);
981 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
982 sizeof(struct SmsMsgData_ST));
983 msg->msgData[0] = mode;
987 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
988 rc = smscore_sendrequest_and_wait(coredev, msg,
989 msg->xMsgHeader.msgLength,
990 &coredev->init_device_done);
991 sms_info("send MSG_SMS_INIT_DEVICE_REQ res = %d\n ",rc);
994 sms_err("Could not allocate buffer for "
995 "init device message.");
999 // start to do loopback test
1000 // rc = AdrLoopbackTest(coredev);
1004 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
1005 sms_err("invalid mode specified %d", mode);
1009 smscore_registry_setmode(coredev->devpath, mode);
1011 if (coredev->detectmode_handler)
1012 coredev->detectmode_handler(coredev->context,
1015 if (coredev->mode != mode && coredev->setmode_handler)
1016 rc = coredev->setmode_handler(coredev->context, mode);
1020 sms_info("device is ready");
1022 struct SmsMsgHdr_ST *msg;
1024 msg = kmalloc(sizeof(struct SmsMsgHdr_ST), GFP_KERNEL | GFP_DMA);
1026 sms_debug("sending MSG_SMS_GET_VERSION_EX_REQ command.");
1027 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,sizeof(struct SmsMsgHdr_ST));
1028 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
1029 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done);
1032 #if SIANO_HALFDUPLEX
1033 g_IsTokenEnable = true;
1034 g_IsTokenOwned = true;
1035 up(&HalfDuplexSemaphore);
1036 sms_debug("g_IsTokenEnable = true \n");
1038 coredev->mode = mode;
1039 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
1043 sms_err("return error code %d.", rc);
1048 * calls device handler to get fw file name
1050 * @param coredev pointer to a coredev object returned by
1051 * smscore_register_device
1052 * @param filename pointer to user buffer to fill the file name
1054 * @return 0 on success, <0 on error.
1056 int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode,
1059 enum sms_device_type_st type;
1062 type = smscore_registry_gettype(coredev->devpath);
1064 #ifdef REQUEST_FIRMWARE_SUPPORTED
1065 /* driver not need file system services */
1068 sprintf(tmpname, "%s/%s", DEFAULT_FW_FILE_PATH,
1069 smscore_fw_lkup[mode][type]);
1071 if (copy_to_user(filename, tmpname, strlen(tmpname) + 1)) {
1072 sms_err("Failed copy file path to user buffer\n");
1079 * calls device handler to keep fw buff for later use
1081 * @param coredev pointer to a coredev object returned by
1082 * smscore_register_device
1083 * @param ufwbuf pointer to user fw buffer
1084 * @param size size in bytes of buffer
1086 * @return 0 on success, <0 on error.
1088 int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf,
1092 /* free old buffer */
1093 if (coredev->fw_buf != NULL) {
1094 kfree(coredev->fw_buf);
1095 coredev->fw_buf = NULL;
1098 coredev->fw_buf = kmalloc(ALIGN(size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA);
1099 if (!coredev->fw_buf) {
1100 sms_err("Failed allocate FW buffer memory\n");
1104 if (copy_from_user(coredev->fw_buf, ufwbuf, size)) {
1105 sms_err("Failed copy FW from user buffer\n");
1106 kfree(coredev->fw_buf);
1109 coredev->fw_buf_size = size;
1115 * calls device handler to get current mode of operation
1117 * @param coredev pointer to a coredev object returned by
1118 * smscore_register_device
1120 * @return current mode
1122 int smscore_get_device_mode(struct smscore_device_t *coredev)
1124 return coredev->mode;
1128 * find client by response id & type within the clients list.
1129 * return client handle or NULL.
1131 * @param coredev pointer to a coredev object returned by
1132 * smscore_register_device
1133 * @param data_type client data type (SMS_DONT_CARE for all types)
1134 * @param id client id (SMS_DONT_CARE for all id)
1137 static struct smscore_client_t *smscore_find_client(
1138 struct smscore_device_t *coredev, int data_type, int id) {
1139 struct smscore_client_t *client = NULL;
1140 struct list_head *next, *first;
1141 unsigned long flags;
1142 struct list_head *firstid, *nextid;
1144 spin_lock_irqsave(&coredev->clientslock, flags);
1145 first = &coredev->clients;
1146 for (next = first->next; (next != first) && !client;
1147 next = next->next) {
1148 firstid = &((struct smscore_client_t *) next)->idlist;
1149 for (nextid = firstid->next; nextid != firstid;
1150 nextid = nextid->next) {
1151 if ((((struct smscore_idlist_t *) nextid)->id == id)
1152 && (((struct smscore_idlist_t *)
1155 || (((struct smscore_idlist_t *)
1156 nextid)->data_type == 0))) {
1157 client = (struct smscore_client_t *) next;
1162 spin_unlock_irqrestore(&coredev->clientslock, flags);
1167 * find client by response id/type, call clients onresponse handler
1168 * return buffer to pool on error
1170 * @param coredev pointer to a coredev object returned by
1171 * smscore_register_device
1172 * @param cb pointer to response buffer descriptor
1175 void smscore_onresponse(struct smscore_device_t *coredev,
1176 struct smscore_buffer_t *cb) {
1177 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
1179 struct smscore_client_t *client = smscore_find_client(coredev,
1180 phdr->msgType, phdr->msgDstId);
1183 static unsigned long last_sample_time; /* = 0; */
1184 static int data_total; /* = 0; */
1185 unsigned long time_now = jiffies_to_msecs(jiffies);
1187 if (!last_sample_time)
1188 last_sample_time = time_now;
1190 if (time_now - last_sample_time > 10000) {
1191 sms_debug("\ndata rate %d bytes/secs",
1192 (int)((data_total * 1000) /
1193 (time_now - last_sample_time)));
1195 last_sample_time = time_now;
1200 data_total += cb->size;
1201 /* If no client registered for type & id,
1202 * check for control client where type is not registered */
1206 sms_debug("client=0x %x\n", client);
1207 rc = client->onresponse_handler(client->context, cb);
1209 sms_debug("onresponse_handler ret = 0x%x\n", rc);
1210 sms_debug("phdr->msgType %d\n", phdr->msgType);
1211 #if SIANO_HALFDUPLEX
1212 if (phdr->msgType==MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST){
1213 g_IsTokenOwned = true;
1214 sms_debug("MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST \n");
1219 smsendian_handle_rx_message((struct SmsMsgData_ST *)phdr);
1221 switch (phdr->msgType) {
1222 case MSG_SMS_GET_VERSION_EX_RES: {
1223 struct SmsVersionRes_ST *ver = (struct SmsVersionRes_ST *) phdr;
1225 sms_debug("MSG_SMS_GET_VERSION_EX_RES "
1226 "id %d prots 0x%x ver %d.%d",
1228 ver->SupportedProtocols,
1229 ver->RomVersionMajor,
1230 ver->RomVersionMinor);
1232 printk("MSG_SMS_GET_VERSION_EX_RES "
1233 "id %d prots 0x%x ver %d.%d\n",
1235 ver->SupportedProtocols,
1236 ver->RomVersionMajor,
1237 ver->RomVersionMinor);
1239 ver->TextLabel[33] = 0x0;
1241 printk("fw version is %s\n",ver->TextLabel);
1243 coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId;
1244 coredev->modes_supported = ver->SupportedProtocols;
1246 complete(&coredev->version_ex_done);
1249 case MSG_SMS_INIT_DEVICE_RES:
1250 sms_debug("MSG_SMS_INIT_DEVICE_RES");
1251 complete(&coredev->init_device_done);
1253 case MSG_SW_RELOAD_START_RES:
1254 sms_debug("MSG_SW_RELOAD_START_RES");
1255 complete(&coredev->reload_start_done);
1257 case MSG_SMS_DATA_DOWNLOAD_RES:
1258 complete(&coredev->data_download_done);
1260 case MSG_SW_RELOAD_EXEC_RES:
1261 sms_debug("MSG_SW_RELOAD_EXEC_RES");
1263 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
1264 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
1265 complete(&coredev->trigger_done);
1267 case MSG_SMS_SLEEP_RESUME_COMP_IND:
1268 complete(&coredev->resume_done);
1270 case MSG_SMS_GPIO_CONFIG_EX_RES:
1271 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
1272 complete(&coredev->gpio_configuration_done);
1274 case MSG_SMS_GPIO_SET_LEVEL_RES:
1275 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
1276 complete(&coredev->gpio_set_level_done);
1278 case MSG_SMS_GPIO_GET_LEVEL_RES:
1280 u32 *msgdata = (u32 *) phdr;
1281 coredev->gpio_get_res = msgdata[1];
1282 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", coredev->gpio_get_res);
1283 complete(&coredev->gpio_get_level_done);
1287 // loopback in the drv
1289 case MSG_SMS_LOOPBACK_RES:
1291 //u32 *msgdata = (u32 *) phdr;
1292 memcpy( g_LbResBuf, (u8 *)phdr, phdr->msgLength );
1293 sms_debug("MSG_SMS_LOOPBACK_RES \n");
1294 complete(&coredev->loopback_res_done);
1300 sms_info("no client (%p) or error (%d), "
1301 "type:%d dstid:%d", client, rc,
1302 phdr->msgType, phdr->msgDstId);
1307 smscore_putbuffer(coredev, cb);
1308 //sms_debug("after putbuffer \n");
1315 * return pointer to next free buffer descriptor from core pool
1317 * @param coredev pointer to a coredev object returned by
1318 * smscore_register_device
1320 * @return pointer to descriptor on success, NULL on error.
1322 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1324 struct smscore_buffer_t *cb = NULL;
1325 unsigned long flags;
1329 spin_lock_irqsave(&coredev->bufferslock, flags);
1331 /* This function must return a valid buffer, since the buffer list is
1332 * finite, we check that there is an available buffer, if not, we wait
1333 * until such buffer become available.
1336 prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
1338 if (list_empty(&coredev->buffers))
1340 //to avoid rx buffers hung
1341 printk("eladr: smscore_getbuffer scheduled caus list is empty\n");
1342 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1344 spin_lock_irqsave(&coredev->bufferslock, flags);
1347 //printk("smscore_getbuffer call finish_wait\n");
1348 finish_wait(&coredev->buffer_mng_waitq, &wait);
1350 // if list is still empty we will return null
1351 if (list_empty(&coredev->buffers))
1354 printk("eladr: smscore_getbuffer fail to allocate buffer, returning null \n");
1358 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1359 if(cb->entry.prev==LIST_POISON1 || cb->entry.next==LIST_POISON1 || cb->entry.prev==LIST_POISON2 || cb->entry.next==LIST_POISON2 )
1361 printk("smscore_getbuffer list is no good\n");
1362 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1366 //printk("smscore_getbuffer buffer was allocated cb=0x%x\n", cb);
1367 list_del(&cb->entry);
1370 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1376 * return buffer descriptor to a pool
1378 * @param coredev pointer to a coredev object returned by
1379 * smscore_register_device
1380 * @param cb pointer buffer descriptor
1383 void smscore_putbuffer(struct smscore_device_t *coredev,
1384 struct smscore_buffer_t *cb) {
1385 wake_up_interruptible(&coredev->buffer_mng_waitq);
1386 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1389 static int smscore_validate_client(struct smscore_device_t *coredev,
1390 struct smscore_client_t *client, int data_type, int id) {
1391 struct smscore_idlist_t *listentry;
1392 struct smscore_client_t *registered_client;
1395 sms_err("bad parameter.");
1398 registered_client = smscore_find_client(coredev, data_type, id);
1399 if (registered_client == client)
1402 if (registered_client) {
1403 sms_err("The msg ID already registered to another client.");
1406 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
1408 sms_err("Can't allocate memory for client id.");
1412 listentry->data_type = data_type;
1413 list_add_locked(&listentry->entry, &client->idlist,
1414 &coredev->clientslock);
1419 * creates smsclient object, check that id is taken by another client
1421 * @param coredev pointer to a coredev object from clients hotplug
1422 * @param initial_id all messages with this id would be sent to this client
1423 * @param data_type all messages of this type would be sent to this client
1424 * @param onresponse_handler client handler that is called to
1425 * process incoming messages
1426 * @param onremove_handler client handler that is called when device is removed
1427 * @param context client-specific context
1428 * @param client pointer to a value that receives created smsclient object
1430 * @return 0 on success, <0 on error.
1432 int smscore_register_client(struct smscore_device_t *coredev,
1433 struct smsclient_params_t *params,
1434 struct smscore_client_t **client) {
1435 struct smscore_client_t *newclient;
1437 /* check that no other channel with same parameters exists */
1439 sms_info("entering....smscore_register_client \n");
1441 if (smscore_find_client(coredev, params->data_type, params->initial_id)) {
1442 sms_err("Client already exist.");
1446 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
1448 sms_err("Failed to allocate memory for client.");
1452 INIT_LIST_HEAD(&newclient->idlist);
1453 newclient->coredev = coredev;
1454 newclient->onresponse_handler = params->onresponse_handler;
1455 newclient->onremove_handler = params->onremove_handler;
1456 newclient->context = params->context;
1457 list_add_locked(&newclient->entry, &coredev->clients,&coredev->clientslock);
1458 smscore_validate_client(coredev, newclient, params->data_type,params->initial_id);
1459 *client = newclient;
1460 sms_debug("Register new client %p DT=%d ID=%d",
1461 params->context, params->data_type, params->initial_id);
1467 * frees smsclient object and all subclients associated with it
1469 * @param client pointer to smsclient object returned by
1470 * smscore_register_client
1473 void smscore_unregister_client(struct smscore_client_t *client)
1475 struct smscore_device_t *coredev = client->coredev;
1476 unsigned long flags;
1478 spin_lock_irqsave(&coredev->clientslock, flags);
1480 while (!list_empty(&client->idlist)) {
1481 struct smscore_idlist_t *identry =
1482 (struct smscore_idlist_t *) client->idlist.next;
1483 list_del(&identry->entry);
1487 sms_info("%p", client->context);
1489 list_del(&client->entry);
1492 spin_unlock_irqrestore(&coredev->clientslock, flags);
1496 * verifies that source id is not taken by another client,
1497 * calls device handler to send requests to the device
1499 * @param client pointer to smsclient object returned by
1500 * smscore_register_client
1501 * @param buffer pointer to a request buffer
1502 * @param size size (in bytes) of request buffer
1504 * @return 0 on success, <0 on error.
1506 int smsclient_sendrequest(struct smscore_client_t *client, void *buffer,
1508 struct smscore_device_t *coredev;
1509 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
1512 if (client == NULL) {
1513 sms_err("Got NULL client");
1517 coredev = client->coredev;
1519 /* check that no other channel with same id exists */
1520 if (coredev == NULL) {
1521 sms_err("Got NULL coredev");
1525 rc = smscore_validate_client(client->coredev, client, 0,
1530 return coredev->sendrequest_handler(coredev->context, buffer, size);
1533 #ifdef SMS_HOSTLIB_SUBSYS
1535 * return the size of large (common) buffer
1537 * @param coredev pointer to a coredev object from clients hotplug
1539 * @return size (in bytes) of the buffer
1541 int smscore_get_common_buffer_size(struct smscore_device_t *coredev)
1543 return coredev->common_buffer_size;
1547 * maps common buffer (if supported by platform)
1549 * @param coredev pointer to a coredev object from clients hotplug
1550 * @param vma pointer to vma struct from mmap handler
1552 * @return 0 on success, <0 on error.
1554 int smscore_map_common_buffer(struct smscore_device_t *coredev,
1555 struct vm_area_struct *vma)
1557 unsigned long end = vma->vm_end,
1558 start = vma->vm_start,
1559 size = PAGE_ALIGN(coredev->common_buffer_size);
1561 if (!(vma->vm_flags & (VM_READ | VM_SHARED)) ||
1562 (vma->vm_flags & VM_WRITE)) {
1563 sms_err("invalid vm flags");
1567 if ((end - start) != size) {
1568 sms_err("invalid size %d expected %d",
1569 (int)(end - start), (int)size);
1573 if (remap_pfn_range(vma, start,
1574 coredev->common_buffer_phys >> PAGE_SHIFT,
1575 size, pgprot_noncached(vma->vm_page_prot))) {
1576 sms_err("remap_page_range failed");
1582 #endif /* SMS_HOSTLIB_SUBSYS */
1584 static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1585 u32 *pGroupNum, u32 *pGroupCfg) {
1589 if (PinNum >= 0 && PinNum <= 1) {
1590 *pTranslatedPinNum = 0;
1593 } else if (PinNum >= 2 && PinNum <= 6) {
1594 *pTranslatedPinNum = 2;
1597 } else if (PinNum >= 7 && PinNum <= 11) {
1598 *pTranslatedPinNum = 7;
1600 } else if (PinNum >= 12 && PinNum <= 15) {
1601 *pTranslatedPinNum = 12;
1604 } else if (PinNum == 16) {
1605 *pTranslatedPinNum = 16;
1607 } else if (PinNum >= 17 && PinNum <= 24) {
1608 *pTranslatedPinNum = 17;
1610 } else if (PinNum == 25) {
1611 *pTranslatedPinNum = 25;
1613 } else if (PinNum >= 26 && PinNum <= 28) {
1614 *pTranslatedPinNum = 26;
1616 } else if (PinNum == 29) {
1617 *pTranslatedPinNum = 29;
1620 } else if (PinNum == 30) {
1621 *pTranslatedPinNum = 30;
1623 } else if (PinNum == 31) {
1624 *pTranslatedPinNum = 31;
1634 int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1635 struct smscore_gpio_config *pGpioConfig) {
1638 u32 TranslatedPinNum;
1646 struct SmsMsgHdr_ST xMsgHeader;
1651 if (PinNum > MAX_GPIO_PIN_NUMBER)
1654 if (pGpioConfig == NULL)
1657 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
1659 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1660 GFP_KERNEL | GFP_DMA);
1664 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1666 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1667 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1668 pMsg->xMsgHeader.msgFlags = 0;
1669 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1670 pMsg->msgData[0] = PinNum;
1672 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1673 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1674 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1678 pMsg->msgData[1] = TranslatedPinNum;
1679 pMsg->msgData[2] = GroupNum;
1680 ElectricChar = (pGpioConfig->PullUpDown)
1681 | (pGpioConfig->InputCharacteristics << 2)
1682 | (pGpioConfig->OutputSlewRate << 3)
1683 | (pGpioConfig->OutputDriving << 4);
1684 pMsg->msgData[3] = ElectricChar;
1685 pMsg->msgData[4] = pGpioConfig->Direction;
1686 pMsg->msgData[5] = groupCfg;
1688 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1689 pMsg->msgData[1] = pGpioConfig->PullUpDown;
1690 pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
1691 pMsg->msgData[3] = pGpioConfig->OutputDriving;
1692 pMsg->msgData[4] = pGpioConfig->Direction;
1693 pMsg->msgData[5] = 0;
1696 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1697 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1698 &coredev->gpio_configuration_done);
1702 sms_err("smscore_gpio_configure timeout");
1704 sms_err("smscore_gpio_configure error");
1711 int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
1719 struct SmsMsgHdr_ST xMsgHeader;
1720 u32 msgData[3]; /* keep it 3 ! */
1723 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
1724 (PinNum > MAX_GPIO_PIN_NUMBER))
1727 totalLen = sizeof(struct SmsMsgHdr_ST) +
1728 (3 * sizeof(u32)); /* keep it 3 ! */
1730 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1731 GFP_KERNEL | GFP_DMA);
1735 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1737 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1738 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1739 pMsg->xMsgHeader.msgFlags = 0;
1740 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1741 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1742 pMsg->msgData[0] = PinNum;
1743 pMsg->msgData[1] = NewLevel;
1745 /* Send message to SMS */
1746 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1747 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1748 &coredev->gpio_set_level_done);
1752 sms_err("smscore_gpio_set_level timeout");
1754 sms_err("smscore_gpio_set_level error");
1761 int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
1769 struct SmsMsgHdr_ST xMsgHeader;
1774 if (PinNum > MAX_GPIO_PIN_NUMBER)
1777 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
1779 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1780 GFP_KERNEL | GFP_DMA);
1784 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1786 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1787 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1788 pMsg->xMsgHeader.msgFlags = 0;
1789 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
1790 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1791 pMsg->msgData[0] = PinNum;
1792 pMsg->msgData[1] = 0;
1794 /* Send message to SMS */
1795 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1796 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1797 &coredev->gpio_get_level_done);
1801 sms_err("smscore_gpio_get_level timeout");
1803 sms_err("smscore_gpio_get_level error");
1807 /* Its a race between other gpio_get_level() and the copy of the single
1808 * global 'coredev->gpio_get_res' to the function's variable 'level'
1810 *level = coredev->gpio_get_res;
1818 static int __init smscore_module_init(void)
1822 printk("smsmdtv module init...\n");
1823 sms_info("entering... smscore_module_init....\n");
1824 INIT_LIST_HEAD(&g_smscore_notifyees);
1825 INIT_LIST_HEAD(&g_smscore_devices);
1826 kmutex_init(&g_smscore_deviceslock);
1828 INIT_LIST_HEAD(&g_smscore_registry);
1829 kmutex_init(&g_smscore_registrylock);
1831 //request the gpio used by cmmb
1832 //request_cmmb_gpio();
1833 /* Register sub system adapter objects */
1834 // request_cmmb_gpio();
1836 #ifdef SMS_NET_SUBSYS
1838 rc = smsnet_register();
1840 sms_err("Error registering Siano's network client.\n");
1845 #ifdef SMS_HOSTLIB_SUBSYS
1846 /* Char interface Register */
1847 rc = smschar_register();
1849 sms_err("Error registering Siano's char device client.\n");
1854 #ifdef SMS_DVB3_SUBSYS
1855 /* DVB v.3 Register */
1856 rc = smsdvb_register();
1858 sms_err("Error registering DVB client.\n");
1863 /* Register interfaces objects */
1867 rc = smsusb_register();
1869 sms_err("Error registering USB bus driver.\n");
1870 goto sms_bus_drv_error;
1876 rc = smssdio_register();
1878 sms_err("Error registering SDIO bus driver.\n");
1879 goto sms_bus_drv_error;
1884 #ifdef SMS_SPI_ROCKCHIP
1885 sms_debug(KERN_INFO "smsspi_register\n");
1886 rc = smsspi_register();
1888 sms_err("Error registering Intel PXA310 SPI bus driver.\n");
1889 goto sms_bus_drv_error;
1896 #ifdef SMS_DVB3_SUBSYS
1897 smsdvb_unregister();
1901 #ifdef SMS_HOSTLIB_SUBSYS
1902 smschar_unregister();
1906 #ifdef SMS_NET_SUBSYS
1907 smsnet_unregister();
1911 sms_err("rc %d", rc);
1912 printk(KERN_INFO "%s, rc %d\n", __func__, rc);
1917 static void __exit smscore_module_exit(void)
1922 #ifdef SMS_NET_SUBSYS
1923 /* Net Unregister */
1924 smsnet_unregister();
1927 #ifdef SMS_HOSTLIB_SUBSYS
1928 /* Char interface Unregister */
1929 smschar_unregister();
1932 #ifdef SMS_DVB3_SUBSYS
1933 /* DVB v.3 unregister */
1934 smsdvb_unregister();
1937 /* Unegister interfaces objects */
1939 /* USB unregister */
1940 smsusb_unregister();
1944 /* SDIO unegister */
1945 smssdio_unregister();
1948 #ifdef SMS_SPI_ROCKCHIP
1949 /* Intel PXA310 SPI unegister */
1950 smsspi_unregister();
1953 kmutex_lock(&g_smscore_deviceslock);
1954 while (!list_empty(&g_smscore_notifyees)) {
1955 struct smscore_device_notifyee_t *notifyee =
1956 (struct smscore_device_notifyee_t *)
1957 g_smscore_notifyees.next;
1959 list_del(¬ifyee->entry);
1962 kmutex_unlock(&g_smscore_deviceslock);
1964 kmutex_lock(&g_smscore_registrylock);
1965 while (!list_empty(&g_smscore_registry)) {
1966 struct smscore_registry_entry_t *entry =
1967 (struct smscore_registry_entry_t *)
1968 g_smscore_registry.next;
1970 list_del(&entry->entry);
1973 kmutex_unlock(&g_smscore_registrylock);
1975 // release_cmmb_gpio();
1980 // for loopback test
1983 int AdrLoopbackTest( struct smscore_device_t *coredev )
1986 struct SmsMsgData_ST* pLoopbackMsg = (struct SmsMsgData_ST*)msgbuff;
1987 struct SmsMsgData_ST* pLoopbackRes = (struct SmsMsgData_ST*)g_LbResBuf;
1989 int g_Loopback_failCounters= 0;
1990 int Len = 252 - sizeof(struct SmsMsgData_ST);
1994 pLoopbackMsg->xMsgHeader.msgType = MSG_SMS_LOOPBACK_REQ;
1995 pLoopbackMsg->xMsgHeader.msgSrcId = 151;
1996 pLoopbackMsg->xMsgHeader.msgDstId = 11;
1997 pLoopbackMsg->xMsgHeader.msgFlags = 0;
1998 pLoopbackMsg->xMsgHeader.msgLength = 252;
2000 sms_info("Loobpack test start.");
2003 for ( i = 0 ; i < 1000 ; i++ )
2006 pPtr = (u8*) &pLoopbackMsg->msgData[1];
2007 for ( j = 0 ; j < Len ; j ++ )
2011 pLoopbackMsg->msgData[0] = i+1;
2013 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pLoopbackMsg);
2014 rc = smscore_sendrequest_and_wait(coredev, pLoopbackMsg,
2015 pLoopbackMsg->xMsgHeader.msgLength,
2016 &coredev->loopback_res_done);
2023 pPtr = (u8*) &pLoopbackRes->msgData[1];
2025 for ( j = 0 ; j < Len ; j ++ )
2027 if ( pPtr[j] != (u8)(j + i))
2029 sms_err("Loopback data error at byte %u. Exp %u, Got %u", j, (u8)(j+i), pPtr[j] );
2030 g_Loopback_failCounters++;
2033 } //for ( j = 0 ; j < Len ; j ++ )
2034 } //for ( i = 0 ; i < 100 ; i++ )
2035 sms_info( "Loobpack test end. RUN times: %d; fail times : %d", i, g_Loopback_failCounters);
2040 module_init(smscore_module_init);
2041 module_exit(smscore_module_exit);
2043 MODULE_DESCRIPTION("Siano MDTV Core module");
2044 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
2045 MODULE_LICENSE("GPL");