xref: /OK3568_Linux_fs/external/rkwifibt/src/rk_wifibt_init.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun #include <stdlib.h>
2*4882a593Smuzhiyun #include <fcntl.h>
3*4882a593Smuzhiyun #include <errno.h>
4*4882a593Smuzhiyun #include <string.h>
5*4882a593Smuzhiyun #include <dirent.h>
6*4882a593Smuzhiyun #include <sys/socket.h>
7*4882a593Smuzhiyun #include <unistd.h>
8*4882a593Smuzhiyun #include <poll.h>
9*4882a593Smuzhiyun #include <dirent.h>
10*4882a593Smuzhiyun #include <stdio.h>
11*4882a593Smuzhiyun #include <assert.h>
12*4882a593Smuzhiyun #include <stdbool.h>
13*4882a593Smuzhiyun #include <unistd.h>
14*4882a593Smuzhiyun #include <sys/stat.h>
15*4882a593Smuzhiyun #include <syslog.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define WIFI_CHIP_TYPE_PATH	"/sys/class/rkwifi/chip"
18*4882a593Smuzhiyun #define WIFI_POWER_INF		"/sys/class/rkwifi/power"
19*4882a593Smuzhiyun #define WIFI_DRIVER_INF		"/sys/class/rkwifi/driver"
20*4882a593Smuzhiyun #define WIFI_PRELOAD_INF	"/sys/class/rkwifi/preload"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define UNKKOWN_DRIVER_MODULE_ARG ""
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define RKWIFIBT_DEBUG
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #ifdef RKWIFIBT_DEBUG
27*4882a593Smuzhiyun #define pr_debug(fmt, ...)		syslog(LOG_DEBUG, fmt, ##__VA_ARGS__)
28*4882a593Smuzhiyun #define pr_info(fmt, ...)		syslog(LOG_INFO, fmt, ##__VA_ARGS__)
29*4882a593Smuzhiyun #define pr_warning(fmt, ...)	syslog(LOG_WARNING, fmt, ##__VA_ARGS__)
30*4882a593Smuzhiyun #define pr_err(fmt, ...)		syslog(LOG_ERR, fmt, ##__VA_ARGS__)
31*4882a593Smuzhiyun #else
32*4882a593Smuzhiyun #define pr_debug
33*4882a593Smuzhiyun #define pr_info
34*4882a593Smuzhiyun #define pr_warning
35*4882a593Smuzhiyun #define pr_err
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun int check_wifi_chip_type(void);
40*4882a593Smuzhiyun int check_wifi_chip_type_string(char *type);
41*4882a593Smuzhiyun int rk_wifi_power_ctrl(int on);
42*4882a593Smuzhiyun int rk_wifi_load_driver(int enable);
43*4882a593Smuzhiyun int check_wireless_ready(void);
44*4882a593Smuzhiyun int get_kernel_version(void);
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static int identify_sucess = -1;
47*4882a593Smuzhiyun static int rtl_usb_bt = 0;
48*4882a593Smuzhiyun static char recoginze_wifi_chip[64];
49*4882a593Smuzhiyun static const char USB_DIR[] = "/sys/bus/usb/devices";
50*4882a593Smuzhiyun static const char SDIO_DIR[]= "/sys/bus/sdio/devices";
51*4882a593Smuzhiyun static const char PCIE_DIR[]= "/sys/bus/pci/devices";
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun static const char PREFIX_SDIO[] = "SDIO_ID=";
54*4882a593Smuzhiyun static const char PREFIX_PCIE[] = "PCI_ID=";
55*4882a593Smuzhiyun static const char PREFIX_USB[] = "PRODUCT=";
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static int invalid_wifi_device_id = -1;
58*4882a593Smuzhiyun static char wifi_type[64] = {0};
59*4882a593Smuzhiyun static char *bt_firmware_patch = {0};
60*4882a593Smuzhiyun static int wifi_dirver_is_loaded = -1;
61*4882a593Smuzhiyun static char bt_tty_dev[64] = { 0 };
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun typedef struct _wifi_devices
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun   char wifi_name[64];
66*4882a593Smuzhiyun   char wifi_vid_pid[64];
67*4882a593Smuzhiyun } wifi_device;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun typedef struct _wifi_ko_file_name
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	char wifi_name[64];
72*4882a593Smuzhiyun 	char wifi_module_path[128];
73*4882a593Smuzhiyun 	char wifi_module_arg[128];
74*4882a593Smuzhiyun 	char bt_firmware_path[128];
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun } wifi_ko_file_name;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun static wifi_device supported_wifi_devices[] = {
79*4882a593Smuzhiyun 	{"RTL8188EU",	"0bda:8179"},
80*4882a593Smuzhiyun 	{"RTL8188EU",	"0bda:0179"},
81*4882a593Smuzhiyun 	{"RTL8723BU",	"0bda:b720"},
82*4882a593Smuzhiyun 	{"RTL8723BS",	"024c:b723"},
83*4882a593Smuzhiyun 	{"RTL8822BS",	"024c:b822"},
84*4882a593Smuzhiyun 	{"RTL8723CS",	"024c:b703"},
85*4882a593Smuzhiyun 	{"RTL8723DS",	"024c:d723"},
86*4882a593Smuzhiyun 	{"RTL8188FU",	"0bda:f179"},
87*4882a593Smuzhiyun 	{"RTL8822BU",	"0bda:b82c"},
88*4882a593Smuzhiyun 	{"RTL8189ES",	"024c:8179"},
89*4882a593Smuzhiyun 	{"RTL8189FS",	"024c:f179"},
90*4882a593Smuzhiyun 	{"RTL8192DU",	"0bda:8194"},
91*4882a593Smuzhiyun 	{"RTL8812AU",	"0bda:8812"},
92*4882a593Smuzhiyun 	{"AP6354",		"02d0:4354"},
93*4882a593Smuzhiyun 	{"AP6330",		"02d0:4330"},
94*4882a593Smuzhiyun 	{"AP6356S",		"02d0:4356"},
95*4882a593Smuzhiyun 	{"AP6398S",		"02d0:4359"},
96*4882a593Smuzhiyun 	{"AP6335",		"02d0:4335"},
97*4882a593Smuzhiyun 	{"AP6255",      "02d0:a9bf"},
98*4882a593Smuzhiyun 	{"AP6256",      "02d0:a9bf"},
99*4882a593Smuzhiyun 	{"AP6212A",     "02d0:a9a6"},
100*4882a593Smuzhiyun 	{"AP6275S",     "02d0:aae8"},
101*4882a593Smuzhiyun 	{"AP6275P",     "14e4:449d"},
102*4882a593Smuzhiyun 	{"RTL8822BE",	"10ec:b822"},
103*4882a593Smuzhiyun 	{"RTL8822CE",	"10ec:c822"},
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun // TODO: use new ANDROID_SOCKET mechanism, once support for multiple
107*4882a593Smuzhiyun // sockets is in
108*4882a593Smuzhiyun #define RTL8188EU_DRIVER_MODULE_PATH "/system/lib/modules/RTL8188EU.ko"
109*4882a593Smuzhiyun #define RTL8723BU_DRIVER_MODULE_PATH "/system/lib/modules/RTL8723BU.ko"
110*4882a593Smuzhiyun #define RTL8723BS_DRIVER_MODULE_PATH "/system/lib/modules/RTL8723BS.ko"
111*4882a593Smuzhiyun #define RTL8723CS_DRIVER_MODULE_PATH "/system/lib/modules/RTL8723CS.ko"
112*4882a593Smuzhiyun #define RTL8723DS_DRIVER_MODULE_PATH "/system/lib/modules/RTL8723DS.ko"
113*4882a593Smuzhiyun #define RTL8188FU_DRIVER_MODULE_PATH "/system/lib/modules/RTL8188FU.ko"
114*4882a593Smuzhiyun #define RTL8822BU_DRIVER_MODULE_PATH "/system/lib/modules/RTL8822BU.ko"
115*4882a593Smuzhiyun #define RTL8822BS_DRIVER_MODULE_PATH "/system/lib/modules/RTL8822BS.ko"
116*4882a593Smuzhiyun #define RTL8189ES_DRIVER_MODULE_PATH "/system/lib/modules/RTL8189ES.ko"
117*4882a593Smuzhiyun #define RTL8189FS_DRIVER_MODULE_PATH "/system/lib/modules/RTL8189FS.ko"
118*4882a593Smuzhiyun #define RTL8192DU_DRIVER_MODULE_PATH "/system/lib/modules/RTL8192DU.ko"
119*4882a593Smuzhiyun #define RTL8812AU_DRIVER_MODULE_PATH "/system/lib/modules/RTL8812AU.ko"
120*4882a593Smuzhiyun #define RTL8822BE_DRIVER_MODULE_PATH "/system/lib/modules/RTL8822BE.ko"
121*4882a593Smuzhiyun #define RTL8822CE_DRIVER_MODULE_PATH "/system/lib/modules/RTL8822CE.ko"
122*4882a593Smuzhiyun #define BCM_DRIVER_MODULE_PATH       "/system/lib/modules/bcmdhd.ko"
123*4882a593Smuzhiyun #define BCM_PCIE_DRIVER_MODULE_PATH   "/system/lib/modules/bcmdhd_pcie.ko"
124*4882a593Smuzhiyun #define DRIVER_MODULE_PATH_UNKNOW    ""
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun #define RTL8822BS_DRIVER_MODULE_NAME "8822bs"
127*4882a593Smuzhiyun #define RTL8723CS_DRIVER_MODULE_NAME "8723cs"
128*4882a593Smuzhiyun #define RTL8723DS_DRIVER_MODULE_NAME "8723ds"
129*4882a593Smuzhiyun #define RTL8188EU_DRIVER_MODULE_NAME "8188eu"
130*4882a593Smuzhiyun #define RTL8723BU_DRIVER_MODULE_NAME "8723bu"
131*4882a593Smuzhiyun #define RTL8723BS_DRIVER_MODULE_NAME "8723bs"
132*4882a593Smuzhiyun #define RTL8723BS_VQ0_DRIVER_MODULE_NAME "8723bs_vq0"
133*4882a593Smuzhiyun #define RTL8188FU_DRIVER_MODULE_NAME "8188fu"
134*4882a593Smuzhiyun #define RTL8189ES_DRIVER_MODULE_NAME "8189es"
135*4882a593Smuzhiyun #define RTL8189FS_DRIVER_MODULE_NAME "8189fs"
136*4882a593Smuzhiyun #define RTL8192DU_DRIVER_MODULE_NAME "8192du"
137*4882a593Smuzhiyun #define RTL8812AU_DRIVER_MODULE_NAME "8812au"
138*4882a593Smuzhiyun #define RTL8822CE_DRIVER_MODULE_NAME "8822ce"
139*4882a593Smuzhiyun #define BCM_DRIVER_MODULE_NAME       "bcmdhd"
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun #define AP6330_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/rk903.hcd"
142*4882a593Smuzhiyun #define AP6212_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/bcm43438a0.hcd"
143*4882a593Smuzhiyun #define AP6212A_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/bcm43438a1.hcd"
144*4882a593Smuzhiyun #define AP6335_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/bcm4339a0.hcd"
145*4882a593Smuzhiyun #define AP6255_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/BCM4345C0.hcd"
146*4882a593Smuzhiyun #define AP6256_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/BCM4345C5.hcd"
147*4882a593Smuzhiyun #define AP6354_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/bcm4354a1.hcd"
148*4882a593Smuzhiyun #define AP6356_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/BCM4356A2.hcd"
149*4882a593Smuzhiyun #define AP6398s_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/BCM4359C0.hcd"
150*4882a593Smuzhiyun #define AP6236_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/BCM4343B0.hcd"
151*4882a593Smuzhiyun #define AP6275_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/BCM4362A2.hcd"
152*4882a593Smuzhiyun #define AP_BT_FIRMWARE_MODULE_PATH "/system/etc/firmware/"
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun wifi_ko_file_name module_list[] =
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	{"RTL8723BU", RTL8723BU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
157*4882a593Smuzhiyun 	{"RTL8188EU", RTL8188EU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
158*4882a593Smuzhiyun 	{"RTL8192DU", RTL8192DU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
159*4882a593Smuzhiyun 	{"RTL8822BU", RTL8822BU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
160*4882a593Smuzhiyun 	{"RTL8822BS", RTL8822BS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
161*4882a593Smuzhiyun 	{"RTL8188FU", RTL8188FU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
162*4882a593Smuzhiyun 	{"RTL8189ES", RTL8189ES_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
163*4882a593Smuzhiyun 	{"RTL8723BS", RTL8723BS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
164*4882a593Smuzhiyun 	{"RTL8723CS", RTL8723CS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
165*4882a593Smuzhiyun 	{"RTL8723DS", RTL8723DS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, "RTL8723DS"},
166*4882a593Smuzhiyun 	{"RTL8812AU", RTL8812AU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
167*4882a593Smuzhiyun 	{"RTL8189FS", RTL8189FS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
168*4882a593Smuzhiyun 	{"RTL8822BE", RTL8822BE_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
169*4882a593Smuzhiyun 	{"RTL8822CE", RTL8822CE_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
170*4882a593Smuzhiyun 	{"AP6335",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6335_BT_FIRMWARE_MODULE_PATH},
171*4882a593Smuzhiyun 	{"AP6330",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6330_BT_FIRMWARE_MODULE_PATH},
172*4882a593Smuzhiyun 	{"AP6354",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6354_BT_FIRMWARE_MODULE_PATH},
173*4882a593Smuzhiyun 	{"AP6356S",         BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6356_BT_FIRMWARE_MODULE_PATH},
174*4882a593Smuzhiyun 	{"AP6255",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6255_BT_FIRMWARE_MODULE_PATH},
175*4882a593Smuzhiyun 	{"AP6256",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6256_BT_FIRMWARE_MODULE_PATH},
176*4882a593Smuzhiyun 	{"AP6212",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6212_BT_FIRMWARE_MODULE_PATH},
177*4882a593Smuzhiyun 	{"AP6212A",         BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP_BT_FIRMWARE_MODULE_PATH},
178*4882a593Smuzhiyun 	{"AP6356",          BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6356_BT_FIRMWARE_MODULE_PATH},
179*4882a593Smuzhiyun 	{"AP6398S",         BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6398s_BT_FIRMWARE_MODULE_PATH},
180*4882a593Smuzhiyun 	{"AP6275S",         BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6275_BT_FIRMWARE_MODULE_PATH},
181*4882a593Smuzhiyun 	{"AP6275P",         BCM_PCIE_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, AP6275_BT_FIRMWARE_MODULE_PATH},
182*4882a593Smuzhiyun 	{"APXXX",           BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG, ""},
183*4882a593Smuzhiyun 	{"UNKNOW",       DRIVER_MODULE_PATH_UNKNOW, UNKKOWN_DRIVER_MODULE_ARG, ""}
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun };
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun static const char RECOGNIZE_WIFI_CHIP[] = "/data/wifi_chip";
188*4882a593Smuzhiyun 
save_wifi_chip_type(char * type)189*4882a593Smuzhiyun int save_wifi_chip_type(char *type)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	int ret, found;
192*4882a593Smuzhiyun 	int fd;
193*4882a593Smuzhiyun 	char buf[64];
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	ret = access(RECOGNIZE_WIFI_CHIP, R_OK|W_OK);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	if ((ret == 0) || (errno == EACCES)) {
198*4882a593Smuzhiyun 		if ((ret != 0) && (chmod(RECOGNIZE_WIFI_CHIP, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) != 0)) {
199*4882a593Smuzhiyun 			pr_info("Cannot set RW to \"%s\": %s \n", RECOGNIZE_WIFI_CHIP, strerror(errno));
200*4882a593Smuzhiyun 			return -1;
201*4882a593Smuzhiyun 		}
202*4882a593Smuzhiyun 		pr_info("%s is exit \n", RECOGNIZE_WIFI_CHIP);
203*4882a593Smuzhiyun 		return 0;
204*4882a593Smuzhiyun 	}
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	fd = open(RECOGNIZE_WIFI_CHIP, O_CREAT|O_RDWR, 0664);
207*4882a593Smuzhiyun 	if (fd < 0) {
208*4882a593Smuzhiyun 		pr_info("Cannot create \"%s\": %s", RECOGNIZE_WIFI_CHIP, strerror(errno));
209*4882a593Smuzhiyun 		return -1;
210*4882a593Smuzhiyun 	}
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	pr_info("%s is not exit,save wifi chip \n", RECOGNIZE_WIFI_CHIP);
213*4882a593Smuzhiyun 	strcpy(buf, type);
214*4882a593Smuzhiyun 	pr_info("recognized wifi chip = %s, save to %s \n", buf, RECOGNIZE_WIFI_CHIP);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	if (write(fd, buf, strlen(buf) + 1) != (strlen(buf) + 1)) {
217*4882a593Smuzhiyun 		pr_info("Error writing \"%s\": %s \n", RECOGNIZE_WIFI_CHIP, strerror(errno));
218*4882a593Smuzhiyun 		close(fd);
219*4882a593Smuzhiyun 		return -1;
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	close(fd);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	if (chmod(RECOGNIZE_WIFI_CHIP, 0664) < 0) {
225*4882a593Smuzhiyun 		pr_info("Error changing permissions of %s to 0664: %s \n",RECOGNIZE_WIFI_CHIP, strerror(errno));
226*4882a593Smuzhiyun 		unlink(RECOGNIZE_WIFI_CHIP);
227*4882a593Smuzhiyun 		return -1;
228*4882a593Smuzhiyun 	}
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	return 1;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
get_wifi_device_id(const char * bus_dir,const char * prefix)233*4882a593Smuzhiyun int get_wifi_device_id(const char *bus_dir, const char *prefix)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	int idnum;
236*4882a593Smuzhiyun 	int i = 0;
237*4882a593Smuzhiyun 	int ret = invalid_wifi_device_id;
238*4882a593Smuzhiyun 	DIR *dir;
239*4882a593Smuzhiyun 	struct dirent *next;
240*4882a593Smuzhiyun 	FILE *fp = NULL;
241*4882a593Smuzhiyun 	idnum = sizeof(supported_wifi_devices) / sizeof(supported_wifi_devices[0]);
242*4882a593Smuzhiyun 	dir = opendir(bus_dir);
243*4882a593Smuzhiyun 	if (!dir) {
244*4882a593Smuzhiyun 		pr_info("open dir failed: %s \n", strerror(errno));
245*4882a593Smuzhiyun 		return invalid_wifi_device_id;
246*4882a593Smuzhiyun 	}
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	while ((next = readdir(dir)) != NULL) {
249*4882a593Smuzhiyun 		char line[256];
250*4882a593Smuzhiyun 		char uevent_file[256] = {0};
251*4882a593Smuzhiyun 		sprintf(uevent_file, "%s/%s/uevent", bus_dir, next->d_name);
252*4882a593Smuzhiyun 		pr_info("uevent path:%s \n", uevent_file);
253*4882a593Smuzhiyun 		fp = fopen(uevent_file, "r");
254*4882a593Smuzhiyun 		if (NULL == fp) {
255*4882a593Smuzhiyun 			continue;
256*4882a593Smuzhiyun 		}
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 		while (fgets(line, sizeof(line), fp)) {
259*4882a593Smuzhiyun 			char *pos = NULL;
260*4882a593Smuzhiyun 			int product_vid = 0;
261*4882a593Smuzhiyun 			int product_did = 0;
262*4882a593Smuzhiyun 			int producd_bcddev = 0;
263*4882a593Smuzhiyun 			char temp[10] = {0};
264*4882a593Smuzhiyun 			pos = strstr(line, prefix);
265*4882a593Smuzhiyun 			pr_info("line: %s, prefix: %s.\n", line, prefix);
266*4882a593Smuzhiyun 			if (pos != NULL) {
267*4882a593Smuzhiyun 				if (strncmp(bus_dir, USB_DIR, sizeof(USB_DIR)) == 0)
268*4882a593Smuzhiyun 					sscanf(pos + 8, "%x/%x/%x", &product_vid, &product_did, &producd_bcddev);
269*4882a593Smuzhiyun 				else if (strncmp(bus_dir, SDIO_DIR, sizeof(SDIO_DIR)) == 0)
270*4882a593Smuzhiyun 					sscanf(pos + 8, "%x:%x", &product_vid, &product_did);
271*4882a593Smuzhiyun 				else if (strncmp(bus_dir, PCIE_DIR, sizeof(PCIE_DIR)) == 0)
272*4882a593Smuzhiyun 					sscanf(pos + 7, "%x:%x", &product_vid, &product_did);
273*4882a593Smuzhiyun 				else
274*4882a593Smuzhiyun 					return invalid_wifi_device_id;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 				sprintf(temp, "%04x:%04x", product_vid, product_did);
277*4882a593Smuzhiyun 				pr_info("pid:vid : %s \n", temp);
278*4882a593Smuzhiyun 				for (i = 0; i < idnum; i++) {
279*4882a593Smuzhiyun 					if (0 == strncmp(temp, supported_wifi_devices[i].wifi_vid_pid, 9)) {
280*4882a593Smuzhiyun 						pr_info("found device pid:vid : %s \n", temp);
281*4882a593Smuzhiyun 						strcpy(recoginze_wifi_chip, supported_wifi_devices[i].wifi_name);
282*4882a593Smuzhiyun 						identify_sucess = 1 ;
283*4882a593Smuzhiyun 						ret = 0;
284*4882a593Smuzhiyun 						fclose(fp);
285*4882a593Smuzhiyun 						goto ready;
286*4882a593Smuzhiyun 					}
287*4882a593Smuzhiyun 				}
288*4882a593Smuzhiyun 			}
289*4882a593Smuzhiyun 		}
290*4882a593Smuzhiyun 		fclose(fp);
291*4882a593Smuzhiyun 	}
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	ret = invalid_wifi_device_id;
294*4882a593Smuzhiyun ready:
295*4882a593Smuzhiyun 	closedir(dir);
296*4882a593Smuzhiyun 	pr_info("wifi detectd return ret:%d \n", ret);
297*4882a593Smuzhiyun 	return ret;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
check_wifi_chip_type_string(char * type)300*4882a593Smuzhiyun int check_wifi_chip_type_string(char *type)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	if (identify_sucess == -1) {
303*4882a593Smuzhiyun 		if (get_wifi_device_id(SDIO_DIR, PREFIX_SDIO) == 0)
304*4882a593Smuzhiyun 			pr_info("SDIO WIFI identify sucess \n");
305*4882a593Smuzhiyun 		else if (get_wifi_device_id(USB_DIR, PREFIX_USB) == 0)
306*4882a593Smuzhiyun 			pr_info("USB WIFI identify sucess \n");
307*4882a593Smuzhiyun 		else if (get_wifi_device_id(PCIE_DIR, PREFIX_PCIE) == 0)
308*4882a593Smuzhiyun 			pr_info("PCIE WIFI identify sucess \n");
309*4882a593Smuzhiyun 		else {
310*4882a593Smuzhiyun 			pr_info("maybe there is no usb wifi or sdio or pcie wifi, set default wifi module Brocom APXXX \n");
311*4882a593Smuzhiyun 			strcpy(recoginze_wifi_chip, "APXXX");
312*4882a593Smuzhiyun 			identify_sucess = 1 ;
313*4882a593Smuzhiyun 		}
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	strcpy(type, recoginze_wifi_chip);
317*4882a593Smuzhiyun 	pr_info("%s: %s \n", __func__, type);
318*4882a593Smuzhiyun 	return 0;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /* 0 - not ready; 1 - ready. */
check_wireless_ready(void)322*4882a593Smuzhiyun int check_wireless_ready(void)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	char line[1024], *ptr = NULL;
325*4882a593Smuzhiyun 	FILE *fp = NULL;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	fp = fopen("/proc/net/dev", "r");
328*4882a593Smuzhiyun 	if (fp == NULL) {
329*4882a593Smuzhiyun 		pr_info("Couldn't open /proc/net/dev \n");
330*4882a593Smuzhiyun 		return 0;
331*4882a593Smuzhiyun 	}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	while(fgets(line, 1024, fp)) {
334*4882a593Smuzhiyun 		if ((strstr(line, "wlan0:") != NULL) || (strstr(line, "p2p0:") != NULL)) {
335*4882a593Smuzhiyun 			pr_info("Wifi driver is ready for now... \n");
336*4882a593Smuzhiyun 			fclose(fp);
337*4882a593Smuzhiyun 			return 1;
338*4882a593Smuzhiyun 		}
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	fclose(fp);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	pr_info("Wifi driver is not ready.\n");
344*4882a593Smuzhiyun 	return 0;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun static const char BT_TEST_FILE[] = "/userdata/bt_pcba_test";
create_bt_test_file_for_brcm(void)348*4882a593Smuzhiyun static int create_bt_test_file_for_brcm(void)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun 	FILE* fp;
351*4882a593Smuzhiyun 	char cmdline[512] = {0};
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	fp = fopen(BT_TEST_FILE, "wt+");
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	if (fp != 0) {
356*4882a593Smuzhiyun 		fputs("killall brcm_patchram_plus1\n", fp);
357*4882a593Smuzhiyun 		fputs("echo 0 > /sys/class/rfkill/rfkill0/state\n", fp);
358*4882a593Smuzhiyun 		fputs("echo 0 > /proc/bluetooth/sleep/btwrite\n", fp);
359*4882a593Smuzhiyun 		fputs("sleep 1\n", fp);
360*4882a593Smuzhiyun 		fputs("echo 1 > /sys/class/rfkill/rfkill0/state\n", fp);
361*4882a593Smuzhiyun 		fputs("echo 1 > /proc/bluetooth/sleep/btwrite\n", fp);
362*4882a593Smuzhiyun 		fputs("sleep 1\n", fp);
363*4882a593Smuzhiyun 		sprintf(cmdline, "brcm_patchram_plus1 --enable_hci --no2bytes --use_baudrate_for_download  --tosleep  200000 --baudrate 1500000 --patchram  %s %s &\n", AP_BT_FIRMWARE_MODULE_PATH, bt_tty_dev);
364*4882a593Smuzhiyun 		fputs(cmdline, fp);
365*4882a593Smuzhiyun 		fputs("sleep 1\n", fp);
366*4882a593Smuzhiyun 		fclose(fp);
367*4882a593Smuzhiyun 		system("chmod 777 /userdata/bt_pcba_test");
368*4882a593Smuzhiyun 		system("mount --bind /userdata/bt_pcba_test /usr/bin/bt_pcba_test");
369*4882a593Smuzhiyun 		system("mount --bind /userdata/bt_pcba_test /usr/bin/bt_init.sh");
370*4882a593Smuzhiyun 		return 0;
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 	return -1;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun 
create_bt_test_file_for_rtl(void)375*4882a593Smuzhiyun static int create_bt_test_file_for_rtl(void)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun 	FILE* fp;
378*4882a593Smuzhiyun 	char cmdline[512] = {0};
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	fp = fopen(BT_TEST_FILE, "wt+");
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	if (strstr(recoginze_wifi_chip , "E")) {
383*4882a593Smuzhiyun 		system("chmod 777 /userdata/bt_pcba_test");
384*4882a593Smuzhiyun 		system("mount --bind /userdata/bt_pcba_test /usr/bin/bt_pcba_test");
385*4882a593Smuzhiyun 		fclose(fp);
386*4882a593Smuzhiyun 		return 0;
387*4882a593Smuzhiyun 	}
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	if (fp != 0) {
390*4882a593Smuzhiyun 		fputs("echo 0 > /sys/class/rfkill/rfkill0/state\n", fp);
391*4882a593Smuzhiyun 		fputs("echo 0 > /proc/bluetooth/sleep/btwrite\n", fp);
392*4882a593Smuzhiyun 		fputs("sleep 0.5\n", fp);
393*4882a593Smuzhiyun 		fputs("echo 1 > /sys/class/rfkill/rfkill0/state\n", fp);
394*4882a593Smuzhiyun 		fputs("echo 1 > /proc/bluetooth/sleep/btwrite\n", fp);
395*4882a593Smuzhiyun 		fputs("sleep 0.5\n", fp);
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 		fputs("insmod /usr/lib/modules/hci_uart.ko\n", fp);
398*4882a593Smuzhiyun 		fputs("sleep 1\n", fp);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 		sprintf(cmdline, "rtk_hciattach -n -s 115200 %s rtk_h5 &\n", bt_tty_dev);
401*4882a593Smuzhiyun 		fputs(cmdline, fp);
402*4882a593Smuzhiyun 		fputs("sleep 0.5\n", fp);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 		fclose(fp);
405*4882a593Smuzhiyun 		system("chmod 777 /userdata/bt_pcba_test");
406*4882a593Smuzhiyun 		system("mount --bind /userdata/bt_pcba_test /usr/bin/bt_pcba_test");
407*4882a593Smuzhiyun 		return 0;
408*4882a593Smuzhiyun 	}
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	return -1;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
wifibt_load_driver(void)413*4882a593Smuzhiyun int wifibt_load_driver(void)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun 	char* wifi_ko_path = NULL ;
416*4882a593Smuzhiyun 	char* wifi_ko_arg =NULL;
417*4882a593Smuzhiyun 	int i = 0;
418*4882a593Smuzhiyun 	int count = 100; /* wait at most 20 seconds for completion */
419*4882a593Smuzhiyun 	char temp[256] = {0};
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (wifi_dirver_is_loaded == 1) {
422*4882a593Smuzhiyun 		return 0;
423*4882a593Smuzhiyun 	}
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	if (check_wireless_ready()) {
426*4882a593Smuzhiyun 		wifi_dirver_is_loaded = 1;
427*4882a593Smuzhiyun 	}
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	pr_info("%s \n", __func__);
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	if (wifi_type[0] == 0) {
432*4882a593Smuzhiyun 		check_wifi_chip_type_string(wifi_type);
433*4882a593Smuzhiyun 		save_wifi_chip_type(wifi_type);
434*4882a593Smuzhiyun 	}
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	for (i = 0; i < (int)(sizeof(module_list) / sizeof(module_list[0])); i++) {
437*4882a593Smuzhiyun 		if (!strcmp(wifi_type , module_list[i].wifi_name)) {
438*4882a593Smuzhiyun 			wifi_ko_path = module_list[i].wifi_module_path;
439*4882a593Smuzhiyun 			wifi_ko_arg = module_list[i].wifi_module_arg;
440*4882a593Smuzhiyun 			bt_firmware_patch = module_list[i].bt_firmware_path;
441*4882a593Smuzhiyun 			pr_info("%s matched ko file path  %s \n", __func__, wifi_ko_path);
442*4882a593Smuzhiyun 			break;
443*4882a593Smuzhiyun 		}
444*4882a593Smuzhiyun 	}
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	if (wifi_ko_path == NULL) {
447*4882a593Smuzhiyun 		pr_info("%s falied to find wifi driver for type=%s \n", __func__, wifi_type);
448*4882a593Smuzhiyun 		return -1;
449*4882a593Smuzhiyun 	}
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	if (strstr(recoginze_wifi_chip , "AP")) {
452*4882a593Smuzhiyun 		if (access("/system/lib/modules/dhd_static_buf.ko", F_OK) == 0)
453*4882a593Smuzhiyun 			system("insmod /system/lib/modules/dhd_static_buf.ko");
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	usleep(500 * 1000);
457*4882a593Smuzhiyun 	sprintf(temp, "insmod %s %s", wifi_ko_path, wifi_ko_arg);
458*4882a593Smuzhiyun 	pr_info("%s %s\n", __func__, temp);
459*4882a593Smuzhiyun 	if (system(temp)) {
460*4882a593Smuzhiyun 		pr_info("%s insmod %s failed \n", __func__, wifi_ko_path);
461*4882a593Smuzhiyun 		return -1;
462*4882a593Smuzhiyun 	}
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	while (count-- > 0) {
465*4882a593Smuzhiyun 		if (check_wireless_ready())
466*4882a593Smuzhiyun 			break;
467*4882a593Smuzhiyun 		usleep(200000);
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	//bt init
471*4882a593Smuzhiyun 	if (strstr(recoginze_wifi_chip , "AP")) {
472*4882a593Smuzhiyun 		create_bt_test_file_for_brcm();
473*4882a593Smuzhiyun 		system("killall brcm_patchram_plus1");
474*4882a593Smuzhiyun 		memset(temp, 0, 256);
475*4882a593Smuzhiyun 		system("echo 0 > /sys/class/rfkill/rfkill0/state");
476*4882a593Smuzhiyun 		system("echo 0 > /proc/bluetooth/sleep/btwrite");
477*4882a593Smuzhiyun 		usleep(5000);
478*4882a593Smuzhiyun 		system("echo 1 > /sys/class/rfkill/rfkill0/state");
479*4882a593Smuzhiyun 		system("echo 1 > /proc/bluetooth/sleep/btwrite");
480*4882a593Smuzhiyun 		usleep(5000);
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 		sprintf(temp, "brcm_patchram_plus1 --enable_hci --no2bytes --use_baudrate_for_download  --tosleep  200000 --baudrate 1500000 --patchram  %s %s &", AP_BT_FIRMWARE_MODULE_PATH, bt_tty_dev);
483*4882a593Smuzhiyun 		pr_info("%s %s\n", __func__, temp);
484*4882a593Smuzhiyun 		if (system(temp)) {
485*4882a593Smuzhiyun 			pr_info("bt_init: %s failed \n", temp);
486*4882a593Smuzhiyun 			return -1;
487*4882a593Smuzhiyun 		}
488*4882a593Smuzhiyun 	} else if (strstr(recoginze_wifi_chip , "RTL")) {
489*4882a593Smuzhiyun 		create_bt_test_file_for_rtl();
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 		if (strstr(recoginze_wifi_chip , "E")) {
492*4882a593Smuzhiyun 			system("insmod /system/lib/modules/rtk_btusb.ko");
493*4882a593Smuzhiyun 		} else {
494*4882a593Smuzhiyun 			system("echo 0 > /sys/class/rfkill/rfkill0/state");
495*4882a593Smuzhiyun 			system("echo 0 > /proc/bluetooth/sleep/btwrite");
496*4882a593Smuzhiyun 			usleep(5000);
497*4882a593Smuzhiyun 			system("echo 1 > /sys/class/rfkill/rfkill0/state");
498*4882a593Smuzhiyun 			system("echo 1 > /proc/bluetooth/sleep/btwrite");
499*4882a593Smuzhiyun 			usleep(5000);
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 			system("insmod /usr/lib/modules/hci_uart.ko");
502*4882a593Smuzhiyun 			usleep(5000);
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 			memset(temp, 0, 256);
505*4882a593Smuzhiyun 			sprintf(temp, "rtk_hciattach -n -s 115200 %s rtk_h5 &", bt_tty_dev);
506*4882a593Smuzhiyun 			system(temp);
507*4882a593Smuzhiyun 			usleep(5000);
508*4882a593Smuzhiyun 		}
509*4882a593Smuzhiyun 	}
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	return 0;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun 
main(int argc,char * argv[])514*4882a593Smuzhiyun int main(int argc, char *argv[])
515*4882a593Smuzhiyun {
516*4882a593Smuzhiyun 	pr_info("Rockchip Linux WifiBt init (ver 2.0)\n");
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	strncpy(bt_tty_dev, argv[1], 10);
519*4882a593Smuzhiyun 	pr_info("BT TTY: %s \n", bt_tty_dev);
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	wifibt_load_driver();
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	return 0;
524*4882a593Smuzhiyun }
525