#include #include #include // for msleep #include //for REG32_VAL #include #include #include // for atomic_inc atomis_dec added by rubbitxiao #include //added begin by rubbit extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); extern int wmt_setsyspara(char *varname, char *varval); //#define WMT_PIN_GP2_SUSGPIO1 19 #define WIFI_POWER_PIN WMT_PIN_GP62_SUSGPIO1 //if you use API in the file ,you should #include void detect_wifi_module(void * pbool) { int retval = -1; int varlen = 127; char buf[200] = {0}; char *wifi; char *bt; char *gps; char *tmp; printk("detect_wifi_module\n"); retval = wmt_getsyspara("wmt.wifi.bluetooth.gps", buf, &varlen); if(!retval) { //sscanf(buf, "%s:%s:%s",wifi,bt,gps); if(strlen(buf) == 0) { printk("uboot enviroment variant(wmt.wifi.bluetooth.gp) is not connect\n"); *(bool*)pbool = false; return ; } tmp = buf; printk("buf:%s\n",buf); wifi = strsep(&tmp,":"); bt = strsep(&tmp,":"); gps = strsep(&tmp,":"); printk("wifi:%s, bt:%s, gps:%s\n",wifi,bt,gps); if(!strncmp(wifi,"mtk_6620",8)) { *(bool*)pbool = true; printk("detect mtk_6620 modules:%d\n",*(bool*)pbool); } else { *(bool*)pbool = false; printk("wifi_module:%s---%d\n",wifi,*(bool*)pbool); } return ; } printk("have not set uboot enviroment variant:wmt.wifi.bluetooth.gps\n"); return; } int bt_is_mtk6622 = -1; int is_mtk6622(void) { if(bt_is_mtk6622==-1){ int retval = -1; int varlen = 127; char buf[200] = {0}; retval = wmt_getsyspara("wmt.bt.param", buf, &varlen); bt_is_mtk6622 = 0; if(!retval) { if(!strcmp(buf,"mtk_6622")) bt_is_mtk6622 = 1; } } return bt_is_mtk6622; } int bt_is_rda5991 = -1; int is_rda5991(void) { if(bt_is_rda5991==-1){ int retval = -1; int varlen = 127; char buf[200] = {0}; retval = wmt_getsyspara("wmt.bt.param", buf, &varlen); bt_is_rda5991 = 0; if(!retval) { if(!strcmp(buf,"rda_5991")) bt_is_rda5991 = 1; } } return bt_is_rda5991; } struct wifi_gpio { int name; int active; int delay; int skip; }; enum LEVEL { LOW = 0, HIGH, }; static struct wifi_gpio l_wifi_gpio = { .name = WIFI_POWER_PIN, .active = 0, .delay = 0, .skip = 0x0, }; int wifi_power_pin(int gpioNum, unsigned int active, int open) { int ret = 0; if(open){ ret = gpio_request(gpioNum, "wifi power pin"); if(ret < 0) { printk("reques gpio:%x failed!!! for wifi\n",gpioNum); return -1; }else{ printk("request gpio:%d for wifi success!!!\n", gpioNum); } if(active) gpio_direction_output(gpioNum, HIGH); else gpio_direction_output(gpioNum, LOW); printk("power on wifi\n"); } else { if(active) gpio_direction_output(gpioNum, LOW); else gpio_direction_output(gpioNum, HIGH); printk("power down wifi\n"); gpio_free(gpioNum); printk("release gpio\n"); } } atomic_t gVwifiPower = ATOMIC_INIT(0); /* * * wmt.gpo.wifi format is the following: * gpionum : active level : delay * * if mdelay is not set, then use l_wifi_gpio.delay as a open delay * if mdelay is set, then use medlay as a open delay, althrough l_wifi_gpio.delay * is specified by uboot var, if l_wifi_gpio.delay is not specified by uboot var, * which have a default value of 1000ms */ void wifi_power_ctrl_comm(int open,int mdelay) { int ret=0; int varlen = 127; int retval; char buf[200]={0}; printk("wifi_power_ctrl %d, delay:%d\n",open,l_wifi_gpio.delay); // if(!open){ // //wait 200 ms for drv to stop // msleep(200); // } if(open) { if( atomic_inc_return(&gVwifiPower) > 1 ) { printk("gVwifiPower:%d\n",atomic_read(&gVwifiPower)); return; } }else { if(atomic_read(&gVwifiPower)<=0){ printk("power off before power on\n"); return; } if(atomic_dec_return(&gVwifiPower) > 0 ) { printk("gVwifiPower:%d\n",atomic_read(&gVwifiPower)); return; } } /* * setenv wmt.gpo.wifi 9c:1:0 */ retval = wmt_getsyspara("wmt.gpo.wifi", buf, &varlen); if(!retval) { sscanf(buf, "%x:%x:%d", &(l_wifi_gpio.name), &(l_wifi_gpio.active), &(l_wifi_gpio.delay)); printk("wifi power up:%s\n", buf); printk("name:0x%x,active:0x%x,open delay:%d\n", l_wifi_gpio.name,l_wifi_gpio.active,l_wifi_gpio.delay); // l_wifi_gpio.skip = 0x01; }else{ printk("use default wifi gpio: susgpio1\n"); printk("name:0x%x,active:0x%x,open delay:%d\n", l_wifi_gpio.name,l_wifi_gpio.active,l_wifi_gpio.delay); // l_wifi_gpio.skip = 0x01; } next: //excute_gpio_op(open); wifi_power_pin(l_wifi_gpio.name, l_wifi_gpio.active, open); if(open){ //wait 1 sec to hw init if(mdelay) msleep(mdelay); else msleep(l_wifi_gpio.delay); } } void wifi_power_ctrl(int open) { wifi_power_ctrl_comm(open,1000);//unit is msec //wifi_power_ctrl_comm(open,0x0);//unit is msec } /* * wifi mac uboot variant: * wmt.wifi.mac xx:xx:xx:xx:xx:xx */ static int is_dir_exit(const char* filename) { struct file *filep = NULL; filep = filp_open(filename, O_RDONLY, 0); if(IS_ERR(filep)){ printk("file %s do not exit\n",filename); return 0x00; } filp_close(filep, 0); return 1; } static int get_wifi_mac(const char * mac_name,unsigned char *buf_mac) { unsigned char buf[200]; int varlen =127; int retval; memset(buf,0,sizeof(buf)); retval = wmt_getsyspara(mac_name, buf, &varlen); if(!retval) { sscanf(buf, "%x:%x:%x:%x:%x:%x", &(buf_mac[0]),&(buf_mac[1]),&(buf_mac[2]), &(buf_mac[3]),&(buf_mac[4]),&(buf_mac[5])); printk("wifi mac:%s\n", buf); return 0x0; }else{ printk("uboot variant:%s do not exit\n",mac_name); random_ether_addr(buf_mac); buf_mac[0] = 0x00;//prevent multi broadcast address sprintf(buf,"%x:%x:%x:%x:%x:%x",buf_mac[0],buf_mac[1],buf_mac[2], buf_mac[3],buf_mac[4],buf_mac[5]); wmt_setsyspara(mac_name, buf); return 0x01; } } int generate_wifi_mac(unsigned char *buf_mac) { if(is_dir_exit("/system")){//means we do not generate mac address when firmware installing return get_wifi_mac("wmt.wifi.mac",buf_mac); } return -1; } int irq_int_status(void) { unsigned long flags; flags = arch_local_save_flags(); if(arch_irqs_disabled_flags(flags)){ printk("irq interruption disabled\n"); }else{ printk("irq interruption enabled\n"); } } EXPORT_SYMBOL(generate_wifi_mac); EXPORT_SYMBOL(is_mtk6622); EXPORT_SYMBOL(is_rda5991); EXPORT_SYMBOL(wifi_power_ctrl); EXPORT_SYMBOL(wifi_power_ctrl_comm); EXPORT_SYMBOL(irq_int_status);