import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / eemcs / eemcs_sysmsg.c
1 /*****************************************************************************
2 *
3 * Filename:
4 * ---------
5 * eemcs_sysmsg.c
6 *
7 * Project:
8 * --------
9 * ALPS
10 *
11 * Description:
12 * ------------
13 * MT6582 CCCI SYSTEM MESSAGE
14 *
15 * Author:
16 * -------
17 *
18 *
19 ****************************************************************************/
20
21 #include <linux/sched.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/device.h>
25 #include <linux/cdev.h>
26 #include <linux/kfifo.h>
27 #include <linux/spinlock.h>
28 #include <linux/interrupt.h>
29 #include <linux/delay.h>
30 #include <linux/uaccess.h>
31 #include <linux/timer.h>
32 #include <linux/delay.h>
33 #include <linux/semaphore.h>
34
35 #include "eemcs_kal.h"
36 #include "eemcs_ccci.h"
37 #include "eemcs_debug.h"
38 #include "eemcs_char.h"
39 #include "eemcs_file_ops.h"
40 #include "eemcs_sysmsg.h"
41 #include "mach/mtk_eemcs_helper.h"
42 #include "eemcs_state.h"
43
44 static spinlock_t sysmsg_fifo_lock = __SPIN_LOCK_UNLOCKED(sysmsg_fifo_lock);
45 static struct kfifo sysmsg_fifo;
46 struct work_struct sysmsg_work;
47
48
49 //#define __EEMCS_SYSMSG_IT__
50 #ifdef __EEMCS_SYSMSG_IT__
51 #define TEST_MSG_ID_MD2AP (0x113)
52 #define TEST_MSG_ID_AP2MD (0x107)
53 #endif
54
55 //------------For MD get Battery info from AP------------//
56 void send_battery_info(int md_id)
57 {
58 int ret = 0;
59 unsigned int para = 0;
60 unsigned int resv = 0;
61 unsigned int msg_id = EXT_MD_GET_BATTERY_INFO;
62
63 resv = eemcs_get_bat_info(para);
64 ret = eemcs_notify_md_by_sys_msg(md_id, msg_id, resv);
65 DBGLOG(SMSG, INF, "send bat vol(%d) to md: %d", resv, ret);
66
67 return;
68 }
69 int eemcs_md_get_battery_info(int md_id, int data)
70 {
71 DBGLOG(SMSG,DBG,"request to send battery voltage to md");
72 send_battery_info(md_id);
73 return 0;
74 }
75 //--------------end-------------------------//
76
77 //------------For MD send sim type msg to AP------------//
78
79 int enable_get_sim_type(int md_id, unsigned int enable)
80 {
81 int ret = 0;
82 unsigned int msg_id = EXT_MD_SIM_TYPE;
83 unsigned int resv = enable;
84
85 ret = eemcs_notify_md_by_sys_msg(MD_SYS5, msg_id, resv);
86
87 DBGLOG(SMSG,INF,"enable_get_sim_type(enable=%d): %d", resv, ret);
88
89 return ret;
90 }
91
92 int sim_type = 0xEEEEEEEE; //sim_type(MCC/MNC) send by MD wouldn't be 0xEEEEEEEE
93 int set_sim_type(int md_id, int data)
94 {
95 int ret = 0;
96 sim_type = data;
97
98 DBGLOG(SMSG,INF,"set_sim_type(type=0x%x): %d", sim_type, ret);
99
100 return ret;
101 }
102
103 int get_sim_type(int md_id, int *p_sim_type)
104 {
105 *p_sim_type = sim_type;
106 if (sim_type == 0xEEEEEEEE)
107 {
108 DBGLOG(SMSG,ERR,"get_sim_type fail: md not send sim type yet, type=0x%x", sim_type);
109 return -1;
110 } else
111 DBGLOG(SMSG,INF,"get_sim_type: type=0x%x", sim_type);
112
113 return 0;
114 }
115
116 //--------------end-------------------------//
117
118 static void eemcs_sysmsg_work(struct work_struct *work)
119 {
120 //unsigned char *p_rdata;
121 struct sk_buff *skb;
122 CCCI_BUFF_T *p_cccih = NULL;
123 int md_id = MD_SYS5;
124
125 DBGLOG(SMSG, DBG, "====> %s", FUNC_NAME);
126
127 while(kfifo_out(&sysmsg_fifo, &skb, sizeof(unsigned int)))
128 {
129 p_cccih = (CCCI_BUFF_T *)skb->data;
130 DBGLOG(SMSG, DBG, "eemcs_sysmsg_work, msg: %08X, %08X, %08X, %08X\n", \
131 p_cccih->data[0], p_cccih->data[1], p_cccih->channel, p_cccih->reserved);
132 eemcs_exec_ccci_sys_call_back(md_id, p_cccih->data[1], p_cccih->reserved);
133 dev_kfree_skb(skb);
134 }
135 DBGLOG(SMSG, DBG, "<==== %s", FUNC_NAME);
136 }
137
138 static int send_eemcs_system_ch_msg(int md_id, unsigned int msg_id, unsigned int data)
139 {
140 CCCI_BUFF_T * ccci_header;
141 struct sk_buff *new_skb;
142 unsigned int skb_len = CCCI_SYSMSG_HEADER_ROOM;
143 int ret = KAL_FAIL;
144
145 DBGLOG(SMSG, DBG, "send_eemcs_system_ch_msg");
146
147 if (check_device_state() != EEMCS_BOOTING_DONE) {//modem not ready
148 DBGLOG(CHAR, ERR, "send sys msg(id=%d) fail when modem not ready", msg_id);
149 return -ENODEV;
150 }
151
152 //when alloc skb fail, not use __GFP_WAIT because this API may be used in interrupt context
153 while(NULL == (new_skb = dev_alloc_skb(skb_len)))
154 {
155 DBGLOG(SMSG, ERR, "dev_alloc_skb fail");
156 }
157
158 /* reserve SDIO_H and CCCI header room */
159 #ifdef CCCI_SDIO_HEAD
160 skb_reserve(new_skb, sizeof(SDIO_H));
161 #endif
162 ccci_header = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ;
163
164
165 ccci_header->data[0] = 0xFFFFFFFF;
166 ccci_header->data[1] = msg_id;
167 ccci_header->channel = CH_SYS_TX;
168 ccci_header->reserved = data;
169
170
171 DBGLOG(SMSG, DBG, "send_sys_msg: 0x%08X, 0x%08X, 0x%02d, 0x%08X",
172 ccci_header->data[0],ccci_header->data[1] ,ccci_header->channel, ccci_header->reserved);
173
174 ret = ccci_sysmsg_ch_write_desc_to_q(ccci_header->channel, new_skb);
175 if(ret != KAL_SUCCESS)
176 {
177 DBGLOG(SMSG, ERR, "send_sys_msg(id=%d, data=0x%x) fail: %d", msg_id, ccci_header->reserved, ret);
178 dev_kfree_skb(new_skb);
179 } else {
180 DBGLOG(SMSG, DBG, "send_sys_msg(id=%d, data=0x%x) OK: %d", msg_id, ccci_header->reserved, ret);
181 }
182 return ret;
183 }
184
185 // eemcs_sysmsg_rx_dispatch_cb: CCCI_SYSTEM_RX message dispatch call back function for MODEM
186 // @skb: pointer to a CCCI buffer
187 // @private_data: pointer to private data of CCCI_SYSTEM_RX
188 KAL_INT32 eemcs_sysmsg_rx_dispatch_cb(struct sk_buff *skb, KAL_UINT32 private_data)
189 {
190 CCCI_BUFF_T *p_cccih = NULL;
191
192 DBGLOG(SMSG, DBG, "====> %s", FUNC_NAME);
193
194 if (skb){
195 p_cccih = (CCCI_BUFF_T *)skb->data;
196 DBGLOG(SMSG, INF, "sysmsg RX callback, msg: %08X, %08X, %02d, %08X\n", p_cccih->data[0], p_cccih->data[1], p_cccih->channel, p_cccih->reserved);
197
198 if (p_cccih->channel == CH_SYS_TX){
199 DBGLOG(SMSG, ERR, "Wrong CH for recv");
200 return KAL_FAIL;
201 }
202
203 if (kfifo_is_full(&sysmsg_fifo))
204 {
205 DBGLOG(SMSG, ERR, "kfifo full and packet drop, msg: %08X, %08X, %02d, %08X\n", \
206 p_cccih->data[0], p_cccih->data[1], p_cccih->channel, p_cccih->reserved);
207 dev_kfree_skb(skb);
208 return KAL_FAIL;
209 }
210
211 spin_lock_bh(&sysmsg_fifo_lock);
212 //DBGLOG(SMSG, TRA, "ready to put skb into FIFO");
213 kfifo_in(&sysmsg_fifo, &skb, sizeof(unsigned int));
214 //DBGLOG(SMSG, TRA, "after put skb into FIFO");
215 spin_unlock_bh(&sysmsg_fifo_lock);
216 DBGLOG(SMSG, DBG, "schedule sysmsg_work");
217 schedule_work(&sysmsg_work);
218
219 }
220 else
221 {
222 DBGLOG(SMSG, ERR, "skb is NULL!");
223 return KAL_FAIL;
224 }
225
226 DBGLOG(SMSG, DBG, "<==== %s", FUNC_NAME);
227 return KAL_SUCCESS;
228 }
229
230 #ifdef __EEMCS_SYSMSG_IT__
231 int eemcs_sysmsg_echo_test(int md_id, int data)
232 {
233 eemcs_notify_md_by_sys_msg(md_id, TEST_MSG_ID_AP2MD, data);
234 return 0;
235 }
236 #endif
237
238 int eemcs_sysmsg_mod_init(void)
239 {
240 int ret = 0;
241
242 DBGLOG(SMSG, DBG, "====> %s", FUNC_NAME);
243
244 ret = kfifo_alloc(&sysmsg_fifo, sizeof(unsigned)*CCCI_SYSMSG_MAX_REQ_NUM, GFP_KERNEL);
245 if (ret)
246 {
247 DBGLOG(SMSG, ERR, "kfifo_alloc fail: %d", ret);
248 return ret;
249 }
250
251 //related channel registration.
252 //RX
253 KAL_ASSERT(ccci_ch_register((CCCI_CHANNEL_T)CH_SYS_RX, eemcs_sysmsg_rx_dispatch_cb, 0) == KAL_SUCCESS);
254 //TX
255 eemcs_register_sys_msg_notify_func(MD_SYS5, send_eemcs_system_ch_msg);
256
257 INIT_WORK(&sysmsg_work, eemcs_sysmsg_work);
258
259 #ifdef __EEMCS_SYSMSG_IT__
260 eemcs_register_ccci_sys_call_back(MD_SYS5, TEST_MSG_ID_MD2AP, eemcs_sysmsg_echo_test);
261 #endif
262
263 //DBGLOG(SMSG, TRA, "register sys msg callback: md_get_battery_info");
264 eemcs_register_ccci_sys_call_back(MD_SYS5, EXT_MD_GET_BATTERY_INFO , eemcs_md_get_battery_info); //EXT_MD_GET_BATTERY_INFO == MD_GET_BATTERY_INFO == 0x105
265
266 eemcs_register_ccci_sys_call_back(MD_SYS5, EXT_MD_SIM_TYPE, set_sim_type);
267
268 DBGLOG(SMSG, DBG, "<==== %s", FUNC_NAME);
269
270 return 0;
271 }
272
273 void eemcs_sysmsg_exit(void)
274 {
275 DBGLOG(SMSG, INF, "====> %s", FUNC_NAME);
276 kfifo_free(&sysmsg_fifo);
277 }
278