rk fb: mid not support uboot display hdmi, so wo identify box and mid at switch screen
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / esp8089 / esp_driver / esp_android.c
1 #include <linux/fs.h>
2 #include <linux/vmalloc.h>
3 #include <linux/kernel.h>
4 #include <linux/version.h>
5 #include <linux/moduleparam.h>
6 #include <linux/firmware.h>
7 #include <linux/netdevice.h>
8 #include <linux/aio.h>
9
10 #include "esp_android.h"
11 #include "esp_debug.h"
12 #include "esp_sif.h"
13
14 #ifdef ANDROID
15 #include "esp_path.h"
16 #include "esp_conf.h"
17
18 int android_readwrite_file(const char *filename, char *rbuf, const char *wbuf, size_t length)
19 {
20         int ret = 0;
21         struct file *filp = (struct file *)-ENOENT;
22         mm_segment_t oldfs;
23         oldfs = get_fs();
24         set_fs(KERNEL_DS);
25         do {
26                 int mode = (wbuf) ? O_RDWR | O_CREAT : O_RDONLY;
27                 filp = filp_open(filename, mode, S_IRUSR);
28                 if (IS_ERR(filp) || !filp->f_op) {
29                         esp_dbg(ESP_DBG_ERROR, "%s: file %s filp_open error\n", __FUNCTION__, filename);
30                         ret = -ENOENT;
31                         break;
32                 }
33
34                 if (length==0) {
35                         /* Read the length of the file only */
36                         struct inode    *inode;
37
38                         inode = GET_INODE_FROM_FILEP(filp);
39                         if (!inode) {
40                                 esp_dbg(ESP_DBG_ERROR, "%s: Get inode from %s failed\n", __FUNCTION__, filename);
41                                 ret = -ENOENT;
42                                 break;
43                         }
44                         ret = i_size_read(inode->i_mapping->host);
45                         break;
46                 }
47
48                 if (wbuf) {
49                         if ( (ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
50                                 esp_dbg(ESP_DBG_ERROR, "%s: Write %u bytes to file %s error %d\n", __FUNCTION__,
51                                         length, filename, ret);
52                                 break;
53                         }
54                 } else {
55                         if ( (ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
56                                 esp_dbg(ESP_DBG_ERROR, "%s: Read %u bytes from file %s error %d\n", __FUNCTION__,
57                                         length, filename, ret);
58                                 break;
59                         }
60                 }
61         } while (0);
62
63         if (!IS_ERR(filp)) {
64                 filp_close(filp, NULL);
65         }
66         set_fs(oldfs);
67
68         return ret;
69 }
70
71 int android_request_firmware(const struct firmware **firmware_p, const char *name,
72                              struct device *device)
73 {
74         int ret = 0;
75         struct firmware *firmware;
76         char filename[256];
77         const char *raw_filename = name;
78         *firmware_p = firmware = kmalloc((sizeof(*firmware)), GFP_KERNEL);
79         if (!firmware)
80                 return -ENOMEM;
81
82         memset(firmware, 0, sizeof(*firmware));
83
84         if (mod_eagle_path_get() == NULL)
85                 sprintf(filename, "%s/%s", FWPATH, raw_filename);
86         else 
87                 sprintf(filename, "%s/%s", mod_eagle_path_get(), raw_filename);
88
89         do {
90                 size_t length, bufsize, bmisize;
91
92                 if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) {
93                         break;
94                 } else {
95                         length = ret;
96                 }
97
98                 bufsize = ALIGN(length, PAGE_SIZE);
99                 bmisize = E_ROUND_UP(length, 4);
100                 bufsize = max(bmisize, bufsize);
101                 firmware->data = vmalloc(bufsize);
102                 firmware->size = length;
103                 if (!firmware->data) {
104                         esp_dbg(ESP_DBG_ERROR, "%s: Cannot allocate buffer for firmware\n", __FUNCTION__);
105                         ret = -ENOMEM;
106                         break;
107                 }
108
109                 if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) {
110                         esp_dbg(ESP_DBG_ERROR, "%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length);
111                         ret = -1;
112                         break;
113                 }
114
115         } while (0);
116
117         if (ret<0) {
118                 if (firmware) {
119                         if (firmware->data)
120                                 vfree(firmware->data);
121
122                         kfree(firmware);
123                 }
124                 *firmware_p = NULL;
125         } else {
126                 ret = 0;
127         }
128
129         return ret;
130 }
131
132 void android_release_firmware(const struct firmware *firmware)
133 {
134         if (firmware) {
135                 if (firmware->data)
136                         vfree(firmware->data);
137
138                 kfree((struct firmware *)firmware);
139         }
140 }
141
142 int logger_write( const unsigned char prio,
143                   const char __kernel * const tag,
144                   const char __kernel * const fmt,
145                   ...)
146 {
147         int ret = 0;
148         va_list vargs;
149         struct file *filp = (struct file *)-ENOENT;
150         mm_segment_t oldfs;
151         struct iovec vec[3];
152         int tag_bytes = strlen(tag) + 1, msg_bytes;
153         char *msg;
154         va_start(vargs, fmt);
155         msg = kvasprintf(GFP_ATOMIC, fmt, vargs);
156         va_end(vargs);
157         if (!msg)
158                 return -ENOMEM;
159         if (in_interrupt()) {
160                 /* we have no choice since aio_write may be blocked */
161                 printk(KERN_ALERT "%s", msg);
162                 goto out_free_message;
163         }
164         msg_bytes = strlen(msg) + 1;
165         if (msg_bytes <= 1) /* empty message? */
166                 goto out_free_message; /* don't bother, then */
167         if ((msg_bytes + tag_bytes + 1) > 2048) {
168                 ret = -E2BIG;
169                 goto out_free_message;
170         }
171
172         vec[0].iov_base  = (unsigned char *) &prio;
173         vec[0].iov_len    = 1;
174         vec[1].iov_base   = (void *) tag;
175         vec[1].iov_len    = strlen(tag) + 1;
176         vec[2].iov_base   = (void *) msg;
177         vec[2].iov_len    = strlen(msg) + 1;
178
179         oldfs = get_fs();
180         set_fs(KERNEL_DS);
181         do {
182                 filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR);
183                 if (IS_ERR(filp) || !filp->f_op) {
184
185                         esp_dbg(ESP_DBG_ERROR, "%s: filp open /dev/log/main error\n", __FUNCTION__);
186                         ret = -ENOENT;
187                         break;
188                 }
189
190                 if (filp->f_op->aio_write) {
191                         int nr_segs = sizeof(vec) / sizeof(vec[0]);
192                         int len = vec[0].iov_len + vec[1].iov_len + vec[2].iov_len;
193                         struct kiocb kiocb;
194                         init_sync_kiocb(&kiocb, filp);
195                         kiocb.ki_pos = 0;
196                         kiocb.ki_left = len;
197                         kiocb.ki_nbytes = len;
198                         ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos);
199                 }
200
201         } while (0);
202
203         if (!IS_ERR(filp)) {
204                 filp_close(filp, NULL);
205         }
206         set_fs(oldfs);
207 out_free_message:
208         if (msg) {
209                 kfree(msg);
210         }
211         return ret;
212 }
213
214
215
216 struct esp_init_table_elem esp_init_table[MAX_ATTR_NUM] = {
217         {"crystal_26M_en",      48, -1}, 
218         {"test_xtal",           49, -1},
219         {"sdio_configure",      50, -1},
220         {"bt_configure",        51, -1},
221         {"bt_protocol",         52, -1},
222         {"dual_ant_configure",  53, -1},
223         {"test_uart_configure", 54, -1},
224         {"share_xtal",          55, -1},
225         {"gpio_wake",           56, -1},
226         {"no_auto_sleep",       57, -1},
227         {"speed_suspend",       58, -1},
228         {"attr11",              -1, -1},
229         {"attr12",              -1, -1},
230         {"attr13",              -1, -1},
231         {"attr14",              -1, -1},
232         {"attr15",              -1, -1},
233         //attr that is not send to target
234         {"ext_rst",              -1, -1},
235         {"wakeup_gpio",         -1, -1},
236         {"ate_test",              -1, -1},
237         {"attr19",              -1, -1},
238         {"attr20",              -1, -1},
239         {"attr21",              -1, -1},
240         {"attr22",              -1, -1},
241         {"attr23",              -1, -1},
242         
243 };
244
245 int esp_atoi(char *str)
246 {
247         int num = 0;
248         int ng_flag = 0;
249
250         if (*str == '-') {
251                 str++;
252                 ng_flag = 1;
253         }
254
255         while(*str != '\0') {
256                 num = num * 10 + *str++ - '0';
257         }
258
259         return ng_flag ? 0-num : num;
260 }
261
262 void show_esp_init_table(struct esp_init_table_elem *econf)
263 {
264         int i;
265         for (i = 0; i < MAX_ATTR_NUM; i++)
266                 if (esp_init_table[i].offset > -1)
267                         esp_dbg(ESP_DBG_ERROR, "%s: esp_init_table[%d] attr[%s] offset[%d] value[%d]\n", 
268                                 __FUNCTION__, i,
269                                 esp_init_table[i].attr,
270                                 esp_init_table[i].offset,
271                                 esp_init_table[i].value);
272 }
273         
274 int android_request_init_conf(void)
275 {
276
277         u8 *conf_buf;
278         u8 *pbuf;
279         int flag;
280         int str_len;    
281         int length;
282         int ret;
283         int i;
284         char attr_name[CONF_ATTR_LEN];
285         char num_buf[CONF_VAL_LEN];
286 #ifdef INIT_DATA_CONF
287         char filename[256];
288
289         if (mod_eagle_path_get() == NULL)
290                 sprintf(filename, "%s/%s", FWPATH, INIT_CONF_FILE);
291         else
292                 sprintf(filename, "%s/%s", mod_eagle_path_get(), INIT_CONF_FILE);
293
294         if ((ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0 || ret > MAX_BUF_LEN) {
295                 esp_dbg(ESP_DBG_ERROR, "%s: file read length error, ret %d\n", __FUNCTION__, ret);
296                 return ret;
297         } else {
298                 length = ret;
299         }
300 #endif /* INIT_DATA_CONF */
301         conf_buf = (u8 *)kmalloc(MAX_BUF_LEN, GFP_KERNEL);
302         if (conf_buf == NULL) {
303                 esp_dbg(ESP_DBG_ERROR, "%s: failed kmalloc memory for read init_data_conf", __func__);
304                 return -ENOMEM;
305         }
306
307 #ifdef INIT_DATA_CONF
308         if ((ret=android_readwrite_file(filename, conf_buf, NULL, length)) != length) {
309                 esp_dbg(ESP_DBG_ERROR, "%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length);
310                 goto failed;
311         }
312 #else
313         length = strlen(INIT_DATA_CONF_BUF);
314         strncpy(conf_buf, INIT_DATA_CONF_BUF, length); 
315 #endif
316         conf_buf[length] = '\0';
317
318         flag = 0;
319         str_len = 0;
320         for (pbuf = conf_buf; *pbuf != '$' && *pbuf != '\n'; pbuf++) {
321                 if (*pbuf == '=') {
322                         flag = 1;
323                         *(attr_name+str_len) = '\0';
324                         str_len = 0;
325                         continue;
326                 }
327
328                 if (*pbuf == ';') {
329                         int value;
330                         flag = 0;
331                         *(num_buf+str_len) = '\0';
332                         if((value = esp_atoi(num_buf)) > 255 || value < 0){
333                                 esp_dbg(ESP_DBG_ERROR, "%s: value is too big", __FUNCTION__);
334                                 goto failed;
335                         }
336
337                         for (i = 0; i < MAX_ATTR_NUM; i++) {
338                                 if (strcmp(esp_init_table[i].attr, attr_name) == 0) {
339                                         esp_dbg(ESP_DBG_TRACE, "%s: attr_name[%s]", __FUNCTION__, attr_name); /* add by th */
340                                         esp_init_table[i].value = value;
341                                 }
342
343                                 if (esp_init_table[i].value < 0)
344                                         continue;
345
346                                 if(strcmp(esp_init_table[i].attr, "share_xtal") == 0){
347                                         sif_record_bt_config(esp_init_table[i].value);
348                                 }
349
350                                 if(strcmp(esp_init_table[i].attr, "ext_rst") == 0){
351                                         sif_record_rst_config(esp_init_table[i].value);
352                                 }
353
354                                 if(strcmp(esp_init_table[i].attr, "wakeup_gpio") == 0){
355                                         sif_record_wakeup_gpio_config(esp_init_table[i].value);
356                                 }
357
358                 if(strcmp(esp_init_table[i].attr, "ate_test") == 0){
359                                         sif_record_ate_config(esp_init_table[i].value);
360                                 }
361
362                         }
363                         str_len = 0;
364                         continue;
365                 }
366
367                 if (flag == 0) {
368                         *(attr_name+str_len) = *pbuf;
369                         if (++str_len > CONF_ATTR_LEN) {
370                                 esp_dbg(ESP_DBG_ERROR, "%s: attr len is too long", __FUNCTION__);
371                                 goto failed;
372                         }
373                 } else {
374                         *(num_buf+str_len) = *pbuf;
375                         if (++str_len > CONF_VAL_LEN) {
376                                 esp_dbg(ESP_DBG_ERROR, "%s: value len is too long", __FUNCTION__);
377                                 goto failed;
378                         }       
379                 }
380         }
381
382         //show_esp_init_table(esp_init_table);
383
384         ret = 0;
385 failed:
386         if (conf_buf)
387                 kfree(conf_buf);
388         return ret;
389 }
390
391 void fix_init_data(u8 *init_data_buf, int buf_size)
392 {
393         int i;
394
395         for (i = 0; i < MAX_FIX_ATTR_NUM; i++) {
396                 if (esp_init_table[i].offset > -1 && esp_init_table[i].offset < buf_size && esp_init_table[i].value > -1) {
397                         *(u8 *)(init_data_buf + esp_init_table[i].offset) = esp_init_table[i].value;
398                 } else if (esp_init_table[i].offset > buf_size) {
399                         esp_dbg(ESP_DBG_ERROR, "%s: offset[%d] longer than init_data_buf len[%d] Ignore\n", __FUNCTION__, esp_init_table[i].offset, buf_size);
400                 }
401         }
402
403 }
404
405 void show_init_buf(u8 *buf, int size)
406 {
407         int i = 0;
408         
409         for (i = 0; i < size; i++)
410                         printk(KERN_ERR "offset[%d] [0x%02x]", i, buf[i]);
411         printk(KERN_ERR "\n");
412                 
413 }
414
415 #endif //ANDROID