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>
10 #include "esp_android.h"
11 #include "esp_debug.h"
18 int android_readwrite_file(const char *filename, char *rbuf, const char *wbuf, size_t length)
21 struct file *filp = (struct file *)-ENOENT;
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);
35 /* Read the length of the file only */
38 inode = GET_INODE_FROM_FILEP(filp);
40 esp_dbg(ESP_DBG_ERROR, "%s: Get inode from %s failed\n", __FUNCTION__, filename);
44 ret = i_size_read(inode->i_mapping->host);
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);
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);
64 filp_close(filp, NULL);
71 int android_request_firmware(const struct firmware **firmware_p, const char *name,
72 struct device *device)
75 struct firmware *firmware;
77 const char *raw_filename = name;
78 *firmware_p = firmware = kmalloc((sizeof(*firmware)), GFP_KERNEL);
82 memset(firmware, 0, sizeof(*firmware));
84 if (mod_eagle_path_get() == NULL)
85 sprintf(filename, "%s/%s", FWPATH, raw_filename);
87 sprintf(filename, "%s/%s", mod_eagle_path_get(), raw_filename);
90 size_t length, bufsize, bmisize;
92 if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) {
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__);
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);
120 vfree(firmware->data);
132 void android_release_firmware(const struct firmware *firmware)
136 vfree(firmware->data);
138 kfree((struct firmware *)firmware);
142 int logger_write( const unsigned char prio,
143 const char __kernel * const tag,
144 const char __kernel * const fmt,
149 struct file *filp = (struct file *)-ENOENT;
152 int tag_bytes = strlen(tag) + 1, msg_bytes;
154 va_start(vargs, fmt);
155 msg = kvasprintf(GFP_ATOMIC, fmt, vargs);
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;
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) {
169 goto out_free_message;
172 vec[0].iov_base = (unsigned char *) &prio;
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;
182 filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR);
183 if (IS_ERR(filp) || !filp->f_op) {
185 esp_dbg(ESP_DBG_ERROR, "%s: filp open /dev/log/main error\n", __FUNCTION__);
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;
194 init_sync_kiocb(&kiocb, filp);
197 kiocb.ki_nbytes = len;
198 ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos);
204 filp_close(filp, NULL);
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},
233 //attr that is not send to target
235 {"wakeup_gpio", -1, -1},
236 {"ate_test", -1, -1},
245 int esp_atoi(char *str)
255 while(*str != '\0') {
256 num = num * 10 + *str++ - '0';
259 return ng_flag ? 0-num : num;
262 void show_esp_init_table(struct esp_init_table_elem *econf)
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",
269 esp_init_table[i].attr,
270 esp_init_table[i].offset,
271 esp_init_table[i].value);
274 int android_request_init_conf(void)
284 char attr_name[CONF_ATTR_LEN];
285 char num_buf[CONF_VAL_LEN];
286 #ifdef INIT_DATA_CONF
289 if (mod_eagle_path_get() == NULL)
290 sprintf(filename, "%s/%s", FWPATH, INIT_CONF_FILE);
292 sprintf(filename, "%s/%s", mod_eagle_path_get(), INIT_CONF_FILE);
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);
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__);
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);
313 length = strlen(INIT_DATA_CONF_BUF);
314 strncpy(conf_buf, INIT_DATA_CONF_BUF, length);
316 conf_buf[length] = '\0';
320 for (pbuf = conf_buf; *pbuf != '$' && *pbuf != '\n'; pbuf++) {
323 *(attr_name+str_len) = '\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__);
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;
343 if (esp_init_table[i].value < 0)
346 if(strcmp(esp_init_table[i].attr, "share_xtal") == 0){
347 sif_record_bt_config(esp_init_table[i].value);
350 if(strcmp(esp_init_table[i].attr, "ext_rst") == 0){
351 sif_record_rst_config(esp_init_table[i].value);
354 if(strcmp(esp_init_table[i].attr, "wakeup_gpio") == 0){
355 sif_record_wakeup_gpio_config(esp_init_table[i].value);
358 if(strcmp(esp_init_table[i].attr, "ate_test") == 0){
359 sif_record_ate_config(esp_init_table[i].value);
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__);
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__);
382 //show_esp_init_table(esp_init_table);
391 void fix_init_data(u8 *init_data_buf, int buf_size)
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);
405 void show_init_buf(u8 *buf, int size)
409 for (i = 0; i < size; i++)
410 printk(KERN_ERR "offset[%d] [0x%02x]", i, buf[i]);
411 printk(KERN_ERR "\n");