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 | |
30 | struct smscore_device_notifyee_t { |
31 | struct list_head entry; |
32 | hotplug_t hotplug; |
33 | }; |
34 | |
35 | struct smscore_idlist_t { |
36 | struct list_head entry; |
37 | int id; |
38 | int data_type; |
39 | }; |
40 | |
41 | struct 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 | |
50 | static 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 | |
372 | char *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 | } |
387 | EXPORT_SYMBOL_GPL(smscore_translate_msg); |
388 | |
389 | void smscore_set_board_id(struct smscore_device_t *core, int id) |
390 | { |
391 | core->board_id = id; |
392 | } |
393 | |
394 | int 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 | } |
400 | EXPORT_SYMBOL_GPL(smscore_set_board_id); |
401 | |
402 | int smscore_get_board_id(struct smscore_device_t *core) |
403 | { |
404 | return core->board_id; |
405 | } |
406 | EXPORT_SYMBOL_GPL(smscore_get_board_id); |
407 | |
408 | struct 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 | |
415 | static struct list_head g_smscore_notifyees; |
416 | static struct list_head g_smscore_devices; |
417 | static DEFINE_MUTEX(g_smscore_deviceslock); |
418 | |
419 | static struct list_head g_smscore_registry; |
420 | static DEFINE_MUTEX(g_smscore_registrylock); |
421 | |
422 | static int default_mode = DEVICE_MODE_NONE; |
423 | |
424 | module_param(default_mode, int, 0644); |
425 | MODULE_PARM_DESC(default_mode, "default firmware id (device mode)" ); |
426 | |
427 | static 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(lock: &g_smscore_registrylock); |
439 | return entry; |
440 | } |
441 | } |
442 | entry = kmalloc(size: sizeof(*entry), GFP_KERNEL); |
443 | if (entry) { |
444 | entry->mode = default_mode; |
445 | strscpy(entry->devpath, devpath, sizeof(entry->devpath)); |
446 | list_add(new: &entry->entry, head: &g_smscore_registry); |
447 | } else |
448 | pr_err("failed to create smscore_registry.\n" ); |
449 | mutex_unlock(lock: &g_smscore_registrylock); |
450 | return entry; |
451 | } |
452 | |
453 | int 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 | } |
465 | EXPORT_SYMBOL_GPL(smscore_registry_getmode); |
466 | |
467 | static 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 | |
480 | static 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 | |
491 | static 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 | |
504 | static 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 | */ |
524 | int 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(size: 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(new: ¬ifyee->entry, head: &g_smscore_notifyees); |
546 | } else |
547 | kfree(objp: notifyee); |
548 | } else |
549 | rc = -ENOMEM; |
550 | |
551 | mutex_unlock(lock: &g_smscore_deviceslock); |
552 | |
553 | return rc; |
554 | } |
555 | EXPORT_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 | */ |
563 | void 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(entry: ¬ifyee->entry); |
578 | kfree(objp: notifyee); |
579 | } |
580 | } |
581 | |
582 | mutex_unlock(lock: &g_smscore_deviceslock); |
583 | } |
584 | EXPORT_SYMBOL_GPL(smscore_unregister_hotplug); |
585 | |
586 | static 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(head: &coredev->clients)) { |
592 | client = (struct smscore_client_t *) coredev->clients.next; |
593 | client->onremove_handler(client->context); |
594 | } |
595 | } |
596 | |
597 | static 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 | |
614 | static struct |
615 | smscore_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(size: 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 | */ |
642 | int 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(size: 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(list: &dev->entry); |
661 | |
662 | /* init queues */ |
663 | INIT_LIST_HEAD(list: &dev->clients); |
664 | INIT_LIST_HEAD(list: &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(x: &dev->version_ex_done); |
672 | init_completion(x: &dev->data_download_done); |
673 | init_completion(x: &dev->data_validity_done); |
674 | init_completion(x: &dev->trigger_done); |
675 | init_completion(x: &dev->init_device_done); |
676 | init_completion(x: &dev->reload_start_done); |
677 | init_completion(x: &dev->resume_done); |
678 | init_completion(x: &dev->gpio_configuration_done); |
679 | init_completion(x: &dev->gpio_set_level_done); |
680 | init_completion(x: &dev->gpio_get_level_done); |
681 | init_completion(x: &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(size: dev->common_buffer_size, GFP_KERNEL); |
690 | else |
691 | buffer = dma_alloc_coherent(dev: params->device, |
692 | size: dev->common_buffer_size, |
693 | dma_handle: &dev->common_buffer_phys, |
694 | GFP_KERNEL | dev->gfp_buf_flags); |
695 | if (!buffer) { |
696 | smscore_unregister_device(coredev: 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, common_buffer: dev->common_buffer, |
707 | common_buffer_phys: dev->common_buffer_phys); |
708 | if (!cb) { |
709 | smscore_unregister_device(coredev: dev); |
710 | return -ENOMEM; |
711 | } |
712 | |
713 | smscore_putbuffer(coredev: 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(devpath: dev->devpath, type: params->device_type); |
733 | |
734 | /* add device to devices list */ |
735 | mutex_lock(&g_smscore_deviceslock); |
736 | list_add(new: &dev->entry, head: &g_smscore_devices); |
737 | mutex_unlock(lock: &g_smscore_deviceslock); |
738 | |
739 | *coredev = dev; |
740 | |
741 | pr_debug("device %p created\n" , dev); |
742 | |
743 | return 0; |
744 | } |
745 | EXPORT_SYMBOL_GPL(smscore_register_device); |
746 | |
747 | |
748 | static 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(x: 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(x: completion, |
763 | timeout: 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 | */ |
772 | static 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(id: 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(size: 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, buffer: msg, |
802 | size: msg->x_msg_header. msg_length, |
803 | completion: &coredev->ir_init_done); |
804 | |
805 | kfree(objp: 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 | */ |
823 | static int smscore_configure_board(struct smscore_device_t *coredev) |
824 | { |
825 | struct sms_board *board; |
826 | |
827 | board = sms_get_board(id: 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 | */ |
872 | int 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(id: 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, device: coredev->device, arrival: 1); |
896 | smscore_init_ir(coredev); |
897 | |
898 | pr_debug("device %p started, rc %d\n" , coredev, rc); |
899 | |
900 | mutex_unlock(lock: &g_smscore_deviceslock); |
901 | |
902 | return rc; |
903 | } |
904 | EXPORT_SYMBOL_GPL(smscore_start_device); |
905 | |
906 | |
907 | static 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(p: (__le32 *)&firmware->start_address); |
917 | firmware->length = le32_to_cpup(p: (__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, buffer: msg, |
939 | size: msg->x_msg_header.msg_length, |
940 | completion: &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, buffer: data_msg, |
965 | size: data_msg->x_msg_header.msg_length, |
966 | completion: &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, buffer: msg, |
986 | size: msg->x_msg_header.msg_length, |
987 | completion: &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, buffer: msg, |
1005 | size: msg->x_msg_header.msg_length, |
1006 | completion: &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(msecs: 400); |
1022 | |
1023 | exit_fw_download: |
1024 | kfree(objp: 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 | |
1037 | static 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 | */ |
1097 | static 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(devpath: 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(id: 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 | */ |
1134 | static 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, name: fw_filename, device: 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, buffer: fw_buf, size: fw_buf_size) |
1171 | : loadfirmware_handler(coredev->context, fw_buf, |
1172 | fw_buf_size); |
1173 | } |
1174 | |
1175 | kfree(objp: 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 | */ |
1190 | void 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, arrival: 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(head: &coredev->buffers)) { |
1209 | cb = (struct smscore_buffer_t *) coredev->buffers.next; |
1210 | list_del(entry: &cb->entry); |
1211 | kfree(objp: 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(lock: &g_smscore_deviceslock); |
1224 | msleep(msecs: 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(objp: coredev->common_buffer); |
1233 | else |
1234 | dma_free_coherent(dev: coredev->device, |
1235 | size: coredev->common_buffer_size, |
1236 | cpu_addr: coredev->common_buffer, |
1237 | dma_handle: coredev->common_buffer_phys); |
1238 | } |
1239 | kfree(objp: coredev->fw_buf); |
1240 | |
1241 | list_del(entry: &coredev->entry); |
1242 | kfree(objp: coredev); |
1243 | |
1244 | mutex_unlock(lock: &g_smscore_deviceslock); |
1245 | |
1246 | pr_debug("device %p destroyed\n" , coredev); |
1247 | } |
1248 | EXPORT_SYMBOL_GPL(smscore_unregister_device); |
1249 | |
1250 | static int smscore_detect_mode(struct smscore_device_t *coredev) |
1251 | { |
1252 | void *buffer = kmalloc(size: 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, buffer: msg, size: msg->msg_length, |
1265 | completion: &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(x: &coredev->resume_done, |
1270 | timeout: msecs_to_jiffies(m: 5000))) { |
1271 | rc = smscore_sendrequest_and_wait( |
1272 | coredev, buffer: msg, size: msg->msg_length, |
1273 | completion: &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(objp: 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 | */ |
1295 | static 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(size: 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, buffer: msg, |
1312 | size: msg->x_msg_header. msg_length, |
1313 | completion: &coredev->init_device_done); |
1314 | |
1315 | kfree(objp: 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 | */ |
1329 | int 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(devpath: 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(devpath: 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(size: 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, buffer: msg, size: msg->x_msg_header.msg_length, |
1401 | completion: &coredev->init_device_done); |
1402 | |
1403 | kfree(objp: 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 | */ |
1423 | int smscore_get_device_mode(struct smscore_device_t *coredev) |
1424 | { |
1425 | return coredev->mode; |
1426 | } |
1427 | EXPORT_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 | */ |
1439 | static struct |
1440 | smscore_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; |
1461 | found: |
1462 | spin_unlock_irqrestore(lock: &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 | */ |
1475 | void 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(j: 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, data_type: phdr->msg_type, id: 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 | buf: (const char *) |
1593 | ((char *)phdr |
1594 | + sizeof(struct sms_msg_hdr)), |
1595 | len: (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 | } |
1617 | EXPORT_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 | |
1628 | static 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(head: &coredev->buffers)) { |
1635 | cb = (struct smscore_buffer_t *) coredev->buffers.next; |
1636 | list_del(entry: &cb->entry); |
1637 | } |
1638 | spin_unlock_irqrestore(lock: &coredev->bufferslock, flags); |
1639 | return cb; |
1640 | } |
1641 | |
1642 | struct 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 | } |
1650 | EXPORT_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 | */ |
1660 | void 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(new: &cb->entry, head: &coredev->buffers, lock: &coredev->bufferslock); |
1664 | } |
1665 | EXPORT_SYMBOL_GPL(smscore_putbuffer); |
1666 | |
1667 | static 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(size: 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(new: &listentry->entry, head: &client->idlist, |
1693 | lock: &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 | */ |
1711 | int 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, data_type: params->data_type, |
1718 | id: params->initial_id)) { |
1719 | pr_err("Client already exist.\n" ); |
1720 | return -EEXIST; |
1721 | } |
1722 | |
1723 | newclient = kzalloc(size: sizeof(*newclient), GFP_KERNEL); |
1724 | if (!newclient) |
1725 | return -ENOMEM; |
1726 | |
1727 | INIT_LIST_HEAD(list: &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(new: &newclient->entry, head: &coredev->clients, |
1733 | lock: &coredev->clientslock); |
1734 | smscore_validate_client(coredev, client: newclient, data_type: params->data_type, |
1735 | id: 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 | } |
1742 | EXPORT_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 | */ |
1751 | void 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(head: &client->idlist)) { |
1760 | struct smscore_idlist_t *identry = |
1761 | (struct smscore_idlist_t *) client->idlist.next; |
1762 | list_del(entry: &identry->entry); |
1763 | kfree(objp: identry); |
1764 | } |
1765 | |
1766 | pr_debug("%p\n" , client->context); |
1767 | |
1768 | list_del(entry: &client->entry); |
1769 | kfree(objp: client); |
1770 | |
1771 | spin_unlock_irqrestore(lock: &coredev->clientslock, flags); |
1772 | } |
1773 | EXPORT_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 | */ |
1786 | int 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(coredev: client->coredev, client, data_type: 0, |
1807 | id: phdr->msg_src_id); |
1808 | if (rc < 0) |
1809 | return rc; |
1810 | |
1811 | return coredev->sendrequest_handler(coredev->context, buffer, size); |
1812 | } |
1813 | EXPORT_SYMBOL_GPL(smsclient_sendrequest); |
1814 | |
1815 | |
1816 | /* old GPIO managements implementation */ |
1817 | int 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 | |
1863 | int 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 */ |
1888 | static 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 | |
1938 | int 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 ; |
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(size: 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, p_translatedpin_num: &translatedpin_num, p_group_num: &group_num, |
1979 | p_group_cfg: &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, buffer: p_msg, size: total_len, |
2003 | completion: &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 | } |
2011 | free: |
2012 | kfree(objp: buffer); |
2013 | |
2014 | return rc; |
2015 | } |
2016 | |
2017 | int 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 ; |
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(size: 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, buffer: p_msg, size: total_len, |
2052 | completion: &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(objp: buffer); |
2061 | |
2062 | return rc; |
2063 | } |
2064 | |
2065 | int 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 ; |
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(size: 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, buffer: p_msg, size: total_len, |
2100 | completion: &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(objp: 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 | |
2118 | static int __init smscore_module_init(void) |
2119 | { |
2120 | INIT_LIST_HEAD(list: &g_smscore_notifyees); |
2121 | INIT_LIST_HEAD(list: &g_smscore_devices); |
2122 | INIT_LIST_HEAD(list: &g_smscore_registry); |
2123 | |
2124 | return 0; |
2125 | } |
2126 | |
2127 | static void __exit smscore_module_exit(void) |
2128 | { |
2129 | mutex_lock(&g_smscore_deviceslock); |
2130 | while (!list_empty(head: &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(entry: ¬ifyee->entry); |
2136 | kfree(objp: notifyee); |
2137 | } |
2138 | mutex_unlock(lock: &g_smscore_deviceslock); |
2139 | |
2140 | mutex_lock(&g_smscore_registrylock); |
2141 | while (!list_empty(head: &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->entry); |
2147 | kfree(objp: entry); |
2148 | } |
2149 | mutex_unlock(lock: &g_smscore_registrylock); |
2150 | |
2151 | pr_debug("\n" ); |
2152 | } |
2153 | |
2154 | module_init(smscore_module_init); |
2155 | module_exit(smscore_module_exit); |
2156 | |
2157 | MODULE_DESCRIPTION("Siano MDTV Core module" ); |
2158 | MODULE_AUTHOR("Siano Mobile Silicon, Inc. <uris@siano-ms.com>" ); |
2159 | MODULE_LICENSE("GPL" ); |
2160 | |
2161 | /* This should match what's defined at smscoreapi.h */ |
2162 | MODULE_FIRMWARE(SMS_FW_ATSC_DENVER); |
2163 | MODULE_FIRMWARE(SMS_FW_CMMB_MING_APP); |
2164 | MODULE_FIRMWARE(SMS_FW_CMMB_VEGA_12MHZ); |
2165 | MODULE_FIRMWARE(SMS_FW_CMMB_VENICE_12MHZ); |
2166 | MODULE_FIRMWARE(SMS_FW_DVBH_RIO); |
2167 | MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ_B0); |
2168 | MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ); |
2169 | MODULE_FIRMWARE(SMS_FW_DVB_RIO); |
2170 | MODULE_FIRMWARE(SMS_FW_FM_RADIO); |
2171 | MODULE_FIRMWARE(SMS_FW_FM_RADIO_RIO); |
2172 | MODULE_FIRMWARE(SMS_FW_DVBT_HCW_55XXX); |
2173 | MODULE_FIRMWARE(SMS_FW_ISDBT_HCW_55XXX); |
2174 | MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ_B0); |
2175 | MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ); |
2176 | MODULE_FIRMWARE(SMS_FW_ISDBT_PELE); |
2177 | MODULE_FIRMWARE(SMS_FW_ISDBT_RIO); |
2178 | MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_A); |
2179 | MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_B); |
2180 | MODULE_FIRMWARE(SMS_FW_DVBT_STELLAR); |
2181 | MODULE_FIRMWARE(SMS_FW_TDMB_DENVER); |
2182 | MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ_B0); |
2183 | MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ); |
2184 | |