linux/drivers/media/common/siano/smscoreapi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  Siano core API module
   4 *
   5 *  This file contains implementation for the interface to sms core component
   6 *
   7 *  author: Uri Shkolnik
   8 *
   9 *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  10 */
  11
  12#include "smscoreapi.h"
  13
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/module.h>
  17#include <linux/moduleparam.h>
  18#include <linux/dma-mapping.h>
  19#include <linux/delay.h>
  20#include <linux/io.h>
  21#include <linux/slab.h>
  22
  23#include <linux/firmware.h>
  24#include <linux/wait.h>
  25#include <asm/byteorder.h>
  26
  27#include "sms-cards.h"
  28#include "smsir.h"
  29
  30struct smscore_device_notifyee_t {
  31        struct list_head entry;
  32        hotplug_t hotplug;
  33};
  34
  35struct smscore_idlist_t {
  36        struct list_head entry;
  37        int             id;
  38        int             data_type;
  39};
  40
  41struct smscore_client_t {
  42        struct list_head entry;
  43        struct smscore_device_t *coredev;
  44        void                    *context;
  45        struct list_head        idlist;
  46        onresponse_t            onresponse_handler;
  47        onremove_t              onremove_handler;
  48};
  49
  50static char *siano_msgs[] = {
  51        [MSG_TYPE_BASE_VAL                           - MSG_TYPE_BASE_VAL] = "MSG_TYPE_BASE_VAL",
  52        [MSG_SMS_GET_VERSION_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_REQ",
  53        [MSG_SMS_GET_VERSION_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_RES",
  54        [MSG_SMS_MULTI_BRIDGE_CFG                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_MULTI_BRIDGE_CFG",
  55        [MSG_SMS_GPIO_CONFIG_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_REQ",
  56        [MSG_SMS_GPIO_CONFIG_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_RES",
  57        [MSG_SMS_GPIO_SET_LEVEL_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_SET_LEVEL_REQ",
  58        [MSG_SMS_GPIO_SET_LEVEL_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_SET_LEVEL_RES",
  59        [MSG_SMS_GPIO_GET_LEVEL_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_GET_LEVEL_REQ",
  60        [MSG_SMS_GPIO_GET_LEVEL_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_GET_LEVEL_RES",
  61        [MSG_SMS_EEPROM_BURN_IND                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_BURN_IND",
  62        [MSG_SMS_LOG_ENABLE_CHANGE_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ENABLE_CHANGE_REQ",
  63        [MSG_SMS_LOG_ENABLE_CHANGE_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ENABLE_CHANGE_RES",
  64        [MSG_SMS_SET_MAX_TX_MSG_LEN_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_MAX_TX_MSG_LEN_REQ",
  65        [MSG_SMS_SET_MAX_TX_MSG_LEN_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_MAX_TX_MSG_LEN_RES",
  66        [MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE",
  67        [MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST",
  68        [MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ     - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ",
  69        [MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES     - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES",
  70        [MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND",
  71        [MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND       - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND",
  72        [MSG_SMS_CONFIGURE_RF_SWITCH_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIGURE_RF_SWITCH_REQ",
  73        [MSG_SMS_CONFIGURE_RF_SWITCH_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIGURE_RF_SWITCH_RES",
  74        [MSG_SMS_MRC_PATH_DISCONNECT_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_PATH_DISCONNECT_REQ",
  75        [MSG_SMS_MRC_PATH_DISCONNECT_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_PATH_DISCONNECT_RES",
  76        [MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ    - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ",
  77        [MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES    - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES",
  78        [MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ       - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ",
  79        [MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES       - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES",
  80        [MSG_WR_REG_RFT_REQ                          - MSG_TYPE_BASE_VAL] = "MSG_WR_REG_RFT_REQ",
  81        [MSG_WR_REG_RFT_RES                          - MSG_TYPE_BASE_VAL] = "MSG_WR_REG_RFT_RES",
  82        [MSG_RD_REG_RFT_REQ                          - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_RFT_REQ",
  83        [MSG_RD_REG_RFT_RES                          - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_RFT_RES",
  84        [MSG_RD_REG_ALL_RFT_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_ALL_RFT_REQ",
  85        [MSG_RD_REG_ALL_RFT_RES                      - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_ALL_RFT_RES",
  86        [MSG_HELP_INT                                - MSG_TYPE_BASE_VAL] = "MSG_HELP_INT",
  87        [MSG_RUN_SCRIPT_INT                          - MSG_TYPE_BASE_VAL] = "MSG_RUN_SCRIPT_INT",
  88        [MSG_SMS_EWS_INBAND_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_EWS_INBAND_REQ",
  89        [MSG_SMS_EWS_INBAND_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_EWS_INBAND_RES",
  90        [MSG_SMS_RFS_SELECT_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_RFS_SELECT_REQ",
  91        [MSG_SMS_RFS_SELECT_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_RFS_SELECT_RES",
  92        [MSG_SMS_MB_GET_VER_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_GET_VER_REQ",
  93        [MSG_SMS_MB_GET_VER_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_GET_VER_RES",
  94        [MSG_SMS_MB_WRITE_CFGFILE_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_WRITE_CFGFILE_REQ",
  95        [MSG_SMS_MB_WRITE_CFGFILE_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_WRITE_CFGFILE_RES",
  96        [MSG_SMS_MB_READ_CFGFILE_REQ                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_READ_CFGFILE_REQ",
  97        [MSG_SMS_MB_READ_CFGFILE_RES                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_READ_CFGFILE_RES",
  98        [MSG_SMS_RD_MEM_REQ                          - MSG_TYPE_BASE_VAL] = "MSG_SMS_RD_MEM_REQ",
  99        [MSG_SMS_RD_MEM_RES                          - MSG_TYPE_BASE_VAL] = "MSG_SMS_RD_MEM_RES",
 100        [MSG_SMS_WR_MEM_REQ                          - MSG_TYPE_BASE_VAL] = "MSG_SMS_WR_MEM_REQ",
 101        [MSG_SMS_WR_MEM_RES                          - MSG_TYPE_BASE_VAL] = "MSG_SMS_WR_MEM_RES",
 102        [MSG_SMS_UPDATE_MEM_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_UPDATE_MEM_REQ",
 103        [MSG_SMS_UPDATE_MEM_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_UPDATE_MEM_RES",
 104        [MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ    - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ",
 105        [MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES    - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES",
 106        [MSG_SMS_RF_TUNE_REQ                         - MSG_TYPE_BASE_VAL] = "MSG_SMS_RF_TUNE_REQ",
 107        [MSG_SMS_RF_TUNE_RES                         - MSG_TYPE_BASE_VAL] = "MSG_SMS_RF_TUNE_RES",
 108        [MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ      - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ",
 109        [MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES      - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES",
 110        [MSG_SMS_ISDBT_SB_RECEPTION_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_SB_RECEPTION_REQ",
 111        [MSG_SMS_ISDBT_SB_RECEPTION_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_SB_RECEPTION_RES",
 112        [MSG_SMS_GENERIC_EPROM_WRITE_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_WRITE_REQ",
 113        [MSG_SMS_GENERIC_EPROM_WRITE_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_WRITE_RES",
 114        [MSG_SMS_GENERIC_EPROM_READ_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_READ_REQ",
 115        [MSG_SMS_GENERIC_EPROM_READ_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_READ_RES",
 116        [MSG_SMS_EEPROM_WRITE_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_WRITE_REQ",
 117        [MSG_SMS_EEPROM_WRITE_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_WRITE_RES",
 118        [MSG_SMS_CUSTOM_READ_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_READ_REQ",
 119        [MSG_SMS_CUSTOM_READ_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_READ_RES",
 120        [MSG_SMS_CUSTOM_WRITE_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_WRITE_REQ",
 121        [MSG_SMS_CUSTOM_WRITE_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_WRITE_RES",
 122        [MSG_SMS_INIT_DEVICE_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_INIT_DEVICE_REQ",
 123        [MSG_SMS_INIT_DEVICE_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_INIT_DEVICE_RES",
 124        [MSG_SMS_ATSC_SET_ALL_IP_REQ                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SET_ALL_IP_REQ",
 125        [MSG_SMS_ATSC_SET_ALL_IP_RES                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SET_ALL_IP_RES",
 126        [MSG_SMS_ATSC_START_ENSEMBLE_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_START_ENSEMBLE_REQ",
 127        [MSG_SMS_ATSC_START_ENSEMBLE_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_START_ENSEMBLE_RES",
 128        [MSG_SMS_SET_OUTPUT_MODE_REQ                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_OUTPUT_MODE_REQ",
 129        [MSG_SMS_SET_OUTPUT_MODE_RES                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_OUTPUT_MODE_RES",
 130        [MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ",
 131        [MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES",
 132        [MSG_SMS_SUB_CHANNEL_START_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_START_REQ",
 133        [MSG_SMS_SUB_CHANNEL_START_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_START_RES",
 134        [MSG_SMS_SUB_CHANNEL_STOP_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_STOP_REQ",
 135        [MSG_SMS_SUB_CHANNEL_STOP_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_STOP_RES",
 136        [MSG_SMS_ATSC_IP_FILTER_ADD_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_ADD_REQ",
 137        [MSG_SMS_ATSC_IP_FILTER_ADD_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_ADD_RES",
 138        [MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ           - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ",
 139        [MSG_SMS_ATSC_IP_FILTER_REMOVE_RES           - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_RES",
 140        [MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ       - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ",
 141        [MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES       - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES",
 142        [MSG_SMS_WAIT_CMD                            - MSG_TYPE_BASE_VAL] = "MSG_SMS_WAIT_CMD",
 143        [MSG_SMS_ADD_PID_FILTER_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_ADD_PID_FILTER_REQ",
 144        [MSG_SMS_ADD_PID_FILTER_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_ADD_PID_FILTER_RES",
 145        [MSG_SMS_REMOVE_PID_FILTER_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_REMOVE_PID_FILTER_REQ",
 146        [MSG_SMS_REMOVE_PID_FILTER_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_REMOVE_PID_FILTER_RES",
 147        [MSG_SMS_FAST_INFORMATION_CHANNEL_REQ        - MSG_TYPE_BASE_VAL] = "MSG_SMS_FAST_INFORMATION_CHANNEL_REQ",
 148        [MSG_SMS_FAST_INFORMATION_CHANNEL_RES        - MSG_TYPE_BASE_VAL] = "MSG_SMS_FAST_INFORMATION_CHANNEL_RES",
 149        [MSG_SMS_DAB_CHANNEL                         - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_CHANNEL",
 150        [MSG_SMS_GET_PID_FILTER_LIST_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_PID_FILTER_LIST_REQ",
 151        [MSG_SMS_GET_PID_FILTER_LIST_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_PID_FILTER_LIST_RES",
 152        [MSG_SMS_POWER_DOWN_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_REQ",
 153        [MSG_SMS_POWER_DOWN_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_RES",
 154        [MSG_SMS_ATSC_SLT_EXIST_IND                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SLT_EXIST_IND",
 155        [MSG_SMS_ATSC_NO_SLT_IND                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_NO_SLT_IND",
 156        [MSG_SMS_GET_STATISTICS_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_REQ",
 157        [MSG_SMS_GET_STATISTICS_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_RES",
 158        [MSG_SMS_SEND_DUMP                           - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_DUMP",
 159        [MSG_SMS_SCAN_START_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_START_REQ",
 160        [MSG_SMS_SCAN_START_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_START_RES",
 161        [MSG_SMS_SCAN_STOP_REQ                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_STOP_REQ",
 162        [MSG_SMS_SCAN_STOP_RES                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_STOP_RES",
 163        [MSG_SMS_SCAN_PROGRESS_IND                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_PROGRESS_IND",
 164        [MSG_SMS_SCAN_COMPLETE_IND                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_COMPLETE_IND",
 165        [MSG_SMS_LOG_ITEM                            - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ITEM",
 166        [MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ",
 167        [MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES",
 168        [MSG_SMS_HO_PER_SLICES_IND                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PER_SLICES_IND",
 169        [MSG_SMS_HO_INBAND_POWER_IND                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_INBAND_POWER_IND",
 170        [MSG_SMS_MANUAL_DEMOD_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_MANUAL_DEMOD_REQ",
 171        [MSG_SMS_HO_TUNE_ON_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_ON_REQ",
 172        [MSG_SMS_HO_TUNE_ON_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_ON_RES",
 173        [MSG_SMS_HO_TUNE_OFF_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_OFF_REQ",
 174        [MSG_SMS_HO_TUNE_OFF_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_OFF_RES",
 175        [MSG_SMS_HO_PEEK_FREQ_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_REQ",
 176        [MSG_SMS_HO_PEEK_FREQ_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_RES",
 177        [MSG_SMS_HO_PEEK_FREQ_IND                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_IND",
 178        [MSG_SMS_MB_ATTEN_SET_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_ATTEN_SET_REQ",
 179        [MSG_SMS_MB_ATTEN_SET_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_ATTEN_SET_RES",
 180        [MSG_SMS_ENABLE_STAT_IN_I2C_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_STAT_IN_I2C_REQ",
 181        [MSG_SMS_ENABLE_STAT_IN_I2C_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_STAT_IN_I2C_RES",
 182        [MSG_SMS_SET_ANTENNA_CONFIG_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_ANTENNA_CONFIG_REQ",
 183        [MSG_SMS_SET_ANTENNA_CONFIG_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_ANTENNA_CONFIG_RES",
 184        [MSG_SMS_GET_STATISTICS_EX_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_EX_REQ",
 185        [MSG_SMS_GET_STATISTICS_EX_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_EX_RES",
 186        [MSG_SMS_SLEEP_RESUME_COMP_IND               - MSG_TYPE_BASE_VAL] = "MSG_SMS_SLEEP_RESUME_COMP_IND",
 187        [MSG_SMS_SWITCH_HOST_INTERFACE_REQ           - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWITCH_HOST_INTERFACE_REQ",
 188        [MSG_SMS_SWITCH_HOST_INTERFACE_RES           - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWITCH_HOST_INTERFACE_RES",
 189        [MSG_SMS_DATA_DOWNLOAD_REQ                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_DOWNLOAD_REQ",
 190        [MSG_SMS_DATA_DOWNLOAD_RES                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_DOWNLOAD_RES",
 191        [MSG_SMS_DATA_VALIDITY_REQ                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_VALIDITY_REQ",
 192        [MSG_SMS_DATA_VALIDITY_RES                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_VALIDITY_RES",
 193        [MSG_SMS_SWDOWNLOAD_TRIGGER_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_TRIGGER_REQ",
 194        [MSG_SMS_SWDOWNLOAD_TRIGGER_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_TRIGGER_RES",
 195        [MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ",
 196        [MSG_SMS_SWDOWNLOAD_BACKDOOR_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_BACKDOOR_RES",
 197        [MSG_SMS_GET_VERSION_EX_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_EX_REQ",
 198        [MSG_SMS_GET_VERSION_EX_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_EX_RES",
 199        [MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ",
 200        [MSG_SMS_CLOCK_OUTPUT_CONFIG_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_CLOCK_OUTPUT_CONFIG_RES",
 201        [MSG_SMS_I2C_SET_FREQ_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SET_FREQ_REQ",
 202        [MSG_SMS_I2C_SET_FREQ_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SET_FREQ_RES",
 203        [MSG_SMS_GENERIC_I2C_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_I2C_REQ",
 204        [MSG_SMS_GENERIC_I2C_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_I2C_RES",
 205        [MSG_SMS_DVBT_BDA_DATA                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_DVBT_BDA_DATA",
 206        [MSG_SW_RELOAD_REQ                           - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_REQ",
 207        [MSG_SMS_DATA_MSG                            - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_MSG",
 208        [MSG_TABLE_UPLOAD_REQ                        - MSG_TYPE_BASE_VAL] = "MSG_TABLE_UPLOAD_REQ",
 209        [MSG_TABLE_UPLOAD_RES                        - MSG_TYPE_BASE_VAL] = "MSG_TABLE_UPLOAD_RES",
 210        [MSG_SW_RELOAD_START_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_START_REQ",
 211        [MSG_SW_RELOAD_START_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_START_RES",
 212        [MSG_SW_RELOAD_EXEC_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_EXEC_REQ",
 213        [MSG_SW_RELOAD_EXEC_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_EXEC_RES",
 214        [MSG_SMS_SPI_INT_LINE_SET_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_INT_LINE_SET_REQ",
 215        [MSG_SMS_SPI_INT_LINE_SET_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_INT_LINE_SET_RES",
 216        [MSG_SMS_GPIO_CONFIG_EX_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_EX_REQ",
 217        [MSG_SMS_GPIO_CONFIG_EX_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_EX_RES",
 218        [MSG_SMS_WATCHDOG_ACT_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_WATCHDOG_ACT_REQ",
 219        [MSG_SMS_WATCHDOG_ACT_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_WATCHDOG_ACT_RES",
 220        [MSG_SMS_LOOPBACK_REQ                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOOPBACK_REQ",
 221        [MSG_SMS_LOOPBACK_RES                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOOPBACK_RES",
 222        [MSG_SMS_RAW_CAPTURE_START_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_START_REQ",
 223        [MSG_SMS_RAW_CAPTURE_START_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_START_RES",
 224        [MSG_SMS_RAW_CAPTURE_ABORT_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_ABORT_REQ",
 225        [MSG_SMS_RAW_CAPTURE_ABORT_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_ABORT_RES",
 226        [MSG_SMS_RAW_CAPTURE_COMPLETE_IND            - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_COMPLETE_IND",
 227        [MSG_SMS_DATA_PUMP_IND                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_IND",
 228        [MSG_SMS_DATA_PUMP_REQ                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_REQ",
 229        [MSG_SMS_DATA_PUMP_RES                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_RES",
 230        [MSG_SMS_FLASH_DL_REQ                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_FLASH_DL_REQ",
 231        [MSG_SMS_EXEC_TEST_1_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXEC_TEST_1_REQ",
 232        [MSG_SMS_EXEC_TEST_1_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXEC_TEST_1_RES",
 233        [MSG_SMS_ENABLE_TS_INTERFACE_REQ             - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_TS_INTERFACE_REQ",
 234        [MSG_SMS_ENABLE_TS_INTERFACE_RES             - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_TS_INTERFACE_RES",
 235        [MSG_SMS_SPI_SET_BUS_WIDTH_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_SET_BUS_WIDTH_REQ",
 236        [MSG_SMS_SPI_SET_BUS_WIDTH_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_SET_BUS_WIDTH_RES",
 237        [MSG_SMS_SEND_EMM_REQ                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_EMM_REQ",
 238        [MSG_SMS_SEND_EMM_RES                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_EMM_RES",
 239        [MSG_SMS_DISABLE_TS_INTERFACE_REQ            - MSG_TYPE_BASE_VAL] = "MSG_SMS_DISABLE_TS_INTERFACE_REQ",
 240        [MSG_SMS_DISABLE_TS_INTERFACE_RES            - MSG_TYPE_BASE_VAL] = "MSG_SMS_DISABLE_TS_INTERFACE_RES",
 241        [MSG_SMS_IS_BUF_FREE_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_IS_BUF_FREE_REQ",
 242        [MSG_SMS_IS_BUF_FREE_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_IS_BUF_FREE_RES",
 243        [MSG_SMS_EXT_ANTENNA_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXT_ANTENNA_REQ",
 244        [MSG_SMS_EXT_ANTENNA_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXT_ANTENNA_RES",
 245        [MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE   - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE",
 246        [MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE   - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE",
 247        [MSG_SMS_BATTERY_LEVEL_REQ                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_BATTERY_LEVEL_REQ",
 248        [MSG_SMS_BATTERY_LEVEL_RES                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_BATTERY_LEVEL_RES",
 249        [MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE      - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE",
 250        [MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE      - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE",
 251        [MSG_SMS_FM_RADIO_BLOCK_IND                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_FM_RADIO_BLOCK_IND",
 252        [MSG_SMS_HOST_NOTIFICATION_IND               - MSG_TYPE_BASE_VAL] = "MSG_SMS_HOST_NOTIFICATION_IND",
 253        [MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE",
 254        [MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE",
 255        [MSG_SMS_CMMB_GET_NETWORKS_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NETWORKS_REQ",
 256        [MSG_SMS_CMMB_GET_NETWORKS_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NETWORKS_RES",
 257        [MSG_SMS_CMMB_START_SERVICE_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_SERVICE_REQ",
 258        [MSG_SMS_CMMB_START_SERVICE_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_SERVICE_RES",
 259        [MSG_SMS_CMMB_STOP_SERVICE_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_SERVICE_REQ",
 260        [MSG_SMS_CMMB_STOP_SERVICE_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_SERVICE_RES",
 261        [MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ",
 262        [MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES",
 263        [MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ      - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ",
 264        [MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES      - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES",
 265        [MSG_SMS_CMMB_START_CONTROL_INFO_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_CONTROL_INFO_REQ",
 266        [MSG_SMS_CMMB_START_CONTROL_INFO_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_CONTROL_INFO_RES",
 267        [MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ          - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ",
 268        [MSG_SMS_CMMB_STOP_CONTROL_INFO_RES          - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_CONTROL_INFO_RES",
 269        [MSG_SMS_ISDBT_TUNE_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_TUNE_REQ",
 270        [MSG_SMS_ISDBT_TUNE_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_TUNE_RES",
 271        [MSG_SMS_TRANSMISSION_IND                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_TRANSMISSION_IND",
 272        [MSG_SMS_PID_STATISTICS_IND                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_PID_STATISTICS_IND",
 273        [MSG_SMS_POWER_DOWN_IND                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_IND",
 274        [MSG_SMS_POWER_DOWN_CONF                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_CONF",
 275        [MSG_SMS_POWER_UP_IND                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_UP_IND",
 276        [MSG_SMS_POWER_UP_CONF                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_UP_CONF",
 277        [MSG_SMS_POWER_MODE_SET_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_MODE_SET_REQ",
 278        [MSG_SMS_POWER_MODE_SET_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_MODE_SET_RES",
 279        [MSG_SMS_DEBUG_HOST_EVENT_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEBUG_HOST_EVENT_REQ",
 280        [MSG_SMS_DEBUG_HOST_EVENT_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEBUG_HOST_EVENT_RES",
 281        [MSG_SMS_NEW_CRYSTAL_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_NEW_CRYSTAL_REQ",
 282        [MSG_SMS_NEW_CRYSTAL_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_NEW_CRYSTAL_RES",
 283        [MSG_SMS_CONFIG_SPI_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIG_SPI_REQ",
 284        [MSG_SMS_CONFIG_SPI_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIG_SPI_RES",
 285        [MSG_SMS_I2C_SHORT_STAT_IND                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SHORT_STAT_IND",
 286        [MSG_SMS_START_IR_REQ                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_START_IR_REQ",
 287        [MSG_SMS_START_IR_RES                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_START_IR_RES",
 288        [MSG_SMS_IR_SAMPLES_IND                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_IR_SAMPLES_IND",
 289        [MSG_SMS_CMMB_CA_SERVICE_IND                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_CA_SERVICE_IND",
 290        [MSG_SMS_SLAVE_DEVICE_DETECTED               - MSG_TYPE_BASE_VAL] = "MSG_SMS_SLAVE_DEVICE_DETECTED",
 291        [MSG_SMS_INTERFACE_LOCK_IND                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_INTERFACE_LOCK_IND",
 292        [MSG_SMS_INTERFACE_UNLOCK_IND                - MSG_TYPE_BASE_VAL] = "MSG_SMS_INTERFACE_UNLOCK_IND",
 293        [MSG_SMS_SEND_ROSUM_BUFF_REQ                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_ROSUM_BUFF_REQ",
 294        [MSG_SMS_SEND_ROSUM_BUFF_RES                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_ROSUM_BUFF_RES",
 295        [MSG_SMS_ROSUM_BUFF                          - MSG_TYPE_BASE_VAL] = "MSG_SMS_ROSUM_BUFF",
 296        [MSG_SMS_SET_AES128_KEY_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_AES128_KEY_REQ",
 297        [MSG_SMS_SET_AES128_KEY_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_AES128_KEY_RES",
 298        [MSG_SMS_MBBMS_WRITE_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_WRITE_REQ",
 299        [MSG_SMS_MBBMS_WRITE_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_WRITE_RES",
 300        [MSG_SMS_MBBMS_READ_IND                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_READ_IND",
 301        [MSG_SMS_IQ_STREAM_START_REQ                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_START_REQ",
 302        [MSG_SMS_IQ_STREAM_START_RES                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_START_RES",
 303        [MSG_SMS_IQ_STREAM_STOP_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_STOP_REQ",
 304        [MSG_SMS_IQ_STREAM_STOP_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_STOP_RES",
 305        [MSG_SMS_IQ_STREAM_DATA_BLOCK                - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_DATA_BLOCK",
 306        [MSG_SMS_GET_EEPROM_VERSION_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_EEPROM_VERSION_REQ",
 307        [MSG_SMS_GET_EEPROM_VERSION_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_EEPROM_VERSION_RES",
 308        [MSG_SMS_SIGNAL_DETECTED_IND                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SIGNAL_DETECTED_IND",
 309        [MSG_SMS_NO_SIGNAL_IND                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_NO_SIGNAL_IND",
 310        [MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ",
 311        [MSG_SMS_MRC_SHUTDOWN_SLAVE_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_SHUTDOWN_SLAVE_RES",
 312        [MSG_SMS_MRC_BRINGUP_SLAVE_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_BRINGUP_SLAVE_REQ",
 313        [MSG_SMS_MRC_BRINGUP_SLAVE_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_BRINGUP_SLAVE_RES",
 314        [MSG_SMS_EXTERNAL_LNA_CTRL_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXTERNAL_LNA_CTRL_REQ",
 315        [MSG_SMS_EXTERNAL_LNA_CTRL_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXTERNAL_LNA_CTRL_RES",
 316        [MSG_SMS_SET_PERIODIC_STATISTICS_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_PERIODIC_STATISTICS_REQ",
 317        [MSG_SMS_SET_PERIODIC_STATISTICS_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_PERIODIC_STATISTICS_RES",
 318        [MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ        - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ",
 319        [MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES        - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES",
 320        [LOCAL_TUNE                                  - MSG_TYPE_BASE_VAL] = "LOCAL_TUNE",
 321        [LOCAL_IFFT_H_ICI                            - MSG_TYPE_BASE_VAL] = "LOCAL_IFFT_H_ICI",
 322        [MSG_RESYNC_REQ                              - MSG_TYPE_BASE_VAL] = "MSG_RESYNC_REQ",
 323        [MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ",
 324        [MSG_SMS_CMMB_GET_MRC_STATISTICS_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_MRC_STATISTICS_RES",
 325        [MSG_SMS_LOG_EX_ITEM                         - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_EX_ITEM",
 326        [MSG_SMS_DEVICE_DATA_LOSS_IND                - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEVICE_DATA_LOSS_IND",
 327        [MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND          - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND",
 328        [MSG_SMS_USER_MSG_REQ                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_USER_MSG_REQ",
 329        [MSG_SMS_USER_MSG_RES                        - MSG_TYPE_BASE_VAL] = "MSG_SMS_USER_MSG_RES",
 330        [MSG_SMS_SMART_CARD_INIT_REQ                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_INIT_REQ",
 331        [MSG_SMS_SMART_CARD_INIT_RES                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_INIT_RES",
 332        [MSG_SMS_SMART_CARD_WRITE_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_WRITE_REQ",
 333        [MSG_SMS_SMART_CARD_WRITE_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_WRITE_RES",
 334        [MSG_SMS_SMART_CARD_READ_IND                 - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_READ_IND",
 335        [MSG_SMS_TSE_ENABLE_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_TSE_ENABLE_REQ",
 336        [MSG_SMS_TSE_ENABLE_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_TSE_ENABLE_RES",
 337        [MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ       - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ",
 338        [MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES       - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES",
 339        [MSG_SMS_LED_CONFIG_REQ                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_LED_CONFIG_REQ",
 340        [MSG_SMS_LED_CONFIG_RES                      - MSG_TYPE_BASE_VAL] = "MSG_SMS_LED_CONFIG_RES",
 341        [MSG_PWM_ANTENNA_REQ                         - MSG_TYPE_BASE_VAL] = "MSG_PWM_ANTENNA_REQ",
 342        [MSG_PWM_ANTENNA_RES                         - MSG_TYPE_BASE_VAL] = "MSG_PWM_ANTENNA_RES",
 343        [MSG_SMS_CMMB_SMD_SN_REQ                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SMD_SN_REQ",
 344        [MSG_SMS_CMMB_SMD_SN_RES                     - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SMD_SN_RES",
 345        [MSG_SMS_CMMB_SET_CA_CW_REQ                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_CW_REQ",
 346        [MSG_SMS_CMMB_SET_CA_CW_RES                  - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_CW_RES",
 347        [MSG_SMS_CMMB_SET_CA_SALT_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_SALT_REQ",
 348        [MSG_SMS_CMMB_SET_CA_SALT_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_SALT_RES",
 349        [MSG_SMS_NSCD_INIT_REQ                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_INIT_REQ",
 350        [MSG_SMS_NSCD_INIT_RES                       - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_INIT_RES",
 351        [MSG_SMS_NSCD_PROCESS_SECTION_REQ            - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_PROCESS_SECTION_REQ",
 352        [MSG_SMS_NSCD_PROCESS_SECTION_RES            - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_PROCESS_SECTION_RES",
 353        [MSG_SMS_DBD_CREATE_OBJECT_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CREATE_OBJECT_REQ",
 354        [MSG_SMS_DBD_CREATE_OBJECT_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CREATE_OBJECT_RES",
 355        [MSG_SMS_DBD_CONFIGURE_REQ                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CONFIGURE_REQ",
 356        [MSG_SMS_DBD_CONFIGURE_RES                   - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CONFIGURE_RES",
 357        [MSG_SMS_DBD_SET_KEYS_REQ                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_SET_KEYS_REQ",
 358        [MSG_SMS_DBD_SET_KEYS_RES                    - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_SET_KEYS_RES",
 359        [MSG_SMS_DBD_PROCESS_HEADER_REQ              - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_HEADER_REQ",
 360        [MSG_SMS_DBD_PROCESS_HEADER_RES              - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_HEADER_RES",
 361        [MSG_SMS_DBD_PROCESS_DATA_REQ                - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_DATA_REQ",
 362        [MSG_SMS_DBD_PROCESS_DATA_RES                - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_DATA_RES",
 363        [MSG_SMS_DBD_PROCESS_GET_DATA_REQ            - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_GET_DATA_REQ",
 364        [MSG_SMS_DBD_PROCESS_GET_DATA_RES            - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_GET_DATA_RES",
 365        [MSG_SMS_NSCD_OPEN_SESSION_REQ               - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_OPEN_SESSION_REQ",
 366        [MSG_SMS_NSCD_OPEN_SESSION_RES               - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_OPEN_SESSION_RES",
 367        [MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ         - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ",
 368        [MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES         - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES",
 369        [MSG_LAST_MSG_TYPE                           - MSG_TYPE_BASE_VAL] = "MSG_LAST_MSG_TYPE",
 370};
 371
 372char *smscore_translate_msg(enum msg_types msgtype)
 373{
 374        int i = msgtype - MSG_TYPE_BASE_VAL;
 375        char *msg;
 376
 377        if (i < 0 || i >= ARRAY_SIZE(siano_msgs))
 378                return "Unknown msg type";
 379
 380        msg = siano_msgs[i];
 381
 382        if (!*msg)
 383                return "Unknown msg type";
 384
 385        return msg;
 386}
 387EXPORT_SYMBOL_GPL(smscore_translate_msg);
 388
 389void smscore_set_board_id(struct smscore_device_t *core, int id)
 390{
 391        core->board_id = id;
 392}
 393
 394int smscore_led_state(struct smscore_device_t *core, int led)
 395{
 396        if (led >= 0)
 397                core->led_state = led;
 398        return core->led_state;
 399}
 400EXPORT_SYMBOL_GPL(smscore_set_board_id);
 401
 402int smscore_get_board_id(struct smscore_device_t *core)
 403{
 404        return core->board_id;
 405}
 406EXPORT_SYMBOL_GPL(smscore_get_board_id);
 407
 408struct smscore_registry_entry_t {
 409        struct list_head entry;
 410        char devpath[32];
 411        int mode;
 412        enum sms_device_type_st type;
 413};
 414
 415static struct list_head g_smscore_notifyees;
 416static struct list_head g_smscore_devices;
 417static DEFINE_MUTEX(g_smscore_deviceslock);
 418
 419static struct list_head g_smscore_registry;
 420static DEFINE_MUTEX(g_smscore_registrylock);
 421
 422static int default_mode = DEVICE_MODE_NONE;
 423
 424module_param(default_mode, int, 0644);
 425MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
 426
 427static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
 428{
 429        struct smscore_registry_entry_t *entry;
 430        struct list_head *next;
 431
 432        mutex_lock(&g_smscore_registrylock);
 433        for (next = g_smscore_registry.next;
 434             next != &g_smscore_registry;
 435             next = next->next) {
 436                entry = (struct smscore_registry_entry_t *) next;
 437                if (!strncmp(entry->devpath, devpath, sizeof(entry->devpath))) {
 438                        mutex_unlock(&g_smscore_registrylock);
 439                        return entry;
 440                }
 441        }
 442        entry = kmalloc(sizeof(*entry), GFP_KERNEL);
 443        if (entry) {
 444                entry->mode = default_mode;
 445                strscpy(entry->devpath, devpath, sizeof(entry->devpath));
 446                list_add(&entry->entry, &g_smscore_registry);
 447        } else
 448                pr_err("failed to create smscore_registry.\n");
 449        mutex_unlock(&g_smscore_registrylock);
 450        return entry;
 451}
 452
 453int smscore_registry_getmode(char *devpath)
 454{
 455        struct smscore_registry_entry_t *entry;
 456
 457        entry = smscore_find_registry(devpath);
 458        if (entry)
 459                return entry->mode;
 460        else
 461                pr_err("No registry found.\n");
 462
 463        return default_mode;
 464}
 465EXPORT_SYMBOL_GPL(smscore_registry_getmode);
 466
 467static enum sms_device_type_st smscore_registry_gettype(char *devpath)
 468{
 469        struct smscore_registry_entry_t *entry;
 470
 471        entry = smscore_find_registry(devpath);
 472        if (entry)
 473                return entry->type;
 474        else
 475                pr_err("No registry found.\n");
 476
 477        return -EINVAL;
 478}
 479
 480static void smscore_registry_setmode(char *devpath, int mode)
 481{
 482        struct smscore_registry_entry_t *entry;
 483
 484        entry = smscore_find_registry(devpath);
 485        if (entry)
 486                entry->mode = mode;
 487        else
 488                pr_err("No registry found.\n");
 489}
 490
 491static void smscore_registry_settype(char *devpath,
 492                                     enum sms_device_type_st type)
 493{
 494        struct smscore_registry_entry_t *entry;
 495
 496        entry = smscore_find_registry(devpath);
 497        if (entry)
 498                entry->type = type;
 499        else
 500                pr_err("No registry found.\n");
 501}
 502
 503
 504static void list_add_locked(struct list_head *new, struct list_head *head,
 505                            spinlock_t *lock)
 506{
 507        unsigned long flags;
 508
 509        spin_lock_irqsave(lock, flags);
 510
 511        list_add(new, head);
 512
 513        spin_unlock_irqrestore(lock, flags);
 514}
 515
 516/*
 517 * register a client callback that called when device plugged in/unplugged
 518 * NOTE: if devices exist callback is called immediately for each device
 519 *
 520 * @param hotplug callback
 521 *
 522 * return: 0 on success, <0 on error.
 523 */
 524int smscore_register_hotplug(hotplug_t hotplug)
 525{
 526        struct smscore_device_notifyee_t *notifyee;
 527        struct list_head *next, *first;
 528        int rc = 0;
 529
 530        mutex_lock(&g_smscore_deviceslock);
 531        notifyee = kmalloc(sizeof(*notifyee), GFP_KERNEL);
 532        if (notifyee) {
 533                /* now notify callback about existing devices */
 534                first = &g_smscore_devices;
 535                for (next = first->next;
 536                     next != first && !rc;
 537                     next = next->next) {
 538                        struct smscore_device_t *coredev =
 539                                (struct smscore_device_t *) next;
 540                        rc = hotplug(coredev, coredev->device, 1);
 541                }
 542
 543                if (rc >= 0) {
 544                        notifyee->hotplug = hotplug;
 545                        list_add(&notifyee->entry, &g_smscore_notifyees);
 546                } else
 547                        kfree(notifyee);
 548        } else
 549                rc = -ENOMEM;
 550
 551        mutex_unlock(&g_smscore_deviceslock);
 552
 553        return rc;
 554}
 555EXPORT_SYMBOL_GPL(smscore_register_hotplug);
 556
 557/*
 558 * unregister a client callback that called when device plugged in/unplugged
 559 *
 560 * @param hotplug callback
 561 *
 562 */
 563void smscore_unregister_hotplug(hotplug_t hotplug)
 564{
 565        struct list_head *next, *first;
 566
 567        mutex_lock(&g_smscore_deviceslock);
 568
 569        first = &g_smscore_notifyees;
 570
 571        for (next = first->next; next != first;) {
 572                struct smscore_device_notifyee_t *notifyee =
 573                        (struct smscore_device_notifyee_t *) next;
 574                next = next->next;
 575
 576                if (notifyee->hotplug == hotplug) {
 577                        list_del(&notifyee->entry);
 578                        kfree(notifyee);
 579                }
 580        }
 581
 582        mutex_unlock(&g_smscore_deviceslock);
 583}
 584EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
 585
 586static void smscore_notify_clients(struct smscore_device_t *coredev)
 587{
 588        struct smscore_client_t *client;
 589
 590        /* the client must call smscore_unregister_client from remove handler */
 591        while (!list_empty(&coredev->clients)) {
 592                client = (struct smscore_client_t *) coredev->clients.next;
 593                client->onremove_handler(client->context);
 594        }
 595}
 596
 597static int smscore_notify_callbacks(struct smscore_device_t *coredev,
 598                                    struct device *device, int arrival)
 599{
 600        struct smscore_device_notifyee_t *elem;
 601        int rc = 0;
 602
 603        /* note: must be called under g_deviceslock */
 604
 605        list_for_each_entry(elem, &g_smscore_notifyees, entry) {
 606                rc = elem->hotplug(coredev, device, arrival);
 607                if (rc < 0)
 608                        break;
 609        }
 610
 611        return rc;
 612}
 613
 614static struct
 615smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
 616                                       dma_addr_t common_buffer_phys)
 617{
 618        struct smscore_buffer_t *cb;
 619
 620        cb = kzalloc(sizeof(*cb), GFP_KERNEL);
 621        if (!cb)
 622                return NULL;
 623
 624        cb->p = buffer;
 625        cb->offset_in_common = buffer - (u8 *) common_buffer;
 626        if (common_buffer_phys)
 627                cb->phys = common_buffer_phys + cb->offset_in_common;
 628
 629        return cb;
 630}
 631
 632/*
 633 * creates coredev object for a device, prepares buffers,
 634 * creates buffer mappings, notifies registered hotplugs about new device.
 635 *
 636 * @param params device pointer to struct with device specific parameters
 637 *               and handlers
 638 * @param coredev pointer to a value that receives created coredev object
 639 *
 640 * return: 0 on success, <0 on error.
 641 */
 642int smscore_register_device(struct smsdevice_params_t *params,
 643                            struct smscore_device_t **coredev,
 644                            gfp_t gfp_buf_flags,
 645                            void *mdev)
 646{
 647        struct smscore_device_t *dev;
 648        u8 *buffer;
 649
 650        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 651        if (!dev)
 652                return -ENOMEM;
 653
 654#ifdef CONFIG_MEDIA_CONTROLLER_DVB
 655        dev->media_dev = mdev;
 656#endif
 657        dev->gfp_buf_flags = gfp_buf_flags;
 658
 659        /* init list entry so it could be safe in smscore_unregister_device */
 660        INIT_LIST_HEAD(&dev->entry);
 661
 662        /* init queues */
 663        INIT_LIST_HEAD(&dev->clients);
 664        INIT_LIST_HEAD(&dev->buffers);
 665
 666        /* init locks */
 667        spin_lock_init(&dev->clientslock);
 668        spin_lock_init(&dev->bufferslock);
 669
 670        /* init completion events */
 671        init_completion(&dev->version_ex_done);
 672        init_completion(&dev->data_download_done);
 673        init_completion(&dev->data_validity_done);
 674        init_completion(&dev->trigger_done);
 675        init_completion(&dev->init_device_done);
 676        init_completion(&dev->reload_start_done);
 677        init_completion(&dev->resume_done);
 678        init_completion(&dev->gpio_configuration_done);
 679        init_completion(&dev->gpio_set_level_done);
 680        init_completion(&dev->gpio_get_level_done);
 681        init_completion(&dev->ir_init_done);
 682
 683        /* Buffer management */
 684        init_waitqueue_head(&dev->buffer_mng_waitq);
 685
 686        /* alloc common buffer */
 687        dev->common_buffer_size = params->buffer_size * params->num_buffers;
 688        if (params->usb_device)
 689                buffer = kzalloc(dev->common_buffer_size, GFP_KERNEL);
 690        else
 691                buffer = dma_alloc_coherent(params->device,
 692                                            dev->common_buffer_size,
 693                                            &dev->common_buffer_phys,
 694                                            GFP_KERNEL | dev->gfp_buf_flags);
 695        if (!buffer) {
 696                smscore_unregister_device(dev);
 697                return -ENOMEM;
 698        }
 699        dev->common_buffer = buffer;
 700
 701        /* prepare dma buffers */
 702        for (; dev->num_buffers < params->num_buffers;
 703             dev->num_buffers++, buffer += params->buffer_size) {
 704                struct smscore_buffer_t *cb;
 705
 706                cb = smscore_createbuffer(buffer, dev->common_buffer,
 707                                          dev->common_buffer_phys);
 708                if (!cb) {
 709                        smscore_unregister_device(dev);
 710                        return -ENOMEM;
 711                }
 712
 713                smscore_putbuffer(dev, cb);
 714        }
 715
 716        pr_debug("allocated %d buffers\n", dev->num_buffers);
 717
 718        dev->mode = DEVICE_MODE_NONE;
 719        dev->board_id = SMS_BOARD_UNKNOWN;
 720        dev->context = params->context;
 721        dev->device = params->device;
 722        dev->usb_device = params->usb_device;
 723        dev->setmode_handler = params->setmode_handler;
 724        dev->detectmode_handler = params->detectmode_handler;
 725        dev->sendrequest_handler = params->sendrequest_handler;
 726        dev->preload_handler = params->preload_handler;
 727        dev->postload_handler = params->postload_handler;
 728
 729        dev->device_flags = params->flags;
 730        strscpy(dev->devpath, params->devpath, sizeof(dev->devpath));
 731
 732        smscore_registry_settype(dev->devpath, params->device_type);
 733
 734        /* add device to devices list */
 735        mutex_lock(&g_smscore_deviceslock);
 736        list_add(&dev->entry, &g_smscore_devices);
 737        mutex_unlock(&g_smscore_deviceslock);
 738
 739        *coredev = dev;
 740
 741        pr_debug("device %p created\n", dev);
 742
 743        return 0;
 744}
 745EXPORT_SYMBOL_GPL(smscore_register_device);
 746
 747
 748static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
 749                void *buffer, size_t size, struct completion *completion) {
 750        int rc;
 751
 752        if (!completion)
 753                return -EINVAL;
 754        init_completion(completion);
 755
 756        rc = coredev->sendrequest_handler(coredev->context, buffer, size);
 757        if (rc < 0) {
 758                pr_info("sendrequest returned error %d\n", rc);
 759                return rc;
 760        }
 761
 762        return wait_for_completion_timeout(completion,
 763                        msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
 764                        0 : -ETIME;
 765}
 766
 767/*
 768 * Starts & enables IR operations
 769 *
 770 * return: 0 on success, < 0 on error.
 771 */
 772static int smscore_init_ir(struct smscore_device_t *coredev)
 773{
 774        int ir_io;
 775        int rc;
 776        void *buffer;
 777
 778        coredev->ir.dev = NULL;
 779        ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
 780        if (ir_io) {/* only if IR port exist we use IR sub-module */
 781                pr_debug("IR loading\n");
 782                rc = sms_ir_init(coredev);
 783
 784                if      (rc != 0)
 785                        pr_err("Error initialization DTV IR sub-module\n");
 786                else {
 787                        buffer = kmalloc(sizeof(struct sms_msg_data2) +
 788                                                SMS_DMA_ALIGNMENT,
 789                                                GFP_KERNEL | coredev->gfp_buf_flags);
 790                        if (buffer) {
 791                                struct sms_msg_data2 *msg =
 792                                (struct sms_msg_data2 *)
 793                                SMS_ALIGN_ADDRESS(buffer);
 794
 795                                SMS_INIT_MSG(&msg->x_msg_header,
 796                                                MSG_SMS_START_IR_REQ,
 797                                                sizeof(struct sms_msg_data2));
 798                                msg->msg_data[0] = coredev->ir.controller;
 799                                msg->msg_data[1] = coredev->ir.timeout;
 800
 801                                rc = smscore_sendrequest_and_wait(coredev, msg,
 802                                                msg->x_msg_header. msg_length,
 803                                                &coredev->ir_init_done);
 804
 805                                kfree(buffer);
 806                        } else
 807                                pr_err("Sending IR initialization message failed\n");
 808                }
 809        } else
 810                pr_info("IR port has not been detected\n");
 811
 812        return 0;
 813}
 814
 815/*
 816 * configures device features according to board configuration structure.
 817 *
 818 * @param coredev pointer to a coredev object returned by
 819 *                smscore_register_device
 820 *
 821 * return: 0 on success, <0 on error.
 822 */
 823static int smscore_configure_board(struct smscore_device_t *coredev)
 824{
 825        struct sms_board *board;
 826
 827        board = sms_get_board(coredev->board_id);
 828        if (!board) {
 829                pr_err("no board configuration exist.\n");
 830                return -EINVAL;
 831        }
 832
 833        if (board->mtu) {
 834                struct sms_msg_data mtu_msg;
 835                pr_debug("set max transmit unit %d\n", board->mtu);
 836
 837                mtu_msg.x_msg_header.msg_src_id = 0;
 838                mtu_msg.x_msg_header.msg_dst_id = HIF_TASK;
 839                mtu_msg.x_msg_header.msg_flags = 0;
 840                mtu_msg.x_msg_header.msg_type = MSG_SMS_SET_MAX_TX_MSG_LEN_REQ;
 841                mtu_msg.x_msg_header.msg_length = sizeof(mtu_msg);
 842                mtu_msg.msg_data[0] = board->mtu;
 843
 844                coredev->sendrequest_handler(coredev->context, &mtu_msg,
 845                                             sizeof(mtu_msg));
 846        }
 847
 848        if (board->crystal) {
 849                struct sms_msg_data crys_msg;
 850                pr_debug("set crystal value %d\n", board->crystal);
 851
 852                SMS_INIT_MSG(&crys_msg.x_msg_header,
 853                                MSG_SMS_NEW_CRYSTAL_REQ,
 854                                sizeof(crys_msg));
 855                crys_msg.msg_data[0] = board->crystal;
 856
 857                coredev->sendrequest_handler(coredev->context, &crys_msg,
 858                                             sizeof(crys_msg));
 859        }
 860
 861        return 0;
 862}
 863
 864/*
 865 * sets initial device mode and notifies client hotplugs that device is ready
 866 *
 867 * @param coredev pointer to a coredev object returned by
 868 *                smscore_register_device
 869 *
 870 * return: 0 on success, <0 on error.
 871 */
 872int smscore_start_device(struct smscore_device_t *coredev)
 873{
 874        int rc;
 875        int board_id = smscore_get_board_id(coredev);
 876        int mode = smscore_registry_getmode(coredev->devpath);
 877
 878        /* Device is initialized as DEVICE_MODE_NONE */
 879        if (board_id != SMS_BOARD_UNKNOWN && mode == DEVICE_MODE_NONE)
 880                mode = sms_get_board(board_id)->default_mode;
 881
 882        rc = smscore_set_device_mode(coredev, mode);
 883        if (rc < 0) {
 884                pr_info("set device mode failed , rc %d\n", rc);
 885                return rc;
 886        }
 887        rc = smscore_configure_board(coredev);
 888        if (rc < 0) {
 889                pr_info("configure board failed , rc %d\n", rc);
 890                return rc;
 891        }
 892
 893        mutex_lock(&g_smscore_deviceslock);
 894
 895        rc = smscore_notify_callbacks(coredev, coredev->device, 1);
 896        smscore_init_ir(coredev);
 897
 898        pr_debug("device %p started, rc %d\n", coredev, rc);
 899
 900        mutex_unlock(&g_smscore_deviceslock);
 901
 902        return rc;
 903}
 904EXPORT_SYMBOL_GPL(smscore_start_device);
 905
 906
 907static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
 908                                         void *buffer, size_t size)
 909{
 910        struct sms_firmware *firmware = (struct sms_firmware *) buffer;
 911        struct sms_msg_data5 *msg;
 912        u32 mem_address,  calc_checksum = 0;
 913        u32 i, *ptr;
 914        u8 *payload = firmware->payload;
 915        int rc = 0;
 916        firmware->start_address = le32_to_cpup((__le32 *)&firmware->start_address);
 917        firmware->length = le32_to_cpup((__le32 *)&firmware->length);
 918
 919        mem_address = firmware->start_address;
 920
 921        pr_debug("loading FW to addr 0x%x size %d\n",
 922                 mem_address, firmware->length);
 923        if (coredev->preload_handler) {
 924                rc = coredev->preload_handler(coredev->context);
 925                if (rc < 0)
 926                        return rc;
 927        }
 928
 929        /* PAGE_SIZE buffer shall be enough and dma aligned */
 930        msg = kmalloc(PAGE_SIZE, GFP_KERNEL | coredev->gfp_buf_flags);
 931        if (!msg)
 932                return -ENOMEM;
 933
 934        if (coredev->mode != DEVICE_MODE_NONE) {
 935                pr_debug("sending reload command.\n");
 936                SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_START_REQ,
 937                             sizeof(struct sms_msg_hdr));
 938                rc = smscore_sendrequest_and_wait(coredev, msg,
 939                                                  msg->x_msg_header.msg_length,
 940                                                  &coredev->reload_start_done);
 941                if (rc < 0) {
 942                        pr_err("device reload failed, rc %d\n", rc);
 943                        goto exit_fw_download;
 944                }
 945                mem_address = *(u32 *) &payload[20];
 946        }
 947
 948        for (i = 0, ptr = (u32 *)firmware->payload; i < firmware->length/4 ;
 949             i++, ptr++)
 950                calc_checksum += *ptr;
 951
 952        while (size && rc >= 0) {
 953                struct sms_data_download *data_msg =
 954                        (struct sms_data_download *) msg;
 955                int payload_size = min_t(int, size, SMS_MAX_PAYLOAD_SIZE);
 956
 957                SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_DOWNLOAD_REQ,
 958                             (u16)(sizeof(struct sms_msg_hdr) +
 959                                      sizeof(u32) + payload_size));
 960
 961                data_msg->mem_addr = mem_address;
 962                memcpy(data_msg->payload, payload, payload_size);
 963
 964                rc = smscore_sendrequest_and_wait(coredev, data_msg,
 965                                data_msg->x_msg_header.msg_length,
 966                                &coredev->data_download_done);
 967
 968                payload += payload_size;
 969                size -= payload_size;
 970                mem_address += payload_size;
 971        }
 972
 973        if (rc < 0)
 974                goto exit_fw_download;
 975
 976        pr_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x\n",
 977                calc_checksum);
 978        SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ,
 979                        sizeof(msg->x_msg_header) +
 980                        sizeof(u32) * 3);
 981        msg->msg_data[0] = firmware->start_address;
 982                /* Entry point */
 983        msg->msg_data[1] = firmware->length;
 984        msg->msg_data[2] = 0; /* Regular checksum*/
 985        rc = smscore_sendrequest_and_wait(coredev, msg,
 986                                          msg->x_msg_header.msg_length,
 987                                          &coredev->data_validity_done);
 988        if (rc < 0)
 989                goto exit_fw_download;
 990
 991        if (coredev->mode == DEVICE_MODE_NONE) {
 992                pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n");
 993                SMS_INIT_MSG(&msg->x_msg_header,
 994                                MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
 995                                sizeof(*msg));
 996
 997                msg->msg_data[0] = firmware->start_address;
 998                                        /* Entry point */
 999                msg->msg_data[1] = 6; /* Priority */
1000                msg->msg_data[2] = 0x200; /* Stack size */
1001                msg->msg_data[3] = 0; /* Parameter */
1002                msg->msg_data[4] = 4; /* Task ID */
1003
1004                rc = smscore_sendrequest_and_wait(coredev, msg,
1005                                        msg->x_msg_header.msg_length,
1006                                        &coredev->trigger_done);
1007        } else {
1008                SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ,
1009                                sizeof(struct sms_msg_hdr));
1010                rc = coredev->sendrequest_handler(coredev->context, msg,
1011                                msg->x_msg_header.msg_length);
1012        }
1013
1014        if (rc < 0)
1015                goto exit_fw_download;
1016
1017        /*
1018         * backward compatibility - wait to device_ready_done for
1019         * not more than 400 ms
1020         */
1021        msleep(400);
1022
1023exit_fw_download:
1024        kfree(msg);
1025
1026        if (coredev->postload_handler) {
1027                pr_debug("rc=%d, postload=0x%p\n",
1028                         rc, coredev->postload_handler);
1029                if (rc >= 0)
1030                        return coredev->postload_handler(coredev->context);
1031        }
1032
1033        pr_debug("rc=%d\n", rc);
1034        return rc;
1035}
1036
1037static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = {
1038        [SMS_NOVA_A0] = {
1039                [DEVICE_MODE_DVBT]              = SMS_FW_DVB_NOVA_12MHZ,
1040                [DEVICE_MODE_DVBH]              = SMS_FW_DVB_NOVA_12MHZ,
1041                [DEVICE_MODE_DAB_TDMB]          = SMS_FW_TDMB_NOVA_12MHZ,
1042                [DEVICE_MODE_DVBT_BDA]          = SMS_FW_DVB_NOVA_12MHZ,
1043                [DEVICE_MODE_ISDBT]             = SMS_FW_ISDBT_NOVA_12MHZ,
1044                [DEVICE_MODE_ISDBT_BDA]         = SMS_FW_ISDBT_NOVA_12MHZ,
1045        },
1046        [SMS_NOVA_B0] = {
1047                [DEVICE_MODE_DVBT]              = SMS_FW_DVB_NOVA_12MHZ_B0,
1048                [DEVICE_MODE_DVBH]              = SMS_FW_DVB_NOVA_12MHZ_B0,
1049                [DEVICE_MODE_DAB_TDMB]          = SMS_FW_TDMB_NOVA_12MHZ_B0,
1050                [DEVICE_MODE_DVBT_BDA]          = SMS_FW_DVB_NOVA_12MHZ_B0,
1051                [DEVICE_MODE_ISDBT]             = SMS_FW_ISDBT_NOVA_12MHZ_B0,
1052                [DEVICE_MODE_ISDBT_BDA]         = SMS_FW_ISDBT_NOVA_12MHZ_B0,
1053                [DEVICE_MODE_FM_RADIO]          = SMS_FW_FM_RADIO,
1054                [DEVICE_MODE_FM_RADIO_BDA]      = SMS_FW_FM_RADIO,
1055        },
1056        [SMS_VEGA] = {
1057                [DEVICE_MODE_CMMB]              = SMS_FW_CMMB_VEGA_12MHZ,
1058        },
1059        [SMS_VENICE] = {
1060                [DEVICE_MODE_CMMB]              = SMS_FW_CMMB_VENICE_12MHZ,
1061        },
1062        [SMS_MING] = {
1063                [DEVICE_MODE_CMMB]              = SMS_FW_CMMB_MING_APP,
1064        },
1065        [SMS_PELE] = {
1066                [DEVICE_MODE_ISDBT]             = SMS_FW_ISDBT_PELE,
1067                [DEVICE_MODE_ISDBT_BDA]         = SMS_FW_ISDBT_PELE,
1068        },
1069        [SMS_RIO] = {
1070                [DEVICE_MODE_DVBT]              = SMS_FW_DVB_RIO,
1071                [DEVICE_MODE_DVBH]              = SMS_FW_DVBH_RIO,
1072                [DEVICE_MODE_DVBT_BDA]          = SMS_FW_DVB_RIO,
1073                [DEVICE_MODE_ISDBT]             = SMS_FW_ISDBT_RIO,
1074                [DEVICE_MODE_ISDBT_BDA]         = SMS_FW_ISDBT_RIO,
1075                [DEVICE_MODE_FM_RADIO]          = SMS_FW_FM_RADIO_RIO,
1076                [DEVICE_MODE_FM_RADIO_BDA]      = SMS_FW_FM_RADIO_RIO,
1077        },
1078        [SMS_DENVER_1530] = {
1079                [DEVICE_MODE_ATSC]              = SMS_FW_ATSC_DENVER,
1080        },
1081        [SMS_DENVER_2160] = {
1082                [DEVICE_MODE_DAB_TDMB]          = SMS_FW_TDMB_DENVER,
1083        },
1084};
1085
1086/*
1087 * get firmware file name from one of the two mechanisms : sms_boards or
1088 * smscore_fw_lkup.
1089 * @param coredev pointer to a coredev object returned by
1090 *                smscore_register_device
1091 * @param mode requested mode of operation
1092 * @param lookup if 1, always get the fw filename from smscore_fw_lkup
1093 *       table. if 0, try first to get from sms_boards
1094 *
1095 * return: 0 on success, <0 on error.
1096 */
1097static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
1098                              int mode)
1099{
1100        char **fw;
1101        int board_id = smscore_get_board_id(coredev);
1102        enum sms_device_type_st type;
1103
1104        type = smscore_registry_gettype(coredev->devpath);
1105
1106        /* Prevent looking outside the smscore_fw_lkup table */
1107        if (type <= SMS_UNKNOWN_TYPE || type >= SMS_NUM_OF_DEVICE_TYPES)
1108                return NULL;
1109        if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX)
1110                return NULL;
1111
1112        pr_debug("trying to get fw name from sms_boards board_id %d mode %d\n",
1113                  board_id, mode);
1114        fw = sms_get_board(board_id)->fw;
1115        if (!fw || !fw[mode]) {
1116                pr_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d\n",
1117                          mode, type);
1118                return smscore_fw_lkup[type][mode];
1119        }
1120
1121        return fw[mode];
1122}
1123
1124/*
1125 * loads specified firmware into a buffer and calls device loadfirmware_handler
1126 *
1127 * @param coredev pointer to a coredev object returned by
1128 *                smscore_register_device
1129 * @param filename null-terminated string specifies firmware file name
1130 * @param loadfirmware_handler device handler that loads firmware
1131 *
1132 * return: 0 on success, <0 on error.
1133 */
1134static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
1135                                           int mode,
1136                                           loadfirmware_t loadfirmware_handler)
1137{
1138        int rc = -ENOENT;
1139        u8 *fw_buf;
1140        u32 fw_buf_size;
1141        const struct firmware *fw;
1142
1143        char *fw_filename = smscore_get_fw_filename(coredev, mode);
1144        if (!fw_filename) {
1145                pr_err("mode %d not supported on this device\n", mode);
1146                return -ENOENT;
1147        }
1148        pr_debug("Firmware name: %s\n", fw_filename);
1149
1150        if (!loadfirmware_handler &&
1151            !(coredev->device_flags & SMS_DEVICE_FAMILY2))
1152                return -EINVAL;
1153
1154        rc = request_firmware(&fw, fw_filename, coredev->device);
1155        if (rc < 0) {
1156                pr_err("failed to open firmware file '%s'\n", fw_filename);
1157                return rc;
1158        }
1159        pr_debug("read fw %s, buffer size=0x%zx\n", fw_filename, fw->size);
1160        fw_buf = kmalloc(ALIGN(fw->size + sizeof(struct sms_firmware),
1161                         SMS_ALLOC_ALIGNMENT), GFP_KERNEL | coredev->gfp_buf_flags);
1162        if (!fw_buf) {
1163                pr_err("failed to allocate firmware buffer\n");
1164                rc = -ENOMEM;
1165        } else {
1166                memcpy(fw_buf, fw->data, fw->size);
1167                fw_buf_size = fw->size;
1168
1169                rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
1170                        smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
1171                        : loadfirmware_handler(coredev->context, fw_buf,
1172                        fw_buf_size);
1173        }
1174
1175        kfree(fw_buf);
1176        release_firmware(fw);
1177
1178        return rc;
1179}
1180
1181/*
1182 * notifies all clients registered with the device, notifies hotplugs,
1183 * frees all buffers and coredev object
1184 *
1185 * @param coredev pointer to a coredev object returned by
1186 *                smscore_register_device
1187 *
1188 * return: 0 on success, <0 on error.
1189 */
1190void smscore_unregister_device(struct smscore_device_t *coredev)
1191{
1192        struct smscore_buffer_t *cb;
1193        int num_buffers = 0;
1194        int retry = 0;
1195
1196        mutex_lock(&g_smscore_deviceslock);
1197
1198        /* Release input device (IR) resources */
1199        sms_ir_exit(coredev);
1200
1201        smscore_notify_clients(coredev);
1202        smscore_notify_callbacks(coredev, NULL, 0);
1203
1204        /* at this point all buffers should be back
1205         * onresponse must no longer be called */
1206
1207        while (1) {
1208                while (!list_empty(&coredev->buffers)) {
1209                        cb = (struct smscore_buffer_t *) coredev->buffers.next;
1210                        list_del(&cb->entry);
1211                        kfree(cb);
1212                        num_buffers++;
1213                }
1214                if (num_buffers == coredev->num_buffers)
1215                        break;
1216                if (++retry > 10) {
1217                        pr_info("exiting although not all buffers released.\n");
1218                        break;
1219                }
1220
1221                pr_debug("waiting for %d buffer(s)\n",
1222                         coredev->num_buffers - num_buffers);
1223                mutex_unlock(&g_smscore_deviceslock);
1224                msleep(100);
1225                mutex_lock(&g_smscore_deviceslock);
1226        }
1227
1228        pr_debug("freed %d buffers\n", num_buffers);
1229
1230        if (coredev->common_buffer) {
1231                if (coredev->usb_device)
1232                        kfree(coredev->common_buffer);
1233                else
1234                        dma_free_coherent(coredev->device,
1235                                          coredev->common_buffer_size,
1236                                          coredev->common_buffer,
1237                                          coredev->common_buffer_phys);
1238        }
1239        kfree(coredev->fw_buf);
1240
1241        list_del(&coredev->entry);
1242        kfree(coredev);
1243
1244        mutex_unlock(&g_smscore_deviceslock);
1245
1246        pr_debug("device %p destroyed\n", coredev);
1247}
1248EXPORT_SYMBOL_GPL(smscore_unregister_device);
1249
1250static int smscore_detect_mode(struct smscore_device_t *coredev)
1251{
1252        void *buffer = kmalloc(sizeof(struct sms_msg_hdr) + SMS_DMA_ALIGNMENT,
1253                               GFP_KERNEL | coredev->gfp_buf_flags);
1254        struct sms_msg_hdr *msg =
1255                (struct sms_msg_hdr *) SMS_ALIGN_ADDRESS(buffer);
1256        int rc;
1257
1258        if (!buffer)
1259                return -ENOMEM;
1260
1261        SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
1262                     sizeof(struct sms_msg_hdr));
1263
1264        rc = smscore_sendrequest_and_wait(coredev, msg, msg->msg_length,
1265                                          &coredev->version_ex_done);
1266        if (rc == -ETIME) {
1267                pr_err("MSG_SMS_GET_VERSION_EX_REQ failed first try\n");
1268
1269                if (wait_for_completion_timeout(&coredev->resume_done,
1270                                                msecs_to_jiffies(5000))) {
1271                        rc = smscore_sendrequest_and_wait(
1272                                coredev, msg, msg->msg_length,
1273                                &coredev->version_ex_done);
1274                        if (rc < 0)
1275                                pr_err("MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n",
1276                                        rc);
1277                } else
1278                        rc = -ETIME;
1279        }
1280
1281        kfree(buffer);
1282
1283        return rc;
1284}
1285
1286/*
1287 * send init device request and wait for response
1288 *
1289 * @param coredev pointer to a coredev object returned by
1290 *                smscore_register_device
1291 * @param mode requested mode of operation
1292 *
1293 * return: 0 on success, <0 on error.
1294 */
1295static int smscore_init_device(struct smscore_device_t *coredev, int mode)
1296{
1297        void *buffer;
1298        struct sms_msg_data *msg;
1299        int rc = 0;
1300
1301        buffer = kmalloc(sizeof(struct sms_msg_data) +
1302                        SMS_DMA_ALIGNMENT, GFP_KERNEL | coredev->gfp_buf_flags);
1303        if (!buffer)
1304                return -ENOMEM;
1305
1306        msg = (struct sms_msg_data *)SMS_ALIGN_ADDRESS(buffer);
1307        SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
1308                        sizeof(struct sms_msg_data));
1309        msg->msg_data[0] = mode;
1310
1311        rc = smscore_sendrequest_and_wait(coredev, msg,
1312                        msg->x_msg_header. msg_length,
1313                        &coredev->init_device_done);
1314
1315        kfree(buffer);
1316        return rc;
1317}
1318
1319/*
1320 * calls device handler to change mode of operation
1321 * NOTE: stellar/usb may disconnect when changing mode
1322 *
1323 * @param coredev pointer to a coredev object returned by
1324 *                smscore_register_device
1325 * @param mode requested mode of operation
1326 *
1327 * return: 0 on success, <0 on error.
1328 */
1329int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
1330{
1331        int rc = 0;
1332
1333        pr_debug("set device mode to %d\n", mode);
1334        if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
1335                if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
1336                        pr_err("invalid mode specified %d\n", mode);
1337                        return -EINVAL;
1338                }
1339
1340                smscore_registry_setmode(coredev->devpath, mode);
1341
1342                if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
1343                        rc = smscore_detect_mode(coredev);
1344                        if (rc < 0) {
1345                                pr_err("mode detect failed %d\n", rc);
1346                                return rc;
1347                        }
1348                }
1349
1350                if (coredev->mode == mode) {
1351                        pr_debug("device mode %d already set\n", mode);
1352                        return 0;
1353                }
1354
1355                if (!(coredev->modes_supported & (1 << mode))) {
1356                        rc = smscore_load_firmware_from_file(coredev,
1357                                                             mode, NULL);
1358                        if (rc >= 0)
1359                                pr_debug("firmware download success\n");
1360                } else {
1361                        pr_debug("mode %d is already supported by running firmware\n",
1362                                 mode);
1363                }
1364                if (coredev->fw_version >= 0x800) {
1365                        rc = smscore_init_device(coredev, mode);
1366                        if (rc < 0)
1367                                pr_err("device init failed, rc %d.\n", rc);
1368                }
1369        } else {
1370                if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
1371                        pr_err("invalid mode specified %d\n", mode);
1372                        return -EINVAL;
1373                }
1374
1375                smscore_registry_setmode(coredev->devpath, mode);
1376
1377                if (coredev->detectmode_handler)
1378                        coredev->detectmode_handler(coredev->context,
1379                                                    &coredev->mode);
1380
1381                if (coredev->mode != mode && coredev->setmode_handler)
1382                        rc = coredev->setmode_handler(coredev->context, mode);
1383        }
1384
1385        if (rc >= 0) {
1386                char *buffer;
1387                coredev->mode = mode;
1388                coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
1389
1390                buffer = kmalloc(sizeof(struct sms_msg_data) +
1391                                 SMS_DMA_ALIGNMENT, GFP_KERNEL | coredev->gfp_buf_flags);
1392                if (buffer) {
1393                        struct sms_msg_data *msg = (struct sms_msg_data *) SMS_ALIGN_ADDRESS(buffer);
1394
1395                        SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
1396                                     sizeof(struct sms_msg_data));
1397                        msg->msg_data[0] = mode;
1398
1399                        rc = smscore_sendrequest_and_wait(
1400                                coredev, msg, msg->x_msg_header.msg_length,
1401                                &coredev->init_device_done);
1402
1403                        kfree(buffer);
1404                }
1405        }
1406
1407        if (rc < 0)
1408                pr_err("return error code %d.\n", rc);
1409        else
1410                pr_debug("Success setting device mode.\n");
1411
1412        return rc;
1413}
1414
1415/*
1416 * calls device handler to get current mode of operation
1417 *
1418 * @param coredev pointer to a coredev object returned by
1419 *                smscore_register_device
1420 *
1421 * return: current mode
1422 */
1423int smscore_get_device_mode(struct smscore_device_t *coredev)
1424{
1425        return coredev->mode;
1426}
1427EXPORT_SYMBOL_GPL(smscore_get_device_mode);
1428
1429/*
1430 * find client by response id & type within the clients list.
1431 * return client handle or NULL.
1432 *
1433 * @param coredev pointer to a coredev object returned by
1434 *                smscore_register_device
1435 * @param data_type client data type (SMS_DONT_CARE for all types)
1436 * @param id client id (SMS_DONT_CARE for all id)
1437 *
1438 */
1439static struct
1440smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
1441                                      int data_type, int id)
1442{
1443        struct list_head *first;
1444        struct smscore_client_t *client;
1445        unsigned long flags;
1446        struct list_head *firstid;
1447        struct smscore_idlist_t *client_id;
1448
1449        spin_lock_irqsave(&coredev->clientslock, flags);
1450        first = &coredev->clients;
1451        list_for_each_entry(client, first, entry) {
1452                firstid = &client->idlist;
1453                list_for_each_entry(client_id, firstid, entry) {
1454                        if ((client_id->id == id) &&
1455                            (client_id->data_type == data_type ||
1456                            (client_id->data_type == 0)))
1457                                goto found;
1458                }
1459        }
1460        client = NULL;
1461found:
1462        spin_unlock_irqrestore(&coredev->clientslock, flags);
1463        return client;
1464}
1465
1466/*
1467 * find client by response id/type, call clients onresponse handler
1468 * return buffer to pool on error
1469 *
1470 * @param coredev pointer to a coredev object returned by
1471 *                smscore_register_device
1472 * @param cb pointer to response buffer descriptor
1473 *
1474 */
1475void smscore_onresponse(struct smscore_device_t *coredev,
1476                struct smscore_buffer_t *cb) {
1477        struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) ((u8 *) cb->p
1478                        + cb->offset);
1479        struct smscore_client_t *client;
1480        int rc = -EBUSY;
1481        static unsigned long last_sample_time; /* = 0; */
1482        static int data_total; /* = 0; */
1483        unsigned long time_now = jiffies_to_msecs(jiffies);
1484
1485        if (!last_sample_time)
1486                last_sample_time = time_now;
1487
1488        if (time_now - last_sample_time > 10000) {
1489                pr_debug("data rate %d bytes/secs\n",
1490                          (int)((data_total * 1000) /
1491                                (time_now - last_sample_time)));
1492
1493                last_sample_time = time_now;
1494                data_total = 0;
1495        }
1496
1497        data_total += cb->size;
1498        /* Do we need to re-route? */
1499        if ((phdr->msg_type == MSG_SMS_HO_PER_SLICES_IND) ||
1500                        (phdr->msg_type == MSG_SMS_TRANSMISSION_IND)) {
1501                if (coredev->mode == DEVICE_MODE_DVBT_BDA)
1502                        phdr->msg_dst_id = DVBT_BDA_CONTROL_MSG_ID;
1503        }
1504
1505
1506        client = smscore_find_client(coredev, phdr->msg_type, phdr->msg_dst_id);
1507
1508        /* If no client registered for type & id,
1509         * check for control client where type is not registered */
1510        if (client)
1511                rc = client->onresponse_handler(client->context, cb);
1512
1513        if (rc < 0) {
1514                switch (phdr->msg_type) {
1515                case MSG_SMS_ISDBT_TUNE_RES:
1516                        break;
1517                case MSG_SMS_RF_TUNE_RES:
1518                        break;
1519                case MSG_SMS_SIGNAL_DETECTED_IND:
1520                        break;
1521                case MSG_SMS_NO_SIGNAL_IND:
1522                        break;
1523                case MSG_SMS_SPI_INT_LINE_SET_RES:
1524                        break;
1525                case MSG_SMS_INTERFACE_LOCK_IND:
1526                        break;
1527                case MSG_SMS_INTERFACE_UNLOCK_IND:
1528                        break;
1529                case MSG_SMS_GET_VERSION_EX_RES:
1530                {
1531                        struct sms_version_res *ver =
1532                                (struct sms_version_res *) phdr;
1533                        pr_debug("Firmware id %d prots 0x%x ver %d.%d\n",
1534                                  ver->firmware_id, ver->supported_protocols,
1535                                  ver->rom_ver_major, ver->rom_ver_minor);
1536
1537                        coredev->mode = ver->firmware_id == 255 ?
1538                                DEVICE_MODE_NONE : ver->firmware_id;
1539                        coredev->modes_supported = ver->supported_protocols;
1540                        coredev->fw_version = ver->rom_ver_major << 8 |
1541                                              ver->rom_ver_minor;
1542
1543                        complete(&coredev->version_ex_done);
1544                        break;
1545                }
1546                case MSG_SMS_INIT_DEVICE_RES:
1547                        complete(&coredev->init_device_done);
1548                        break;
1549                case MSG_SW_RELOAD_START_RES:
1550                        complete(&coredev->reload_start_done);
1551                        break;
1552                case MSG_SMS_DATA_VALIDITY_RES:
1553                {
1554                        struct sms_msg_data *validity = (struct sms_msg_data *) phdr;
1555
1556                        pr_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x\n",
1557                                validity->msg_data[0]);
1558                        complete(&coredev->data_validity_done);
1559                        break;
1560                }
1561                case MSG_SMS_DATA_DOWNLOAD_RES:
1562                        complete(&coredev->data_download_done);
1563                        break;
1564                case MSG_SW_RELOAD_EXEC_RES:
1565                        break;
1566                case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
1567                        complete(&coredev->trigger_done);
1568                        break;
1569                case MSG_SMS_SLEEP_RESUME_COMP_IND:
1570                        complete(&coredev->resume_done);
1571                        break;
1572                case MSG_SMS_GPIO_CONFIG_EX_RES:
1573                        complete(&coredev->gpio_configuration_done);
1574                        break;
1575                case MSG_SMS_GPIO_SET_LEVEL_RES:
1576                        complete(&coredev->gpio_set_level_done);
1577                        break;
1578                case MSG_SMS_GPIO_GET_LEVEL_RES:
1579                {
1580                        u32 *msgdata = (u32 *) phdr;
1581                        coredev->gpio_get_res = msgdata[1];
1582                        pr_debug("gpio level %d\n",
1583                                        coredev->gpio_get_res);
1584                        complete(&coredev->gpio_get_level_done);
1585                        break;
1586                }
1587                case MSG_SMS_START_IR_RES:
1588                        complete(&coredev->ir_init_done);
1589                        break;
1590                case MSG_SMS_IR_SAMPLES_IND:
1591                        sms_ir_event(coredev,
1592                                (const char *)
1593                                ((char *)phdr
1594                                + sizeof(struct sms_msg_hdr)),
1595                                (int)phdr->msg_length
1596                                - sizeof(struct sms_msg_hdr));
1597                        break;
1598
1599                case MSG_SMS_DVBT_BDA_DATA:
1600                        /*
1601                         * It can be received here, if the frontend is
1602                         * tuned into a valid channel and the proper firmware
1603                         * is loaded. That happens when the module got removed
1604                         * and re-inserted, without powering the device off
1605                         */
1606                        break;
1607
1608                default:
1609                        pr_debug("message %s(%d) not handled.\n",
1610                                  smscore_translate_msg(phdr->msg_type),
1611                                  phdr->msg_type);
1612                        break;
1613                }
1614                smscore_putbuffer(coredev, cb);
1615        }
1616}
1617EXPORT_SYMBOL_GPL(smscore_onresponse);
1618
1619/*
1620 * return pointer to next free buffer descriptor from core pool
1621 *
1622 * @param coredev pointer to a coredev object returned by
1623 *                smscore_register_device
1624 *
1625 * return: pointer to descriptor on success, NULL on error.
1626 */
1627
1628static struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
1629{
1630        struct smscore_buffer_t *cb = NULL;
1631        unsigned long flags;
1632
1633        spin_lock_irqsave(&coredev->bufferslock, flags);
1634        if (!list_empty(&coredev->buffers)) {
1635                cb = (struct smscore_buffer_t *) coredev->buffers.next;
1636                list_del(&cb->entry);
1637        }
1638        spin_unlock_irqrestore(&coredev->bufferslock, flags);
1639        return cb;
1640}
1641
1642struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1643{
1644        struct smscore_buffer_t *cb = NULL;
1645
1646        wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
1647
1648        return cb;
1649}
1650EXPORT_SYMBOL_GPL(smscore_getbuffer);
1651
1652/*
1653 * return buffer descriptor to a pool
1654 *
1655 * @param coredev pointer to a coredev object returned by
1656 *                smscore_register_device
1657 * @param cb pointer buffer descriptor
1658 *
1659 */
1660void smscore_putbuffer(struct smscore_device_t *coredev,
1661                struct smscore_buffer_t *cb) {
1662        wake_up_interruptible(&coredev->buffer_mng_waitq);
1663        list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1664}
1665EXPORT_SYMBOL_GPL(smscore_putbuffer);
1666
1667static int smscore_validate_client(struct smscore_device_t *coredev,
1668                                   struct smscore_client_t *client,
1669                                   int data_type, int id)
1670{
1671        struct smscore_idlist_t *listentry;
1672        struct smscore_client_t *registered_client;
1673
1674        if (!client) {
1675                pr_err("bad parameter.\n");
1676                return -EINVAL;
1677        }
1678        registered_client = smscore_find_client(coredev, data_type, id);
1679        if (registered_client == client)
1680                return 0;
1681
1682        if (registered_client) {
1683                pr_err("The msg ID already registered to another client.\n");
1684                return -EEXIST;
1685        }
1686        listentry = kzalloc(sizeof(*listentry), GFP_KERNEL);
1687        if (!listentry)
1688                return -ENOMEM;
1689
1690        listentry->id = id;
1691        listentry->data_type = data_type;
1692        list_add_locked(&listentry->entry, &client->idlist,
1693                        &coredev->clientslock);
1694        return 0;
1695}
1696
1697/*
1698 * creates smsclient object, check that id is taken by another client
1699 *
1700 * @param coredev pointer to a coredev object from clients hotplug
1701 * @param initial_id all messages with this id would be sent to this client
1702 * @param data_type all messages of this type would be sent to this client
1703 * @param onresponse_handler client handler that is called to
1704 *                           process incoming messages
1705 * @param onremove_handler client handler that is called when device is removed
1706 * @param context client-specific context
1707 * @param client pointer to a value that receives created smsclient object
1708 *
1709 * return: 0 on success, <0 on error.
1710 */
1711int smscore_register_client(struct smscore_device_t *coredev,
1712                            struct smsclient_params_t *params,
1713                            struct smscore_client_t **client)
1714{
1715        struct smscore_client_t *newclient;
1716        /* check that no other channel with same parameters exists */
1717        if (smscore_find_client(coredev, params->data_type,
1718                                params->initial_id)) {
1719                pr_err("Client already exist.\n");
1720                return -EEXIST;
1721        }
1722
1723        newclient = kzalloc(sizeof(*newclient), GFP_KERNEL);
1724        if (!newclient)
1725                return -ENOMEM;
1726
1727        INIT_LIST_HEAD(&newclient->idlist);
1728        newclient->coredev = coredev;
1729        newclient->onresponse_handler = params->onresponse_handler;
1730        newclient->onremove_handler = params->onremove_handler;
1731        newclient->context = params->context;
1732        list_add_locked(&newclient->entry, &coredev->clients,
1733                        &coredev->clientslock);
1734        smscore_validate_client(coredev, newclient, params->data_type,
1735                                params->initial_id);
1736        *client = newclient;
1737        pr_debug("%p %d %d\n", params->context, params->data_type,
1738                  params->initial_id);
1739
1740        return 0;
1741}
1742EXPORT_SYMBOL_GPL(smscore_register_client);
1743
1744/*
1745 * frees smsclient object and all subclients associated with it
1746 *
1747 * @param client pointer to smsclient object returned by
1748 *               smscore_register_client
1749 *
1750 */
1751void smscore_unregister_client(struct smscore_client_t *client)
1752{
1753        struct smscore_device_t *coredev = client->coredev;
1754        unsigned long flags;
1755
1756        spin_lock_irqsave(&coredev->clientslock, flags);
1757
1758
1759        while (!list_empty(&client->idlist)) {
1760                struct smscore_idlist_t *identry =
1761                        (struct smscore_idlist_t *) client->idlist.next;
1762                list_del(&identry->entry);
1763                kfree(identry);
1764        }
1765
1766        pr_debug("%p\n", client->context);
1767
1768        list_del(&client->entry);
1769        kfree(client);
1770
1771        spin_unlock_irqrestore(&coredev->clientslock, flags);
1772}
1773EXPORT_SYMBOL_GPL(smscore_unregister_client);
1774
1775/*
1776 * verifies that source id is not taken by another client,
1777 * calls device handler to send requests to the device
1778 *
1779 * @param client pointer to smsclient object returned by
1780 *               smscore_register_client
1781 * @param buffer pointer to a request buffer
1782 * @param size size (in bytes) of request buffer
1783 *
1784 * return: 0 on success, <0 on error.
1785 */
1786int smsclient_sendrequest(struct smscore_client_t *client,
1787                          void *buffer, size_t size)
1788{
1789        struct smscore_device_t *coredev;
1790        struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer;
1791        int rc;
1792
1793        if (!client) {
1794                pr_err("Got NULL client\n");
1795                return -EINVAL;
1796        }
1797
1798        coredev = client->coredev;
1799
1800        /* check that no other channel with same id exists */
1801        if (!coredev) {
1802                pr_err("Got NULL coredev\n");
1803                return -EINVAL;
1804        }
1805
1806        rc = smscore_validate_client(client->coredev, client, 0,
1807                                     phdr->msg_src_id);
1808        if (rc < 0)
1809                return rc;
1810
1811        return coredev->sendrequest_handler(coredev->context, buffer, size);
1812}
1813EXPORT_SYMBOL_GPL(smsclient_sendrequest);
1814
1815
1816/* old GPIO managements implementation */
1817int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
1818                           struct smscore_config_gpio *pinconfig)
1819{
1820        struct {
1821                struct sms_msg_hdr hdr;
1822                u32 data[6];
1823        } msg;
1824
1825        if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
1826                msg.hdr.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
1827                msg.hdr.msg_dst_id = HIF_TASK;
1828                msg.hdr.msg_flags = 0;
1829                msg.hdr.msg_type  = MSG_SMS_GPIO_CONFIG_EX_REQ;
1830                msg.hdr.msg_length = sizeof(msg);
1831
1832                msg.data[0] = pin;
1833                msg.data[1] = pinconfig->pullupdown;
1834
1835                /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
1836                msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
1837
1838                switch (pinconfig->outputdriving) {
1839                case SMS_GPIO_OUTPUTDRIVING_S_16mA:
1840                        msg.data[3] = 7; /* Nova - 16mA */
1841                        break;
1842                case SMS_GPIO_OUTPUTDRIVING_S_12mA:
1843                        msg.data[3] = 5; /* Nova - 11mA */
1844                        break;
1845                case SMS_GPIO_OUTPUTDRIVING_S_8mA:
1846                        msg.data[3] = 3; /* Nova - 7mA */
1847                        break;
1848                case SMS_GPIO_OUTPUTDRIVING_S_4mA:
1849                default:
1850                        msg.data[3] = 2; /* Nova - 4mA */
1851                        break;
1852                }
1853
1854                msg.data[4] = pinconfig->direction;
1855                msg.data[5] = 0;
1856        } else /* TODO: SMS_DEVICE_FAMILY1 */
1857                return -EINVAL;
1858
1859        return coredev->sendrequest_handler(coredev->context,
1860                                            &msg, sizeof(msg));
1861}
1862
1863int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
1864{
1865        struct {
1866                struct sms_msg_hdr hdr;
1867                u32 data[3];
1868        } msg;
1869
1870        if (pin > MAX_GPIO_PIN_NUMBER)
1871                return -EINVAL;
1872
1873        msg.hdr.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
1874        msg.hdr.msg_dst_id = HIF_TASK;
1875        msg.hdr.msg_flags = 0;
1876        msg.hdr.msg_type  = MSG_SMS_GPIO_SET_LEVEL_REQ;
1877        msg.hdr.msg_length = sizeof(msg);
1878
1879        msg.data[0] = pin;
1880        msg.data[1] = level ? 1 : 0;
1881        msg.data[2] = 0;
1882
1883        return coredev->sendrequest_handler(coredev->context,
1884                                            &msg, sizeof(msg));
1885}
1886
1887/* new GPIO management implementation */
1888static int get_gpio_pin_params(u32 pin_num, u32 *p_translatedpin_num,
1889                u32 *p_group_num, u32 *p_group_cfg) {
1890
1891        *p_group_cfg = 1;
1892
1893        if (pin_num <= 1)       {
1894                *p_translatedpin_num = 0;
1895                *p_group_num = 9;
1896                *p_group_cfg = 2;
1897        } else if (pin_num >= 2 && pin_num <= 6) {
1898                *p_translatedpin_num = 2;
1899                *p_group_num = 0;
1900                *p_group_cfg = 2;
1901        } else if (pin_num >= 7 && pin_num <= 11) {
1902                *p_translatedpin_num = 7;
1903                *p_group_num = 1;
1904        } else if (pin_num >= 12 && pin_num <= 15) {
1905                *p_translatedpin_num = 12;
1906                *p_group_num = 2;
1907                *p_group_cfg = 3;
1908        } else if (pin_num == 16) {
1909                *p_translatedpin_num = 16;
1910                *p_group_num = 23;
1911        } else if (pin_num >= 17 && pin_num <= 24) {
1912                *p_translatedpin_num = 17;
1913                *p_group_num = 3;
1914        } else if (pin_num == 25) {
1915                *p_translatedpin_num = 25;
1916                *p_group_num = 6;
1917        } else if (pin_num >= 26 && pin_num <= 28) {
1918                *p_translatedpin_num = 26;
1919                *p_group_num = 4;
1920        } else if (pin_num == 29) {
1921                *p_translatedpin_num = 29;
1922                *p_group_num = 5;
1923                *p_group_cfg = 2;
1924        } else if (pin_num == 30) {
1925                *p_translatedpin_num = 30;
1926                *p_group_num = 8;
1927        } else if (pin_num == 31) {
1928                *p_translatedpin_num = 31;
1929                *p_group_num = 17;
1930        } else
1931                return -1;
1932
1933        *p_group_cfg <<= 24;
1934
1935        return 0;
1936}
1937
1938int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num,
1939                struct smscore_config_gpio *p_gpio_config) {
1940
1941        u32 total_len;
1942        u32 translatedpin_num = 0;
1943        u32 group_num = 0;
1944        u32 electric_char;
1945        u32 group_cfg;
1946        void *buffer;
1947        int rc;
1948
1949        struct set_gpio_msg {
1950                struct sms_msg_hdr x_msg_header;
1951                u32 msg_data[6];
1952        } *p_msg;
1953
1954
1955        if (pin_num > MAX_GPIO_PIN_NUMBER)
1956                return -EINVAL;
1957
1958        if (!p_gpio_config)
1959                return -EINVAL;
1960
1961        total_len = sizeof(struct sms_msg_hdr) + (sizeof(u32) * 6);
1962
1963        buffer = kmalloc(total_len + SMS_DMA_ALIGNMENT,
1964                        GFP_KERNEL | coredev->gfp_buf_flags);
1965        if (!buffer)
1966                return -ENOMEM;
1967
1968        p_msg = (struct set_gpio_msg *) SMS_ALIGN_ADDRESS(buffer);
1969
1970        p_msg->x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
1971        p_msg->x_msg_header.msg_dst_id = HIF_TASK;
1972        p_msg->x_msg_header.msg_flags = 0;
1973        p_msg->x_msg_header.msg_length = (u16) total_len;
1974        p_msg->msg_data[0] = pin_num;
1975
1976        if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1977                p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_CONFIG_REQ;
1978                if (get_gpio_pin_params(pin_num, &translatedpin_num, &group_num,
1979                                &group_cfg) != 0) {
1980                        rc = -EINVAL;
1981                        goto free;
1982                }
1983
1984                p_msg->msg_data[1] = translatedpin_num;
1985                p_msg->msg_data[2] = group_num;
1986                electric_char = (p_gpio_config->pullupdown)
1987                                | (p_gpio_config->inputcharacteristics << 2)
1988                                | (p_gpio_config->outputslewrate << 3)
1989                                | (p_gpio_config->outputdriving << 4);
1990                p_msg->msg_data[3] = electric_char;
1991                p_msg->msg_data[4] = p_gpio_config->direction;
1992                p_msg->msg_data[5] = group_cfg;
1993        } else {
1994                p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_CONFIG_EX_REQ;
1995                p_msg->msg_data[1] = p_gpio_config->pullupdown;
1996                p_msg->msg_data[2] = p_gpio_config->outputslewrate;
1997                p_msg->msg_data[3] = p_gpio_config->outputdriving;
1998                p_msg->msg_data[4] = p_gpio_config->direction;
1999                p_msg->msg_data[5] = 0;
2000        }
2001
2002        rc = smscore_sendrequest_and_wait(coredev, p_msg, total_len,
2003                        &coredev->gpio_configuration_done);
2004
2005        if (rc != 0) {
2006                if (rc == -ETIME)
2007                        pr_err("smscore_gpio_configure timeout\n");
2008                else
2009                        pr_err("smscore_gpio_configure error\n");
2010        }
2011free:
2012        kfree(buffer);
2013
2014        return rc;
2015}
2016
2017int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 pin_num,
2018                u8 new_level) {
2019
2020        u32 total_len;
2021        int rc;
2022        void *buffer;
2023
2024        struct set_gpio_msg {
2025                struct sms_msg_hdr x_msg_header;
2026                u32 msg_data[3]; /* keep it 3 ! */
2027        } *p_msg;
2028
2029        if ((new_level > 1) || (pin_num > MAX_GPIO_PIN_NUMBER))
2030                return -EINVAL;
2031
2032        total_len = sizeof(struct sms_msg_hdr) +
2033                        (3 * sizeof(u32)); /* keep it 3 ! */
2034
2035        buffer = kmalloc(total_len + SMS_DMA_ALIGNMENT,
2036                        GFP_KERNEL | coredev->gfp_buf_flags);
2037        if (!buffer)
2038                return -ENOMEM;
2039
2040        p_msg = (struct set_gpio_msg *) SMS_ALIGN_ADDRESS(buffer);
2041
2042        p_msg->x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
2043        p_msg->x_msg_header.msg_dst_id = HIF_TASK;
2044        p_msg->x_msg_header.msg_flags = 0;
2045        p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_SET_LEVEL_REQ;
2046        p_msg->x_msg_header.msg_length = (u16) total_len;
2047        p_msg->msg_data[0] = pin_num;
2048        p_msg->msg_data[1] = new_level;
2049
2050        /* Send message to SMS */
2051        rc = smscore_sendrequest_and_wait(coredev, p_msg, total_len,
2052                        &coredev->gpio_set_level_done);
2053
2054        if (rc != 0) {
2055                if (rc == -ETIME)
2056                        pr_err("smscore_gpio_set_level timeout\n");
2057                else
2058                        pr_err("smscore_gpio_set_level error\n");
2059        }
2060        kfree(buffer);
2061
2062        return rc;
2063}
2064
2065int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
2066                u8 *level) {
2067
2068        u32 total_len;
2069        int rc;
2070        void *buffer;
2071
2072        struct set_gpio_msg {
2073                struct sms_msg_hdr x_msg_header;
2074                u32 msg_data[2];
2075        } *p_msg;
2076
2077
2078        if (pin_num > MAX_GPIO_PIN_NUMBER)
2079                return -EINVAL;
2080
2081        total_len = sizeof(struct sms_msg_hdr) + (2 * sizeof(u32));
2082
2083        buffer = kmalloc(total_len + SMS_DMA_ALIGNMENT,
2084                        GFP_KERNEL | coredev->gfp_buf_flags);
2085        if (!buffer)
2086                return -ENOMEM;
2087
2088        p_msg = (struct set_gpio_msg *) SMS_ALIGN_ADDRESS(buffer);
2089
2090        p_msg->x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
2091        p_msg->x_msg_header.msg_dst_id = HIF_TASK;
2092        p_msg->x_msg_header.msg_flags = 0;
2093        p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_GET_LEVEL_REQ;
2094        p_msg->x_msg_header.msg_length = (u16) total_len;
2095        p_msg->msg_data[0] = pin_num;
2096        p_msg->msg_data[1] = 0;
2097
2098        /* Send message to SMS */
2099        rc = smscore_sendrequest_and_wait(coredev, p_msg, total_len,
2100                        &coredev->gpio_get_level_done);
2101
2102        if (rc != 0) {
2103                if (rc == -ETIME)
2104                        pr_err("smscore_gpio_get_level timeout\n");
2105                else
2106                        pr_err("smscore_gpio_get_level error\n");
2107        }
2108        kfree(buffer);
2109
2110        /* Its a race between other gpio_get_level() and the copy of the single
2111         * global 'coredev->gpio_get_res' to  the function's variable 'level'
2112         */
2113        *level = coredev->gpio_get_res;
2114
2115        return rc;
2116}
2117
2118static int __init smscore_module_init(void)
2119{
2120        INIT_LIST_HEAD(&g_smscore_notifyees);
2121        INIT_LIST_HEAD(&g_smscore_devices);
2122        INIT_LIST_HEAD(&g_smscore_registry);
2123
2124        return 0;
2125}
2126
2127static void __exit smscore_module_exit(void)
2128{
2129        mutex_lock(&g_smscore_deviceslock);
2130        while (!list_empty(&g_smscore_notifyees)) {
2131                struct smscore_device_notifyee_t *notifyee =
2132                        (struct smscore_device_notifyee_t *)
2133                                g_smscore_notifyees.next;
2134
2135                list_del(&notifyee->entry);
2136                kfree(notifyee);
2137        }
2138        mutex_unlock(&g_smscore_deviceslock);
2139
2140        mutex_lock(&g_smscore_registrylock);
2141        while (!list_empty(&g_smscore_registry)) {
2142                struct smscore_registry_entry_t *entry =
2143                        (struct smscore_registry_entry_t *)
2144                                g_smscore_registry.next;
2145
2146                list_del(&entry->entry);
2147                kfree(entry);
2148        }
2149        mutex_unlock(&g_smscore_registrylock);
2150
2151        pr_debug("\n");
2152}
2153
2154module_init(smscore_module_init);
2155module_exit(smscore_module_exit);
2156
2157MODULE_DESCRIPTION("Siano MDTV Core module");
2158MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
2159MODULE_LICENSE("GPL");
2160
2161/* This should match what's defined at smscoreapi.h */
2162MODULE_FIRMWARE(SMS_FW_ATSC_DENVER);
2163MODULE_FIRMWARE(SMS_FW_CMMB_MING_APP);
2164MODULE_FIRMWARE(SMS_FW_CMMB_VEGA_12MHZ);
2165MODULE_FIRMWARE(SMS_FW_CMMB_VENICE_12MHZ);
2166MODULE_FIRMWARE(SMS_FW_DVBH_RIO);
2167MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ_B0);
2168MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ);
2169MODULE_FIRMWARE(SMS_FW_DVB_RIO);
2170MODULE_FIRMWARE(SMS_FW_FM_RADIO);
2171MODULE_FIRMWARE(SMS_FW_FM_RADIO_RIO);
2172MODULE_FIRMWARE(SMS_FW_DVBT_HCW_55XXX);
2173MODULE_FIRMWARE(SMS_FW_ISDBT_HCW_55XXX);
2174MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ_B0);
2175MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ);
2176MODULE_FIRMWARE(SMS_FW_ISDBT_PELE);
2177MODULE_FIRMWARE(SMS_FW_ISDBT_RIO);
2178MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_A);
2179MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_B);
2180MODULE_FIRMWARE(SMS_FW_DVBT_STELLAR);
2181MODULE_FIRMWARE(SMS_FW_TDMB_DENVER);
2182MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ_B0);
2183MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ);
2184