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>
41 #define MAX_GPIO_PIN_NUMBER 31
43 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
44 //#define REQUEST_FIRMWARE_SUPPORTED
45 #undef REQUEST_FIRMWARE_SUPPORTED
46 //#define DEFAULT_FW_FILE_PATH "/opl/usr/firmware/"
47 #define DEFAULT_FW_FILE_PATH "/etc/firmware/"
49 //#define DEFAULT_FW_FILE_PATH "/lib/firmware"
50 //#define DEFAULT_FW_FILE_PATH "/opl/usr/firmware/"
51 #define DEFAULT_FW_FILE_PATH "/etc/firmware/"
56 int sms_debug =0; //hzb 0526
58 char g_LbResBuf[256]={0};
60 volatile bool g_libdownload = false;
61 module_param_named(debug, sms_debug, int, 0644);
62 MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
64 //static int default_mode = 4;
65 static int default_mode = DEVICE_MODE_CMMB;
68 extern int g_IsTokenEnable;
69 extern int g_IsTokenOwned;
70 extern struct semaphore HalfDuplexSemaphore;
73 module_param(default_mode, int, 0644);
74 MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
76 struct smscore_device_notifyee_t {
77 struct list_head entry;
81 struct smscore_idlist_t {
82 struct list_head entry;
87 struct smscore_client_t {
88 struct list_head entry;
89 struct smscore_device_t *coredev;
91 struct list_head idlist;
92 onresponse_t onresponse_handler;
93 onremove_t onremove_handler;
96 struct smscore_device_t {
97 struct list_head entry;
99 struct list_head clients;
100 struct list_head subclients;
101 spinlock_t clientslock;
103 struct list_head buffers;
104 spinlock_t bufferslock;
108 int common_buffer_size;
109 dma_addr_t common_buffer_phys;
112 struct device *device;
115 unsigned long device_flags;
117 setmode_t setmode_handler;
118 detectmode_t detectmode_handler;
119 sendrequest_t sendrequest_handler;
120 preload_t preload_handler;
121 postload_t postload_handler;
123 int mode, modes_supported;
125 struct completion version_ex_done, data_download_done, trigger_done;
126 struct completion init_device_done, reload_start_done, resume_done;
127 struct completion gpio_configuration_done, gpio_set_level_done;
128 struct completion gpio_get_level_done;
130 struct completion loopback_res_done;
139 wait_queue_head_t buffer_mng_waitq;
146 static struct smscore_device_t* panic_core_dev = NULL ;
148 void smscore_panic_print(void)
152 printk("common_buffer_size = [0x%x]\n", panic_core_dev-> common_buffer_size) ;
153 printk("common_buffer start addr= [0x%x]\n",(unsigned int) panic_core_dev->common_buffer ) ;
154 printk("common_buffer end addr= [0x%x]\n",
155 (unsigned int) (panic_core_dev->common_buffer + panic_core_dev-> common_buffer_size -1)) ;
156 printk("common_buffer_phys start addr = [0x%x]\n",(unsigned int) panic_core_dev->common_buffer_phys) ;
157 printk("common_buffer_phys end addr = [0x%x]\n",
158 (unsigned int) ( panic_core_dev->common_buffer_phys+ panic_core_dev-> common_buffer_size -1)) ;
165 int AdrLoopbackTest( struct smscore_device_t *coredev );
167 void smscore_set_board_id(struct smscore_device_t *core, int id)
172 int smscore_get_board_id(struct smscore_device_t *core)
174 return core->board_id;
177 struct smscore_registry_entry_t {
178 struct list_head entry;
181 enum sms_device_type_st type;
184 static struct list_head g_smscore_notifyees;
185 static struct list_head g_smscore_devices;
186 static struct mutex g_smscore_deviceslock;
187 static struct list_head g_smscore_registry;
188 static struct mutex g_smscore_registrylock;
190 static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
192 struct smscore_registry_entry_t *entry;
193 struct list_head *next;
195 kmutex_lock(&g_smscore_registrylock);
196 for (next = g_smscore_registry.next; next != &g_smscore_registry; next
198 entry = (struct smscore_registry_entry_t *) next;
199 if (!strcmp(entry->devpath, devpath)) {
200 kmutex_unlock(&g_smscore_registrylock);
204 entry = /* (struct smscore_registry_entry_t *) */kmalloc(
205 sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
207 entry->mode = default_mode;
208 if(strlen(devpath) >= 32)
210 sms_err(" strlen(devpath) >= 32\n");
213 strcpy(entry->devpath, devpath);
214 list_add(&entry->entry, &g_smscore_registry);
216 sms_err("failed to create smscore_registry.");
217 kmutex_unlock(&g_smscore_registrylock);
221 int smscore_registry_getmode(char *devpath)
223 struct smscore_registry_entry_t *entry;
225 entry = smscore_find_registry(devpath);
229 sms_err("No registry found.");
234 static enum sms_device_type_st smscore_registry_gettype(char *devpath)
236 struct smscore_registry_entry_t *entry;
238 entry = smscore_find_registry(devpath);
242 sms_err("No registry found.");
247 void smscore_registry_setmode(char *devpath, int mode)
249 struct smscore_registry_entry_t *entry;
251 entry = smscore_find_registry(devpath);
255 sms_err("No registry found.");
258 static void smscore_registry_settype(char *devpath,
259 enum sms_device_type_st type) {
260 struct smscore_registry_entry_t *entry;
262 entry = smscore_find_registry(devpath);
266 sms_err("No registry found.");
269 static void list_add_locked(struct list_head *new, struct list_head *head,
273 spin_lock_irqsave(lock, flags);
275 spin_unlock_irqrestore(lock, flags);
279 * register a client callback that called when device plugged in/unplugged
280 * NOTE: if devices exist callback is called immediately for each device
282 * @param hotplug callback
284 * @return 0 on success, <0 on error.
286 int smscore_register_hotplug(hotplug_t hotplug)
288 struct smscore_device_notifyee_t *notifyee;
289 struct list_head *next, *first;
292 sms_info(" entering... smscore_register_hotplug \n");
293 kmutex_lock(&g_smscore_deviceslock);
295 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
298 /* now notify callback about existing devices */
299 first = &g_smscore_devices;
300 for (next = first->next; next != first && !rc;
302 struct smscore_device_t *coredev =
303 (struct smscore_device_t *) next;
304 rc = hotplug(coredev, coredev->device, 1);
308 notifyee->hotplug = hotplug;
309 list_add(¬ifyee->entry, &g_smscore_notifyees);
315 kmutex_unlock(&g_smscore_deviceslock);
321 * unregister a client callback that called when device plugged in/unplugged
323 * @param hotplug callback
326 void smscore_unregister_hotplug(hotplug_t hotplug)
328 struct list_head *next, *first;
330 kmutex_lock(&g_smscore_deviceslock);
332 first = &g_smscore_notifyees;
334 for (next = first->next; next != first;) {
335 struct smscore_device_notifyee_t *notifyee =
336 (struct smscore_device_notifyee_t *) next;
339 if (notifyee->hotplug == hotplug) {
340 list_del(¬ifyee->entry);
345 kmutex_unlock(&g_smscore_deviceslock);
348 static void smscore_notify_clients(struct smscore_device_t *coredev)
350 struct smscore_client_t *client;
352 /* the client must call smscore_unregister_client from remove handler */
353 while (!list_empty(&coredev->clients)) {
354 client = (struct smscore_client_t *) coredev->clients.next;
355 client->onremove_handler(client->context);
359 static int smscore_notify_callbacks(struct smscore_device_t *coredev,
360 struct device *device, int arrival) {
361 struct list_head *next, *first;
364 /* note: must be called under g_deviceslock */
366 first = &g_smscore_notifyees;
368 for (next = first->next; next != first; next = next->next) {
369 rc = ((struct smscore_device_notifyee_t *) next)->
370 hotplug(coredev, device, arrival);
378 static struct smscore_buffer_t *smscore_createbuffer(u8 *buffer,
379 void *common_buffer, dma_addr_t common_buffer_phys) {
380 struct smscore_buffer_t *cb = kmalloc(sizeof(struct smscore_buffer_t),
383 sms_info("kmalloc(...) failed");
388 cb->offset_in_common = buffer - (u8 *) common_buffer;
389 cb->phys = common_buffer_phys + cb->offset_in_common;
395 * creates coredev object for a device, prepares buffers,
396 * creates buffer mappings, notifies registered hotplugs about new device.
398 * @param params device pointer to struct with device specific parameters
400 * @param coredev pointer to a value that receives created coredev object
402 * @return 0 on success, <0 on error.
404 int smscore_register_device(struct smsdevice_params_t *params,
405 struct smscore_device_t **coredev) {
406 struct smscore_device_t *dev;
409 sms_info(" entering....smscore_register_device \n");
410 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
412 sms_info("kzalloc(...) failed");
416 /* init list entry so it could be safe in smscore_unregister_device */
417 INIT_LIST_HEAD(&dev->entry);
420 INIT_LIST_HEAD(&dev->clients);
421 INIT_LIST_HEAD(&dev->buffers);
424 spin_lock_init(&dev->clientslock);
425 spin_lock_init(&dev->bufferslock);
427 /* init completion events */
428 init_completion(&dev->version_ex_done);
429 init_completion(&dev->data_download_done);
430 init_completion(&dev->trigger_done);
431 init_completion(&dev->init_device_done);
432 init_completion(&dev->reload_start_done);
433 init_completion(&dev->resume_done);
434 init_completion(&dev->gpio_configuration_done);
435 init_completion(&dev->gpio_set_level_done);
436 init_completion(&dev->gpio_get_level_done);
438 init_completion(&dev->loopback_res_done);
439 init_waitqueue_head(&dev->buffer_mng_waitq);
441 /* alloc common buffer */
442 sms_info(" entering...alloc common buffer \n");
443 dev->common_buffer_size = params->buffer_size * params->num_buffers;
445 dev->common_buffer = kmalloc(dev->common_buffer_size, GFP_KERNEL|GFP_DMA);
446 dev->common_buffer_phys = __pa(dev->common_buffer);
447 sms_debug("dev->common_buffer_phys=0x%x",dev->common_buffer_phys);
449 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
450 &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA);
453 if (!dev->common_buffer) {
454 smscore_unregister_device(dev);
459 /* prepare dma buffers */
460 sms_info(" entering...prepare dma buffers \n");
463 for (buffer = dev->common_buffer ; dev->num_buffers <
464 params->num_buffers ; dev->num_buffers++, buffer
465 += params->buffer_size) {
466 struct smscore_buffer_t *cb = smscore_createbuffer(buffer,
467 dev->common_buffer, dev->common_buffer_phys);
469 smscore_unregister_device(dev);
473 smscore_putbuffer(dev, cb);
476 sms_info("allocated %d buffers", dev->num_buffers);
478 dev->mode = DEVICE_MODE_NONE;
479 dev->context = params->context;
480 dev->device = params->device;
481 dev->setmode_handler = params->setmode_handler;
482 dev->detectmode_handler = params->detectmode_handler;
483 dev->sendrequest_handler = params->sendrequest_handler;
484 dev->preload_handler = params->preload_handler;
485 dev->postload_handler = params->postload_handler;
487 dev->device_flags = params->flags;
488 strcpy(dev->devpath, params->devpath);
490 smscore_registry_settype(dev->devpath, params->device_type);
492 /* add device to devices list */
493 kmutex_lock(&g_smscore_deviceslock);
494 list_add(&dev->entry, &g_smscore_devices);
495 kmutex_unlock(&g_smscore_deviceslock);
498 panic_core_dev = dev ;
499 sms_info("device %p created", dev);
505 * sets initial device mode and notifies client hotplugs that device is ready
507 * @param coredev pointer to a coredev object returned by
508 * smscore_register_device
510 * @return 0 on success, <0 on error.
512 int smscore_start_device(struct smscore_device_t *coredev)
516 #ifdef REQUEST_FIRMWARE_SUPPORTED
517 rc = smscore_set_device_mode(coredev, smscore_registry_getmode(
520 sms_info("set device mode faile , rc %d", rc);
525 kmutex_lock(&g_smscore_deviceslock);
527 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
529 sms_info("device %p started, rc %d", coredev, rc);
531 kmutex_unlock(&g_smscore_deviceslock);
536 static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
537 void *buffer, size_t size, struct completion *completion) {
538 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
540 sms_info("sendrequest returned error %d", rc);
544 return wait_for_completion_timeout(completion,
545 msecs_to_jiffies(30000)) ? 0 : -ETIME;//10000
548 static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
549 void *buffer, size_t size) {
550 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
551 struct SmsMsgHdr_ST *msg;
553 u8 *payload = firmware->Payload;
556 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
557 firmware->Length = le32_to_cpu(firmware->Length);
559 mem_address = firmware->StartAddress;
561 sms_info("loading FW to addr 0x%x size %d",
562 mem_address, firmware->Length);
563 if (coredev->preload_handler) {
564 rc = coredev->preload_handler(coredev->context);
567 sms_err("sms preload handler fail !!!");
572 sms_info("preload handle after");
575 /* PAGE_SIZE buffer shall be enough and dma aligned */
576 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
580 //while (1)//hzb test 0527
583 //if (coredev->mode != DEVICE_MODE_NONE) //hzb test 0527
585 sms_info("sending MSG_SMS_GET_VERSION_EX_REQ command.");
586 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
587 sizeof(struct SmsMsgHdr_ST));
588 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
589 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
590 &coredev->version_ex_done);
591 // mem_address = *(u32 *) &payload[20];
592 sms_info("sms get version req ret=0x%x",rc);
597 g_libdownload = true;
600 while (size && rc >= 0) {
601 struct SmsDataDownload_ST *DataMsg =
602 (struct SmsDataDownload_ST *) msg;
603 int payload_size = min((int)size, SMS_MAX_PAYLOAD_SIZE);
605 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
606 (u16) (sizeof(struct SmsMsgHdr_ST) +
607 sizeof(u32) + payload_size));
609 DataMsg->MemAddr = mem_address;
610 memcpy(DataMsg->Payload, payload, payload_size);
612 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
613 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
614 (coredev->mode == DEVICE_MODE_NONE))
615 rc = coredev->sendrequest_handler(coredev->context,DataMsg,DataMsg->xMsgHeader.msgLength);
619 // complete(&coredev->data_download_done);
621 // g_libdownload = false;
624 rc = smscore_sendrequest_and_wait(coredev, DataMsg,DataMsg->xMsgHeader.msgLength,&coredev->data_download_done);
626 payload += payload_size;
627 size -= payload_size;
628 mem_address += payload_size;
630 sms_debug("size=%d \n", size);
633 sms_info("transfer over!!!!!!!!!!!!!!!!!!\n");
636 complete(&coredev->data_download_done);
638 g_libdownload = false;
640 // ¼ÓÈëÑÓʱ£¬·ÀÖ¹³õʼ»¯Ê§°Ü£¬ZYC
642 //printk("firmware is downloaded\n!!!!");
645 sms_info("firmware is loaded over 1111111111\n");
646 if (coredev->mode == DEVICE_MODE_NONE) {
647 struct SmsMsgData_ST *TriggerMsg =
648 (struct SmsMsgData_ST *) msg;
650 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
651 sizeof(struct SmsMsgHdr_ST) +
654 TriggerMsg->msgData[0] = firmware->StartAddress;
656 TriggerMsg->msgData[1] = 5; /* Priority */
657 TriggerMsg->msgData[2] = 0x200; /* Stack size */
658 TriggerMsg->msgData[3] = 0; /* Parameter */
659 TriggerMsg->msgData[4] = 4; /* Task ID */
661 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
662 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
664 sms_info("firmware is loaded over , but no response,222222222\n");
665 rc = coredev->sendrequest_handler(coredev->
667 TriggerMsg->xMsgHeader.msgLength);
670 rc = smscore_sendrequest_and_wait(coredev,
672 TriggerMsg->xMsgHeader.msgLength,
673 &coredev->trigger_done);
675 sms_info("firmware is loaded over , but mode is none,333333333333\n");
677 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
678 sizeof(struct SmsMsgHdr_ST));
679 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
680 rc = coredev->sendrequest_handler(coredev->context, msg,
687 sms_info("firmware is not loaded over , it is wrong,4444444444444\n");
689 sms_debug("rc=%d, postload=%p ", rc, coredev->postload_handler);
693 return ((rc >= 0) && coredev->postload_handler) ?
694 coredev->postload_handler(coredev->context) : rc;
698 * loads specified firmware into a buffer and calls device loadfirmware_handler
700 * @param coredev pointer to a coredev object returned by
701 * smscore_register_device
702 * @param filename null-terminated string specifies firmware file name
703 * @param loadfirmware_handler device handler that loads firmware
705 * @return 0 on success, <0 on error.
707 static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
708 char *filename, loadfirmware_t loadfirmware_handler) {
713 #ifdef REQUEST_FIRMWARE_SUPPORTED
714 const struct firmware *fw;
716 if (loadfirmware_handler == NULL && !(coredev->device_flags
717 & SMS_DEVICE_FAMILY2))
720 rc = request_firmware(&fw, filename, coredev->device);
722 sms_info("failed to open \"%s\"", filename);
725 sms_info("read FW %s, size=%zd", filename, fw->size);
726 fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
727 GFP_KERNEL | GFP_DMA);
729 sms_info("failed to allocate firmware buffer");
732 memcpy(fw_buf, fw->data, fw->size);
733 fw_buf_size = fw->size;
735 if (!coredev->fw_buf) {
736 sms_info("missing fw file buffer");
739 fw_buf = coredev->fw_buf;
740 fw_buf_size = coredev->fw_buf_size;
742 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
743 smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
744 : /*loadfirmware_handler(coredev->context, fw_buf,
745 fw_buf_size);*/printk(" error - should not be here\n");
748 #ifdef REQUEST_FIRMWARE_SUPPORTED
749 release_firmware(fw);
751 coredev->fw_buf = NULL;
752 coredev->fw_buf_size = 0;
758 * notifies all clients registered with the device, notifies hotplugs,
759 * frees all buffers and coredev object
761 * @param coredev pointer to a coredev object returned by
762 * smscore_register_device
764 * @return 0 on success, <0 on error.
766 void smscore_unregister_device(struct smscore_device_t *coredev)
768 struct smscore_buffer_t *cb;
772 kmutex_lock(&g_smscore_deviceslock);
774 smscore_notify_clients(coredev);
775 smscore_notify_callbacks(coredev, NULL, 0);
777 /* at this point all buffers should be back
778 * onresponse must no longer be called */
781 while(!list_empty(&coredev->buffers))
783 cb = (struct smscore_buffer_t *) coredev->buffers.next;
784 list_del(&cb->entry);
788 if (num_buffers == coredev->num_buffers )
791 sms_info("exiting although "
792 "not all buffers released.");
796 sms_info("waiting for %d buffer(s)",
797 coredev->num_buffers - num_buffers);
801 sms_info("freed %d buffers", num_buffers);
803 if(coredev->common_buffer)
806 kfree(coredev->common_buffer);
808 dma_free_coherent(NULL, coredev->common_buffer_size,coredev->common_buffer, coredev->common_buffer_phys);
811 if (coredev->fw_buf != NULL)
812 kfree(coredev->fw_buf);
814 list_del(&coredev->entry);
816 panic_core_dev = NULL ;
817 kmutex_unlock(&g_smscore_deviceslock);
819 sms_info("device %p destroyed", coredev);
822 static int smscore_detect_mode(struct smscore_device_t *coredev)
824 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
825 GFP_KERNEL | GFP_DMA);
826 struct SmsMsgHdr_ST *msg =
827 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
833 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
834 sizeof(struct SmsMsgHdr_ST));
836 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
837 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
838 &coredev->version_ex_done);
840 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
842 if (wait_for_completion_timeout(&coredev->resume_done,
843 msecs_to_jiffies(5000))) {
844 rc = smscore_sendrequest_and_wait(coredev, msg,
845 msg->msgLength, &coredev->version_ex_done);
847 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
848 "second try, rc %d", rc);
858 static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
859 /*Stellar NOVA A0 Nova B0 VEGA */
861 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
863 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
865 { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none" },
866 /*DABIP*/{ "none", "none", "none", "none" },
868 { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none" },
870 { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none" },
872 { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none" },
873 /*CMMB*/{ "none", "none", "none", "cmmb_vega_12mhz.inp" } };
875 static inline char *sms_get_fw_name(struct smscore_device_t *coredev, int mode,
876 enum sms_device_type_st type) {
877 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
878 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
882 int smscore_reset_device_drvs(struct smscore_device_t *coredev)
886 sms_debug("currnet device mode to %d", coredev->mode);
887 coredev->mode = DEVICE_MODE_NONE;
888 coredev->device_flags = SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY |
896 * calls device handler to change mode of operation
897 * NOTE: stellar/usb may disconnect when changing mode
899 * @param coredev pointer to a coredev object returned by
900 * smscore_register_device
901 * @param mode requested mode of operation
903 * @return 0 on success, <0 on error.
905 int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
909 enum sms_device_type_st type;
912 sms_info("set device mode to %d", mode);
913 //sms_debug("current device mode, device flags, modes_supported to %d", coredev->mode, coredev->device_flags, coredev->modes_supported);
915 sms_debug("set device mode to %d", mode);
916 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
917 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
918 sms_err("invalid mode specified %d", mode);
922 smscore_registry_setmode(coredev->devpath, mode);
924 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
925 rc = smscore_detect_mode(coredev);
927 sms_err("mode detect failed %d", rc);
932 if (coredev->mode == mode) {
933 sms_info("device mode %d already set", mode);
937 if (!(coredev->modes_supported & (1 << mode))) {
940 type = smscore_registry_gettype(coredev->devpath);
941 fw_filename = sms_get_fw_name(coredev, mode, type);
943 if(NULL == fw_filename)
945 sms_err("wrong filename");
949 rc = smscore_load_firmware_from_file(coredev,
952 sms_warn("error %d loading firmware: %s, "
953 "trying again with default firmware",
956 /* try again with the default firmware */
957 fw_filename = smscore_fw_lkup[mode][type];
958 rc = smscore_load_firmware_from_file(coredev,
962 sms_warn("error %d loading "
968 sms_info("firmware download success: %s", fw_filename);
970 sms_info("mode %d supported by running "
973 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
974 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
976 struct SmsMsgData_ST *msg =
977 (struct SmsMsgData_ST *)
978 SMS_ALIGN_ADDRESS(buffer);
980 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
981 sizeof(struct SmsMsgData_ST));
982 msg->msgData[0] = mode;
986 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
987 rc = smscore_sendrequest_and_wait(coredev, msg,
988 msg->xMsgHeader.msgLength,
989 &coredev->init_device_done);
990 sms_info("send MSG_SMS_INIT_DEVICE_REQ res = %d\n ",rc);
993 sms_err("Could not allocate buffer for "
994 "init device message.");
998 // start to do loopback test
999 // rc = AdrLoopbackTest(coredev);
1003 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
1004 sms_err("invalid mode specified %d", mode);
1008 smscore_registry_setmode(coredev->devpath, mode);
1010 if (coredev->detectmode_handler)
1011 coredev->detectmode_handler(coredev->context,
1014 if (coredev->mode != mode && coredev->setmode_handler)
1015 rc = coredev->setmode_handler(coredev->context, mode);
1019 sms_info("device is ready");
1021 struct SmsMsgHdr_ST *msg;
1023 msg = kmalloc(sizeof(struct SmsMsgHdr_ST), GFP_KERNEL | GFP_DMA);
1025 sms_debug("sending MSG_SMS_GET_VERSION_EX_REQ command.");
1026 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,sizeof(struct SmsMsgHdr_ST));
1027 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)msg);
1028 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done);
1031 #if SIANO_HALFDUPLEX
1032 g_IsTokenEnable = true;
1033 g_IsTokenOwned = true;
1034 up(&HalfDuplexSemaphore);
1035 sms_debug("g_IsTokenEnable = true \n");
1037 coredev->mode = mode;
1038 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
1042 sms_err("return error code %d.", rc);
1047 * calls device handler to get fw file name
1049 * @param coredev pointer to a coredev object returned by
1050 * smscore_register_device
1051 * @param filename pointer to user buffer to fill the file name
1053 * @return 0 on success, <0 on error.
1055 int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode,
1058 enum sms_device_type_st type;
1061 type = smscore_registry_gettype(coredev->devpath);
1063 #ifdef REQUEST_FIRMWARE_SUPPORTED
1064 /* driver not need file system services */
1067 sprintf(tmpname, "%s/%s", DEFAULT_FW_FILE_PATH,
1068 smscore_fw_lkup[mode][type]);
1070 if (copy_to_user(filename, tmpname, strlen(tmpname) + 1)) {
1071 sms_err("Failed copy file path to user buffer\n");
1078 * calls device handler to keep fw buff for later use
1080 * @param coredev pointer to a coredev object returned by
1081 * smscore_register_device
1082 * @param ufwbuf pointer to user fw buffer
1083 * @param size size in bytes of buffer
1085 * @return 0 on success, <0 on error.
1087 int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf,
1091 /* free old buffer */
1092 if (coredev->fw_buf != NULL) {
1093 kfree(coredev->fw_buf);
1094 coredev->fw_buf = NULL;
1097 coredev->fw_buf = kmalloc(ALIGN(size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA);
1098 if (!coredev->fw_buf) {
1099 sms_err("Failed allocate FW buffer memory\n");
1103 if (copy_from_user(coredev->fw_buf, ufwbuf, size)) {
1104 sms_err("Failed copy FW from user buffer\n");
1105 kfree(coredev->fw_buf);
1108 coredev->fw_buf_size = size;
1114 * calls device handler to get current mode of operation
1116 * @param coredev pointer to a coredev object returned by
1117 * smscore_register_device
1119 * @return current mode
1121 int smscore_get_device_mode(struct smscore_device_t *coredev)
1123 return coredev->mode;
1127 * find client by response id & type within the clients list.
1128 * return client handle or NULL.
1130 * @param coredev pointer to a coredev object returned by
1131 * smscore_register_device
1132 * @param data_type client data type (SMS_DONT_CARE for all types)
1133 * @param id client id (SMS_DONT_CARE for all id)
1136 static struct smscore_client_t *smscore_find_client(
1137 struct smscore_device_t *coredev, int data_type, int id) {
1138 struct smscore_client_t *client = NULL;
1139 struct list_head *next, *first;
1140 unsigned long flags;
1141 struct list_head *firstid, *nextid;
1143 spin_lock_irqsave(&coredev->clientslock, flags);
1144 first = &coredev->clients;
1145 for (next = first->next; (next != first) && !client;
1146 next = next->next) {
1147 firstid = &((struct smscore_client_t *) next)->idlist;
1148 for (nextid = firstid->next; nextid != firstid;
1149 nextid = nextid->next) {
1150 if ((((struct smscore_idlist_t *) nextid)->id == id)
1151 && (((struct smscore_idlist_t *)
1154 || (((struct smscore_idlist_t *)
1155 nextid)->data_type == 0))) {
1156 client = (struct smscore_client_t *) next;
1161 spin_unlock_irqrestore(&coredev->clientslock, flags);
1166 * find client by response id/type, call clients onresponse handler
1167 * return buffer to pool on error
1169 * @param coredev pointer to a coredev object returned by
1170 * smscore_register_device
1171 * @param cb pointer to response buffer descriptor
1174 void smscore_onresponse(struct smscore_device_t *coredev,
1175 struct smscore_buffer_t *cb) {
1176 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
1178 struct smscore_client_t *client = smscore_find_client(coredev,
1179 phdr->msgType, phdr->msgDstId);
1182 static unsigned long last_sample_time; /* = 0; */
1183 static int data_total; /* = 0; */
1184 unsigned long time_now = jiffies_to_msecs(jiffies);
1186 if (!last_sample_time)
1187 last_sample_time = time_now;
1189 if (time_now - last_sample_time > 10000) {
1190 sms_debug("\ndata rate %d bytes/secs",
1191 (int)((data_total * 1000) /
1192 (time_now - last_sample_time)));
1194 last_sample_time = time_now;
1199 data_total += cb->size;
1200 /* If no client registered for type & id,
1201 * check for control client where type is not registered */
1205 sms_debug("client=0x %x\n", client);
1206 rc = client->onresponse_handler(client->context, cb);
1208 sms_debug("onresponse_handler ret = 0x%x\n", rc);
1209 sms_debug("phdr->msgType %d\n", phdr->msgType);
1210 #if SIANO_HALFDUPLEX
1211 if (phdr->msgType==MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST){
1212 g_IsTokenOwned = true;
1213 sms_debug("MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST \n");
1218 smsendian_handle_rx_message((struct SmsMsgData_ST *)phdr);
1220 switch (phdr->msgType) {
1221 case MSG_SMS_GET_VERSION_EX_RES: {
1222 struct SmsVersionRes_ST *ver = (struct SmsVersionRes_ST *) phdr;
1224 sms_debug("MSG_SMS_GET_VERSION_EX_RES "
1225 "id %d prots 0x%x ver %d.%d",
1227 ver->SupportedProtocols,
1228 ver->RomVersionMajor,
1229 ver->RomVersionMinor);
1231 printk("MSG_SMS_GET_VERSION_EX_RES "
1232 "id %d prots 0x%x ver %d.%d\n",
1234 ver->SupportedProtocols,
1235 ver->RomVersionMajor,
1236 ver->RomVersionMinor);
1238 ver->TextLabel[33] = 0x0;
1240 printk("fw version is %s\n",ver->TextLabel);
1242 coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId;
1243 coredev->modes_supported = ver->SupportedProtocols;
1245 complete(&coredev->version_ex_done);
1248 case MSG_SMS_INIT_DEVICE_RES:
1249 sms_debug("MSG_SMS_INIT_DEVICE_RES");
1250 complete(&coredev->init_device_done);
1252 case MSG_SW_RELOAD_START_RES:
1253 sms_debug("MSG_SW_RELOAD_START_RES");
1254 complete(&coredev->reload_start_done);
1256 case MSG_SMS_DATA_DOWNLOAD_RES:
1257 complete(&coredev->data_download_done);
1259 case MSG_SW_RELOAD_EXEC_RES:
1260 sms_debug("MSG_SW_RELOAD_EXEC_RES");
1262 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
1263 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
1264 complete(&coredev->trigger_done);
1266 case MSG_SMS_SLEEP_RESUME_COMP_IND:
1267 complete(&coredev->resume_done);
1269 case MSG_SMS_GPIO_CONFIG_EX_RES:
1270 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
1271 complete(&coredev->gpio_configuration_done);
1273 case MSG_SMS_GPIO_SET_LEVEL_RES:
1274 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
1275 complete(&coredev->gpio_set_level_done);
1277 case MSG_SMS_GPIO_GET_LEVEL_RES:
1279 u32 *msgdata = (u32 *) phdr;
1280 coredev->gpio_get_res = msgdata[1];
1281 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", coredev->gpio_get_res);
1282 complete(&coredev->gpio_get_level_done);
1286 // loopback in the drv
1288 case MSG_SMS_LOOPBACK_RES:
1290 //u32 *msgdata = (u32 *) phdr;
1291 memcpy( g_LbResBuf, (u8 *)phdr, phdr->msgLength );
1292 sms_debug("MSG_SMS_LOOPBACK_RES \n");
1293 complete(&coredev->loopback_res_done);
1299 sms_info("no client (%p) or error (%d), "
1300 "type:%d dstid:%d", client, rc,
1301 phdr->msgType, phdr->msgDstId);
1306 smscore_putbuffer(coredev, cb);
1307 //sms_debug("after putbuffer \n");
1314 * return pointer to next free buffer descriptor from core pool
1316 * @param coredev pointer to a coredev object returned by
1317 * smscore_register_device
1319 * @return pointer to descriptor on success, NULL on error.
1321 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1323 struct smscore_buffer_t *cb = NULL;
1324 unsigned long flags;
1328 spin_lock_irqsave(&coredev->bufferslock, flags);
1330 /* This function must return a valid buffer, since the buffer list is
1331 * finite, we check that there is an available buffer, if not, we wait
1332 * until such buffer become available.
1335 prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
1337 if (list_empty(&coredev->buffers))
1339 //to avoid rx buffers hung
1340 printk("eladr: smscore_getbuffer scheduled caus list is empty\n");
1341 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1343 spin_lock_irqsave(&coredev->bufferslock, flags);
1346 //printk("smscore_getbuffer call finish_wait\n");
1347 finish_wait(&coredev->buffer_mng_waitq, &wait);
1349 // if list is still empty we will return null
1350 if (list_empty(&coredev->buffers))
1353 printk("eladr: smscore_getbuffer fail to allocate buffer, returning null \n");
1357 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1358 if(cb->entry.prev==LIST_POISON1 || cb->entry.next==LIST_POISON1 || cb->entry.prev==LIST_POISON2 || cb->entry.next==LIST_POISON2 )
1360 printk("smscore_getbuffer list is no good\n");
1361 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1365 //printk("smscore_getbuffer buffer was allocated cb=0x%x\n", cb);
1366 list_del(&cb->entry);
1369 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1375 * return buffer descriptor to a pool
1377 * @param coredev pointer to a coredev object returned by
1378 * smscore_register_device
1379 * @param cb pointer buffer descriptor
1382 void smscore_putbuffer(struct smscore_device_t *coredev,
1383 struct smscore_buffer_t *cb) {
1384 wake_up_interruptible(&coredev->buffer_mng_waitq);
1385 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1388 static int smscore_validate_client(struct smscore_device_t *coredev,
1389 struct smscore_client_t *client, int data_type, int id) {
1390 struct smscore_idlist_t *listentry;
1391 struct smscore_client_t *registered_client;
1394 sms_err("bad parameter.");
1397 registered_client = smscore_find_client(coredev, data_type, id);
1398 if (registered_client == client)
1401 if (registered_client) {
1402 sms_err("The msg ID already registered to another client.");
1405 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
1407 sms_err("Can't allocate memory for client id.");
1411 listentry->data_type = data_type;
1412 list_add_locked(&listentry->entry, &client->idlist,
1413 &coredev->clientslock);
1418 * creates smsclient object, check that id is taken by another client
1420 * @param coredev pointer to a coredev object from clients hotplug
1421 * @param initial_id all messages with this id would be sent to this client
1422 * @param data_type all messages of this type would be sent to this client
1423 * @param onresponse_handler client handler that is called to
1424 * process incoming messages
1425 * @param onremove_handler client handler that is called when device is removed
1426 * @param context client-specific context
1427 * @param client pointer to a value that receives created smsclient object
1429 * @return 0 on success, <0 on error.
1431 int smscore_register_client(struct smscore_device_t *coredev,
1432 struct smsclient_params_t *params,
1433 struct smscore_client_t **client) {
1434 struct smscore_client_t *newclient;
1436 /* check that no other channel with same parameters exists */
1438 sms_info("entering....smscore_register_client \n");
1440 if (smscore_find_client(coredev, params->data_type, params->initial_id)) {
1441 sms_err("Client already exist.");
1445 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
1447 sms_err("Failed to allocate memory for client.");
1451 INIT_LIST_HEAD(&newclient->idlist);
1452 newclient->coredev = coredev;
1453 newclient->onresponse_handler = params->onresponse_handler;
1454 newclient->onremove_handler = params->onremove_handler;
1455 newclient->context = params->context;
1456 list_add_locked(&newclient->entry, &coredev->clients,&coredev->clientslock);
1457 smscore_validate_client(coredev, newclient, params->data_type,params->initial_id);
1458 *client = newclient;
1459 sms_debug("Register new client %p DT=%d ID=%d",
1460 params->context, params->data_type, params->initial_id);
1466 * frees smsclient object and all subclients associated with it
1468 * @param client pointer to smsclient object returned by
1469 * smscore_register_client
1472 void smscore_unregister_client(struct smscore_client_t *client)
1474 struct smscore_device_t *coredev = client->coredev;
1475 unsigned long flags;
1477 spin_lock_irqsave(&coredev->clientslock, flags);
1479 while (!list_empty(&client->idlist)) {
1480 struct smscore_idlist_t *identry =
1481 (struct smscore_idlist_t *) client->idlist.next;
1482 list_del(&identry->entry);
1486 sms_info("%p", client->context);
1488 list_del(&client->entry);
1491 spin_unlock_irqrestore(&coredev->clientslock, flags);
1495 * verifies that source id is not taken by another client,
1496 * calls device handler to send requests to the device
1498 * @param client pointer to smsclient object returned by
1499 * smscore_register_client
1500 * @param buffer pointer to a request buffer
1501 * @param size size (in bytes) of request buffer
1503 * @return 0 on success, <0 on error.
1505 int smsclient_sendrequest(struct smscore_client_t *client, void *buffer,
1507 struct smscore_device_t *coredev;
1508 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
1511 if (client == NULL) {
1512 sms_err("Got NULL client");
1516 coredev = client->coredev;
1518 /* check that no other channel with same id exists */
1519 if (coredev == NULL) {
1520 sms_err("Got NULL coredev");
1524 rc = smscore_validate_client(client->coredev, client, 0,
1529 return coredev->sendrequest_handler(coredev->context, buffer, size);
1532 #ifdef SMS_HOSTLIB_SUBSYS
1534 * return the size of large (common) buffer
1536 * @param coredev pointer to a coredev object from clients hotplug
1538 * @return size (in bytes) of the buffer
1540 int smscore_get_common_buffer_size(struct smscore_device_t *coredev)
1542 return coredev->common_buffer_size;
1546 * maps common buffer (if supported by platform)
1548 * @param coredev pointer to a coredev object from clients hotplug
1549 * @param vma pointer to vma struct from mmap handler
1551 * @return 0 on success, <0 on error.
1553 int smscore_map_common_buffer(struct smscore_device_t *coredev,
1554 struct vm_area_struct *vma)
1556 unsigned long end = vma->vm_end,
1557 start = vma->vm_start,
1558 size = PAGE_ALIGN(coredev->common_buffer_size);
1560 if (!(vma->vm_flags & (VM_READ | VM_SHARED)) ||
1561 (vma->vm_flags & VM_WRITE)) {
1562 sms_err("invalid vm flags");
1566 if ((end - start) != size) {
1567 sms_err("invalid size %d expected %d",
1568 (int)(end - start), (int)size);
1572 if (remap_pfn_range(vma, start,
1573 coredev->common_buffer_phys >> PAGE_SHIFT,
1574 size, pgprot_noncached(vma->vm_page_prot))) {
1575 sms_err("remap_page_range failed");
1581 #endif /* SMS_HOSTLIB_SUBSYS */
1583 static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1584 u32 *pGroupNum, u32 *pGroupCfg) {
1588 if (PinNum >= 0 && PinNum <= 1) {
1589 *pTranslatedPinNum = 0;
1592 } else if (PinNum >= 2 && PinNum <= 6) {
1593 *pTranslatedPinNum = 2;
1596 } else if (PinNum >= 7 && PinNum <= 11) {
1597 *pTranslatedPinNum = 7;
1599 } else if (PinNum >= 12 && PinNum <= 15) {
1600 *pTranslatedPinNum = 12;
1603 } else if (PinNum == 16) {
1604 *pTranslatedPinNum = 16;
1606 } else if (PinNum >= 17 && PinNum <= 24) {
1607 *pTranslatedPinNum = 17;
1609 } else if (PinNum == 25) {
1610 *pTranslatedPinNum = 25;
1612 } else if (PinNum >= 26 && PinNum <= 28) {
1613 *pTranslatedPinNum = 26;
1615 } else if (PinNum == 29) {
1616 *pTranslatedPinNum = 29;
1619 } else if (PinNum == 30) {
1620 *pTranslatedPinNum = 30;
1622 } else if (PinNum == 31) {
1623 *pTranslatedPinNum = 31;
1633 int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1634 struct smscore_gpio_config *pGpioConfig) {
1637 u32 TranslatedPinNum;
1645 struct SmsMsgHdr_ST xMsgHeader;
1650 if (PinNum > MAX_GPIO_PIN_NUMBER)
1653 if (pGpioConfig == NULL)
1656 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
1658 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1659 GFP_KERNEL | GFP_DMA);
1663 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1665 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1666 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1667 pMsg->xMsgHeader.msgFlags = 0;
1668 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1669 pMsg->msgData[0] = PinNum;
1671 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1672 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1673 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1677 pMsg->msgData[1] = TranslatedPinNum;
1678 pMsg->msgData[2] = GroupNum;
1679 ElectricChar = (pGpioConfig->PullUpDown)
1680 | (pGpioConfig->InputCharacteristics << 2)
1681 | (pGpioConfig->OutputSlewRate << 3)
1682 | (pGpioConfig->OutputDriving << 4);
1683 pMsg->msgData[3] = ElectricChar;
1684 pMsg->msgData[4] = pGpioConfig->Direction;
1685 pMsg->msgData[5] = groupCfg;
1687 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1688 pMsg->msgData[1] = pGpioConfig->PullUpDown;
1689 pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
1690 pMsg->msgData[3] = pGpioConfig->OutputDriving;
1691 pMsg->msgData[4] = pGpioConfig->Direction;
1692 pMsg->msgData[5] = 0;
1695 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1696 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1697 &coredev->gpio_configuration_done);
1701 sms_err("smscore_gpio_configure timeout");
1703 sms_err("smscore_gpio_configure error");
1710 int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
1718 struct SmsMsgHdr_ST xMsgHeader;
1719 u32 msgData[3]; /* keep it 3 ! */
1722 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
1723 (PinNum > MAX_GPIO_PIN_NUMBER))
1726 totalLen = sizeof(struct SmsMsgHdr_ST) +
1727 (3 * sizeof(u32)); /* keep it 3 ! */
1729 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1730 GFP_KERNEL | GFP_DMA);
1734 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1736 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1737 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1738 pMsg->xMsgHeader.msgFlags = 0;
1739 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1740 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1741 pMsg->msgData[0] = PinNum;
1742 pMsg->msgData[1] = NewLevel;
1744 /* Send message to SMS */
1745 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1746 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1747 &coredev->gpio_set_level_done);
1751 sms_err("smscore_gpio_set_level timeout");
1753 sms_err("smscore_gpio_set_level error");
1760 int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
1768 struct SmsMsgHdr_ST xMsgHeader;
1773 if (PinNum > MAX_GPIO_PIN_NUMBER)
1776 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
1778 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1779 GFP_KERNEL | GFP_DMA);
1783 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1785 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1786 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1787 pMsg->xMsgHeader.msgFlags = 0;
1788 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
1789 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1790 pMsg->msgData[0] = PinNum;
1791 pMsg->msgData[1] = 0;
1793 /* Send message to SMS */
1794 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1795 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1796 &coredev->gpio_get_level_done);
1800 sms_err("smscore_gpio_get_level timeout");
1802 sms_err("smscore_gpio_get_level error");
1806 /* Its a race between other gpio_get_level() and the copy of the single
1807 * global 'coredev->gpio_get_res' to the function's variable 'level'
1809 *level = coredev->gpio_get_res;
1817 static int __init smscore_module_init(void)
1821 printk("smsmdtv module init...\n");
1822 sms_info("entering... smscore_module_init....\n");
1823 INIT_LIST_HEAD(&g_smscore_notifyees);
1824 INIT_LIST_HEAD(&g_smscore_devices);
1825 kmutex_init(&g_smscore_deviceslock);
1827 INIT_LIST_HEAD(&g_smscore_registry);
1828 kmutex_init(&g_smscore_registrylock);
1830 //request the gpio used by cmmb
1831 //request_cmmb_gpio();
1832 /* Register sub system adapter objects */
1833 // request_cmmb_gpio();
1835 #ifdef SMS_NET_SUBSYS
1837 rc = smsnet_register();
1839 sms_err("Error registering Siano's network client.\n");
1844 #ifdef SMS_HOSTLIB_SUBSYS
1845 /* Char interface Register */
1846 rc = smschar_register();
1848 sms_err("Error registering Siano's char device client.\n");
1853 #ifdef SMS_DVB3_SUBSYS
1854 /* DVB v.3 Register */
1855 rc = smsdvb_register();
1857 sms_err("Error registering DVB client.\n");
1862 /* Register interfaces objects */
1866 rc = smsusb_register();
1868 sms_err("Error registering USB bus driver.\n");
1869 goto sms_bus_drv_error;
1875 rc = smssdio_register();
1877 sms_err("Error registering SDIO bus driver.\n");
1878 goto sms_bus_drv_error;
1883 #ifdef SMS_SPI_ROCKCHIP
1884 sms_debug(KERN_INFO "smsspi_register\n");
1885 rc = smsspi_register();
1887 sms_err("Error registering Intel PXA310 SPI bus driver.\n");
1888 goto sms_bus_drv_error;
1895 #ifdef SMS_DVB3_SUBSYS
1896 smsdvb_unregister();
1900 #ifdef SMS_HOSTLIB_SUBSYS
1901 smschar_unregister();
1905 #ifdef SMS_NET_SUBSYS
1906 smsnet_unregister();
1910 sms_err("rc %d", rc);
1911 printk(KERN_INFO "%s, rc %d\n", __func__, rc);
1916 static void __exit smscore_module_exit(void)
1921 #ifdef SMS_NET_SUBSYS
1922 /* Net Unregister */
1923 smsnet_unregister();
1926 #ifdef SMS_HOSTLIB_SUBSYS
1927 /* Char interface Unregister */
1928 smschar_unregister();
1931 #ifdef SMS_DVB3_SUBSYS
1932 /* DVB v.3 unregister */
1933 smsdvb_unregister();
1936 /* Unegister interfaces objects */
1938 /* USB unregister */
1939 smsusb_unregister();
1943 /* SDIO unegister */
1944 smssdio_unregister();
1947 #ifdef SMS_SPI_ROCKCHIP
1948 /* Intel PXA310 SPI unegister */
1949 smsspi_unregister();
1952 kmutex_lock(&g_smscore_deviceslock);
1953 while (!list_empty(&g_smscore_notifyees)) {
1954 struct smscore_device_notifyee_t *notifyee =
1955 (struct smscore_device_notifyee_t *)
1956 g_smscore_notifyees.next;
1958 list_del(¬ifyee->entry);
1961 kmutex_unlock(&g_smscore_deviceslock);
1963 kmutex_lock(&g_smscore_registrylock);
1964 while (!list_empty(&g_smscore_registry)) {
1965 struct smscore_registry_entry_t *entry =
1966 (struct smscore_registry_entry_t *)
1967 g_smscore_registry.next;
1969 list_del(&entry->entry);
1972 kmutex_unlock(&g_smscore_registrylock);
1974 // release_cmmb_gpio();
1979 // for loopback test
1982 int AdrLoopbackTest( struct smscore_device_t *coredev )
1985 struct SmsMsgData_ST* pLoopbackMsg = (struct SmsMsgData_ST*)msgbuff;
1986 struct SmsMsgData_ST* pLoopbackRes = (struct SmsMsgData_ST*)g_LbResBuf;
1988 int g_Loopback_failCounters= 0;
1989 int Len = 252 - sizeof(struct SmsMsgData_ST);
1993 pLoopbackMsg->xMsgHeader.msgType = MSG_SMS_LOOPBACK_REQ;
1994 pLoopbackMsg->xMsgHeader.msgSrcId = 151;
1995 pLoopbackMsg->xMsgHeader.msgDstId = 11;
1996 pLoopbackMsg->xMsgHeader.msgFlags = 0;
1997 pLoopbackMsg->xMsgHeader.msgLength = 252;
1999 sms_info("Loobpack test start.");
2002 for ( i = 0 ; i < 1000 ; i++ )
2005 pPtr = (u8*) &pLoopbackMsg->msgData[1];
2006 for ( j = 0 ; j < Len ; j ++ )
2010 pLoopbackMsg->msgData[0] = i+1;
2012 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pLoopbackMsg);
2013 rc = smscore_sendrequest_and_wait(coredev, pLoopbackMsg,
2014 pLoopbackMsg->xMsgHeader.msgLength,
2015 &coredev->loopback_res_done);
2022 pPtr = (u8*) &pLoopbackRes->msgData[1];
2024 for ( j = 0 ; j < Len ; j ++ )
2026 if ( pPtr[j] != (u8)(j + i))
2028 sms_err("Loopback data error at byte %u. Exp %u, Got %u", j, (u8)(j+i), pPtr[j] );
2029 g_Loopback_failCounters++;
2032 } //for ( j = 0 ; j < Len ; j ++ )
2033 } //for ( i = 0 ; i < 100 ; i++ )
2034 sms_info( "Loobpack test end. RUN times: %d; fail times : %d", i, g_Loopback_failCounters);
2039 module_init(smscore_module_init);
2040 module_exit(smscore_module_exit);
2042 MODULE_DESCRIPTION("Siano MDTV Core module");
2043 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
2044 MODULE_LICENSE("GPL");