blob: 5553e3985d42bcb4bbc81943b53aa053ecd999e4 [file] [log] [blame]
Matthew.Shyu55f40e92014-07-18 11:47:47 +08001/* main.c */
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <errno.h>
6#include <string.h>
7#include <sys/stat.h>
8#include <sys/types.h>
9
10#include <fcntl.h>
11#include <dirent.h>
12#include "porting.h"
13
14#define LOG_TAG "USBPower"
15
Matthew.Shyu55f40e92014-07-18 11:47:47 +080016#include "usbctrl.h"
17
18#define TOLOWER(x) ((x) | 0x20)
19
20//driver support 0-kernel2.6 1-kernel3.0(before M6) 2-kernel3.0(M6&later)
21#define DWC_DRIVER_1 0
22#define DWC_DRIVER_2 1
23#define DWC_DRIVER_3 2
24#define DWC_DRIVER_4 3
25#define DWC_DRIVER_MAX 4
26
27#define DWC_DRIVER_VERSION_1 "2.60a"
28#define DWC_DRIVER_VERSION_2 "2.20a"
29#define DWC_DRIVER_VERSION_3 "2.94a"
30#define DWC_DRIVER_VERSION_4 "3.10a"
31#define DWC_DRIVER_VERSION_LEN 5
32
33#define DWC_OTG_VERSION_DIR "/sys/bus/logicmodule/drivers/dwc_otg/version"
34
35#define IDX_ATTR_FILENAME "/sys/devices/platform/usb_phy_control/index"
36
37#define POWER_ATTR_FILENAME_1 "/sys/devices/platform/usb_phy_control/por"
38#define POWER_ATTR_FILENAME_2 "/sys/devices/lm0/peri_sleepm"
39#define POWER_ATTR_FILENAME_3 "/sys/devices/lm0/peri_sleepm"
40#define POWER_ATTR_FILENAME_4 "/sys/devices/lm0/peri_sleepm"
41//#define POWER_ATTR_FILENAME_2 "/sys/devices/lm0/peri_power"
42//#define POWER_ATTR_FILENAME_3 "/sys/devices/lm0/peri_power"
43
44#define OTG_DISABLE_FILE_NAME_1 "/sys/devices/platform/usb_phy_control/otgdisable"
45#define OTG_DISABLE_FILE_NAME_2 "/sys/devices/lm0/peri_otg_disable"
46#define OTG_DISABLE_FILE_NAME_3 "/sys/devices/lm0/peri_otg_disable"
47#define OTG_DISABLE_FILE_NAME_4 "/sys/devices/lm0/peri_otg_disable"
48
49#define CONNECT_STR "Bus Connected = 0x"
50#define CONNECT_FILE_NAME "/sys/devices/lm0/busconnected"
51#define PULLUP_FILE_NAME "/sys/devices/lm0/pullup"
52
53#define GOTGCTL_STR "GOTGCTL = 0x"
54#define GOTGCTL_FILE_NAME "/sys/devices/lm0/gotgctl"
55
56#define USB_GATE_OFF_FILE_NAME "/sys/class/aml_mod/mod_off"
57#define USB_GATE_ON_FILE_NAME "/sys/class/aml_mod/mod_on"
58
59#define USB_ID 16
60#define USB_ID_HOST 0x0
61#define USB_ID_DEVICE 0x1
62
63#define USB_SES 18
64#define USB_SES_VALID 0x3
65
66int dwc_driver_version=-1; //if dwc_driver_version == -1(not support) 0--2(driver version)
67char dwc_driver_version_str[DWC_DRIVER_MAX][DWC_DRIVER_VERSION_LEN+1] =
68{
69 DWC_DRIVER_VERSION_1,
70 DWC_DRIVER_VERSION_2,
71 DWC_DRIVER_VERSION_3,
72 DWC_DRIVER_VERSION_4
73};
74
75char power_attr_filename_str[DWC_DRIVER_MAX][64] =
76{
77 POWER_ATTR_FILENAME_1,
78 POWER_ATTR_FILENAME_2,
79 POWER_ATTR_FILENAME_3,
80 POWER_ATTR_FILENAME_4
81};
82
83char otg_disable_filename_str[DWC_DRIVER_MAX][64]=
84{
85 OTG_DISABLE_FILE_NAME_1,
86 OTG_DISABLE_FILE_NAME_2,
87 OTG_DISABLE_FILE_NAME_3,
88 OTG_DISABLE_FILE_NAME_4
89};
90
91char usb_index_str[USB_IDX_MAX][2]=
92{
93 "A","B"
94};
95
96char usb_state_str[USB_CMD_MAX][8]=
97{
98 "on","off","if"
99};
100
101char usb_state_val[USB_CMD_MAX][2]=
102{
103 "0","1","2"
104};
105char pullup_filename_str[32];
106char usb_gate_str[8]={"usb0"};
107
108static void usage(void)
109{
110 printf("usbpower USAGE:\n");
111 printf("usbpower <portindex> <cmd> \n");
112 printf(" index: A or B ; state: on/off/if(find device exist)\n");
113 printf("for example: usbpower A on\n");
114 exit(1);
115}
116
117static int get_device_if(int idx)
118{
119 int ret = 0;
120 int err = 0;
121 char line[32];
122 char filename[32];
123 FILE *fp;
124 unsigned int busconnect,gotgctl;
125
126 strcpy(filename,GOTGCTL_FILE_NAME);
127 filename[15] = idx + '0';
128
129 if((fp = fopen(filename,"r"))) {
130 if (fgets(line, 32, fp)) {
131 if (!strncmp(line, GOTGCTL_STR, strlen(GOTGCTL_STR))) {
132 sscanf(line+strlen(GOTGCTL_STR),"%x",&gotgctl);
133 }
134 else
135 {
136 SLOGE("gotgctl txt is error\n");
137 err =1;
138 }
139 } else {
140 SLOGE("Failed to read gotgctl\n");
141 err=2;
142 }
143
144 fclose(fp);
145 } else {
146 //SLOGW("No usb device\n");
147 err=3;
148 }
149
150 if(err)
151 return 0;
152
153 strcpy(filename,CONNECT_FILE_NAME);
154 filename[15] = idx + '0';
155
156 if((fp = fopen(filename,"r"))) {
157 if (fgets(line, 32, fp)) {
158 if (!strncmp(line, CONNECT_STR, strlen(CONNECT_STR))) {
159 sscanf(line+strlen(CONNECT_STR),"%x",&busconnect);
160 }else{
161 SLOGE("busconnected txt is error\n");
162 err=4;
163 }
164 } else {
165 SLOGE("Failed to read busconnected\n");
166 err=5;
167 }
168
169 fclose(fp);
170 } else {
171 //SLOGW("No usb device\n");
172 err=6;
173 }
174
175 if(err)
176 return 0;
177
178 if(((gotgctl>>USB_ID)&0x1)== USB_ID_HOST)
179 {
180 if(idx==0)
181 {
182 if(((gotgctl>>USB_SES)&0x3)== USB_SES_VALID)
183 {
184 // this case,check busconnected
185 if(busconnect==1)
186 ret = 1;
187 }
188 else
189 {
190 //this case ,can't power of,so we look it as connect
191 ret = 1;
192 }
193 }
194 else
195 {
196 if(busconnect==1)
197 ret = 1;
198 }
199 }
200 else
201 {
202 // this case,check gotgctl USB_SES_VALID
203 if(((gotgctl>>USB_SES)&0x3)== USB_SES_VALID)
204 ret = 1;
205 }
206 return ret;
207}
208
209static int set_power_ctl(int idx,int cmd)
210{
211 int ret = 0;
212 int err = 0;
213 FILE *fp,*fpp = NULL,*fpo = NULL, *fp_gotgctl,*fp_gate;
214 unsigned int gotgctl;
215 char filename[32];
216 char line[32];
217 int version = dwc_driver_version;
218
219 if(cmd == USB_CMD_OFF)
220 {
221 ret = get_device_if(idx);
222 if(ret == 1)
223 {
224 printf("Has devices on this port,can't power off!\n");
225 return ret;
226 }
227 }
228
229 strcpy(filename,GOTGCTL_FILE_NAME);
230 filename[15] = idx + '0';
231
232 if((fp_gotgctl = fopen(filename,"r"))) {
233 if (fgets(line, 32, fp_gotgctl)) {
234 if (!strncmp(line, GOTGCTL_STR, strlen(GOTGCTL_STR))) {
235 sscanf(line+strlen(GOTGCTL_STR),"%x",&gotgctl);
236 }
237 else
238 {
239 SLOGE("gotgctl txt is error\n");
240 err =1;
241 }
242 } else {
243 SLOGE("Failed to read gotgctl\n");
244 err=2;
245 }
246
247 fclose(fp_gotgctl);
248 } else {
249 //SLOGW("No usb device\n");
250 err=3;
251 }
252
253 if(err)
254 return -1;
255
256 if(version == DWC_DRIVER_1)
257 {
258 if((fp = fopen(IDX_ATTR_FILENAME,"w"))){
259 fwrite(usb_index_str[idx], 1, strlen(usb_index_str[idx]),fp);
260 fclose(fp);
261 }
262 else
263 {
264 ret = -1;
265 }
266
267 if(ret == 0)
268 {
269 if(((gotgctl>>USB_ID)&0x1)== USB_ID_HOST)
270 {
271 if((fp = fopen(power_attr_filename_str[version],"w"))){
272 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fp); //power
273 }
274 else
275 {
276 ret = -2;
277 }
278 if(fp) fclose(fp);
279 }
280 else
281 {
282 strcpy(pullup_filename_str,PULLUP_FILE_NAME);
283 pullup_filename_str[15] = idx + '0';
284 if((fp = fopen(power_attr_filename_str[version],"w")) && (fpp = fopen(pullup_filename_str,"w"))
285 && (fpo = fopen(otg_disable_filename_str[version],"w"))){
286 if(cmd == USB_CMD_OFF)
287 {
288 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fpo); //otg
289 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fpp); //pullup
290 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fp); //power
291 }
292 else
293 {
294 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fp); //power
295 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fpo); //otg
296 fwrite(usb_state_str[cmd], 1, strlen(usb_state_str[cmd]),fpp); //pullup
297 }
298 }
299 else
300 {
301 ret = -2;
302 }
303 if(fp) fclose(fp);
304 if(fpp) fclose(fpp);
305 if(fpo) fclose(fpo);
306 }
307 }
308 }
309 else
310 {
311 power_attr_filename_str[version][15] = idx + '0';
312 otg_disable_filename_str[version][15]= idx + '0';
313 usb_gate_str[3] = idx + '0';
314
315 if(((gotgctl>>USB_ID)&0x1)== USB_ID_HOST)
316 {
317 if((fp = fopen(power_attr_filename_str[version],"w"))){
318 if(cmd == USB_CMD_OFF)
319 {
320 fwrite(usb_state_val[cmd], 1, strlen(usb_state_val[cmd]),fp); //power
321 fp_gate = fopen(USB_GATE_OFF_FILE_NAME,"w");
322 if(fp_gate){
323 fwrite(usb_gate_str,1,strlen(usb_gate_str),fp_gate);
324 fclose(fp_gate);
325 }
326 }
327 else
328 {
329 fp_gate = fopen(USB_GATE_ON_FILE_NAME,"w");
330 if(fp_gate){
331 fwrite(usb_gate_str,1,strlen(usb_gate_str),fp_gate);
332 fclose(fp_gate);
333 }
334 fwrite(usb_state_val[cmd], 1, strlen(usb_state_val[cmd]),fp); //power
335 }
336 }
337 else
338 {
339 ret = -2;
340 }
341 if(fp) fclose(fp);
342 }
343 else
344 {
345 if((fp = fopen(power_attr_filename_str[version],"w"))
346 && (fpo = fopen(otg_disable_filename_str[version],"w"))){
347 if(cmd == USB_CMD_OFF)
348 {
349 fwrite(usb_state_val[cmd], 1, strlen(usb_state_val[cmd]),fpo); //otg
350 fwrite(usb_state_val[cmd], 1, strlen(usb_state_val[cmd]),fp); //power
351 fp_gate = fopen(USB_GATE_OFF_FILE_NAME,"w");
352 if(fp_gate){
353 fwrite(usb_gate_str,1,strlen(usb_gate_str),fp_gate);
354 fclose(fp_gate);
355 }
356 }
357 else
358 {
359 fp_gate = fopen(USB_GATE_ON_FILE_NAME,"w");
360 if(fp_gate){
361 fwrite(usb_gate_str,1,strlen(usb_gate_str),fp_gate);
362 fclose(fp_gate);
363 }
364 fwrite(usb_state_val[cmd], 1, strlen(usb_state_val[cmd]),fp); //power
365 fwrite(usb_state_val[cmd], 1, strlen(usb_state_val[cmd]),fpo); //otg
366 }
367 }
368 else
369 {
370 ret = -2;
371 }
372 if(fp) fclose(fp);
373 if(fpo) fclose(fpo);
374 }
375 }
376
377 return ret;
378}
379
380char ver_buf[DWC_DRIVER_VERSION_LEN + 1];
381int get_dwc_driver_version(void)
382{
383 FILE *fpv;
384 int i;
385
386 dwc_driver_version = -1;
Matthew.Shyu55f40e92014-07-18 11:47:47 +0800387 fpv = fopen(DWC_OTG_VERSION_DIR,"r");
388 if(fpv){
Jiacai.Liu18f542a2022-07-25 15:01:56 +0800389 if (fread(ver_buf,1,DWC_DRIVER_VERSION_LEN + 1,fpv) == DWC_DRIVER_VERSION_LEN + 1 ) {
390 for (i=DWC_DRIVER_1; i<DWC_DRIVER_MAX; i++) {
Matthew.Shyu55f40e92014-07-18 11:47:47 +0800391 if(strncmp(ver_buf,dwc_driver_version_str[i],DWC_DRIVER_VERSION_LEN)==0){
392 dwc_driver_version = i;
393 break;
394 }
395 }
396 }
397 fclose(fpv);
398 }
399
400 if(dwc_driver_version==-1){
401 //used other process for the version different from DWC_DRIVER_VERSION
402 return -1;
403 }
404
405 if(dwc_driver_version == DWC_DRIVER_2)
406 {
407 //now we have not supported this version.It will be supported later.
408 return -1;
409 }
410 return 0;
411}
412
413int usbpower(int index,int cmd)
414{
415 int ret=0;
416
417 if((cmd==USB_CMD_ON)||(cmd==USB_CMD_OFF))
418 {
419 ret = set_power_ctl(index,cmd);
420 }
421 else if(cmd == USB_CMD_IF)
422 {
423 ret = get_device_if(index);
424#if 0
425 if(ret == 1 )
426 printf("Has Device\n");
427 else
428 printf("No device\n");
429#endif
430 }
431
432 return ret;
433}
434
435