USB: fix Coding Style.
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_bc.c
1 /*
2  * Copyright (C) 2013-2014 ROCKCHIP, Inc.
3  * Author: LIYUNZHI  <lyz@rock-chips.com>
4  * Data: 2014-3-14
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include "usbdev_rk.h"
18
19 /****** GET and SET REGISTER FIELDS IN GRF UOC ******/
20
21 #define BC_GET(x) grf_uoc_get_field(&pBC_UOC_FIELDS[x])
22 #define BC_SET(x, v) grf_uoc_set_field(&pBC_UOC_FIELDS[x], v)
23
24 uoc_field_t *pBC_UOC_FIELDS;
25 static void *pGRF_BASE;
26 int rk_usb_charger_status = USB_BC_TYPE_DISCNT;
27
28 /****** GET REGISTER FIELD INFO FROM Device Tree ******/
29
30 static inline void *get_grf_base(struct device_node *np)
31 {
32         void *grf_base = of_iomap(of_get_parent(np), 0);
33
34         if (of_machine_is_compatible("rockchip,rk3188"))
35                 grf_base -= 0xac;
36         else if (of_machine_is_compatible("rockchip,rk3288"))
37                 grf_base -= 0x284;
38
39         return grf_base;
40 }
41
42 void grf_uoc_set_field(uoc_field_t *field, u32 value)
43 {
44         if (!uoc_field_valid(field))
45                 return;
46         grf_uoc_set(pGRF_BASE, field->b.offset, field->b.bitmap, field->b.mask,
47                     value);
48 }
49
50 u32 grf_uoc_get_field(uoc_field_t *field)
51 {
52         return grf_uoc_get(pGRF_BASE, field->b.offset, field->b.bitmap,
53                            field->b.mask);
54 }
55
56 static inline int uoc_init_field(struct device_node *np, const char *name,
57                                  uoc_field_t *f)
58 {
59         of_property_read_u32_array(np, name, f->array, 3);
60         /* printk("usb battery charger detect: uoc_init_field: 0x%08x %d %d \n",
61          *        f->b.offset,f->b.bitmap,f->b.mask);*/
62         return 0;
63 }
64
65 static inline void uoc_init_synop(struct device_node *np)
66 {
67         pBC_UOC_FIELDS =
68             (uoc_field_t *) kzalloc(SYNOP_BC_MAX * sizeof(uoc_field_t),
69                                     GFP_ATOMIC);
70
71         uoc_init_field(np, "rk_usb,bvalid", &pBC_UOC_FIELDS[SYNOP_BC_BVALID]);
72         uoc_init_field(np, "rk_usb,dcdenb", &pBC_UOC_FIELDS[SYNOP_BC_DCDENB]);
73         uoc_init_field(np, "rk_usb,vdatsrcenb",
74                        &pBC_UOC_FIELDS[SYNOP_BC_VDATSRCENB]);
75         uoc_init_field(np, "rk_usb,vdatdetenb",
76                        &pBC_UOC_FIELDS[SYNOP_BC_VDATDETENB]);
77         uoc_init_field(np, "rk_usb,chrgsel", &pBC_UOC_FIELDS[SYNOP_BC_CHRGSEL]);
78         uoc_init_field(np, "rk_usb,chgdet", &pBC_UOC_FIELDS[SYNOP_BC_CHGDET]);
79         uoc_init_field(np, "rk_usb,fsvplus", &pBC_UOC_FIELDS[SYNOP_BC_FSVPLUS]);
80         uoc_init_field(np, "rk_usb,fsvminus",
81                        &pBC_UOC_FIELDS[SYNOP_BC_FSVMINUS]);
82 }
83
84 static inline void uoc_init_rk(struct device_node *np)
85 {
86         pBC_UOC_FIELDS =
87             (uoc_field_t *) kzalloc(RK_BC_MAX * sizeof(uoc_field_t),
88                                     GFP_ATOMIC);
89
90         uoc_init_field(np, "rk_usb,bvalid", &pBC_UOC_FIELDS[RK_BC_BVALID]);
91         uoc_init_field(np, "rk_usb,line", &pBC_UOC_FIELDS[RK_BC_LINESTATE]);
92         uoc_init_field(np, "rk_usb,softctrl", &pBC_UOC_FIELDS[RK_BC_SOFTCTRL]);
93         uoc_init_field(np, "rk_usb,opmode", &pBC_UOC_FIELDS[RK_BC_OPMODE]);
94         uoc_init_field(np, "rk_usb,xcvrsel", &pBC_UOC_FIELDS[RK_BC_XCVRSELECT]);
95         uoc_init_field(np, "rk_usb,termsel", &pBC_UOC_FIELDS[RK_BC_TERMSELECT]);
96 }
97
98 static inline void uoc_init_inno(struct device_node *np)
99 {
100         ;
101 }
102
103 /****** BATTERY CHARGER DETECT FUNCTIONS ******/
104
105 int usb_battery_charger_detect_rk(bool wait)
106 {
107
108         int port_type = USB_BC_TYPE_DISCNT;
109
110         if (BC_GET(RK_BC_BVALID)) {
111                 mdelay(10);
112                 BC_SET(RK_BC_SOFTCTRL, 1);
113                 BC_SET(RK_BC_OPMODE, 0);
114                 BC_SET(RK_BC_XCVRSELECT, 1);
115                 BC_SET(RK_BC_TERMSELECT, 1);
116
117                 mdelay(1);
118                 switch (BC_GET(RK_BC_LINESTATE)) {
119                 case 1:
120                         port_type = USB_BC_TYPE_SDP;
121                         break;
122
123                 case 3:
124                         port_type = USB_BC_TYPE_DCP;
125                         break;
126
127                 default:
128                         port_type = USB_BC_TYPE_SDP;
129                         /* printk("%s linestate = %d bad status\n",
130                          *        __func__, BC_GET(RK_BC_LINESTATE)); */
131                 }
132
133         }
134         BC_SET(RK_BC_SOFTCTRL, 0);
135
136         /* printk("%s , battery_charger_detect %d\n",
137          *        __func__, port_type); */
138         return port_type;
139 }
140
141 int usb_battery_charger_detect_inno(bool wait)
142 {
143
144         return -1;
145 }
146
147 /* When do BC detect PCD pull-up register should be disabled  */
148 /* wait wait for dcd timeout 900ms */
149 int usb_battery_charger_detect_synop(bool wait)
150 {
151         int port_type = USB_BC_TYPE_DISCNT;
152         int dcd_state;
153         int timeout = 0, i = 0;
154         /* VBUS Valid detect */
155         if (BC_GET(SYNOP_BC_BVALID)) {
156                 if (wait) {
157                         /* Do DCD */
158                         dcd_state = DCD_TIMEOUT;
159                         BC_SET(SYNOP_BC_DCDENB, 1);
160                         timeout = T_DCD_TIMEOUT;
161                         while (timeout--) {
162                                 if (!BC_GET(SYNOP_BC_FSVPLUS))
163                                         i++;
164                                 if (i >= 3) {
165                                         /* It is a filter here to assure data
166                                          * lines contacted for at least 3ms */
167                                         dcd_state = DCD_POSITIVE;
168                                         break;
169                                 }
170
171                                 mdelay(1);
172                         }
173                         BC_SET(SYNOP_BC_DCDENB, 0);
174                 } else {
175                         dcd_state = DCD_PASSED;
176                 }
177                 if (dcd_state == DCD_TIMEOUT) {
178                         port_type = USB_BC_TYPE_UNKNOW;
179                         goto out;
180                 }
181
182                 /* Turn on VDPSRC */
183                 /* Primary Detection */
184                 BC_SET(SYNOP_BC_VDATSRCENB, 1);
185                 BC_SET(SYNOP_BC_VDATDETENB, 1);
186                 BC_SET(SYNOP_BC_CHRGSEL, 0);
187
188                 udelay(T_BC_CHGDET_VALID);
189
190                 /* SDP and CDP/DCP distinguish */
191                 if (BC_GET(SYNOP_BC_CHGDET)) {
192                         /* Turn off VDPSRC */
193                         BC_SET(SYNOP_BC_VDATSRCENB, 0);
194                         BC_SET(SYNOP_BC_VDATDETENB, 0);
195
196                         udelay(T_BC_CHGDET_VALID);
197
198                         /* Turn on VDMSRC */
199                         BC_SET(SYNOP_BC_VDATSRCENB, 1);
200                         BC_SET(SYNOP_BC_VDATDETENB, 1);
201                         BC_SET(SYNOP_BC_CHRGSEL, 1);
202                         udelay(T_BC_CHGDET_VALID);
203                         if (BC_GET(SYNOP_BC_CHGDET))
204                                 port_type = USB_BC_TYPE_DCP;
205                         else
206                                 port_type = USB_BC_TYPE_CDP;
207                 } else {
208                         port_type = USB_BC_TYPE_SDP;
209                 }
210                 BC_SET(SYNOP_BC_VDATSRCENB, 0);
211                 BC_SET(SYNOP_BC_VDATDETENB, 0);
212                 BC_SET(SYNOP_BC_CHRGSEL, 0);
213
214         }
215 out:
216         printk("%s , battery_charger_detect %d, %s DCD, dcd_state = %d\n",
217                __func__, port_type, wait ? "wait" : "pass", dcd_state);
218         return port_type;
219 }
220
221 int usb_battery_charger_detect(bool wait)
222 {
223         static struct device_node *np;
224         if (!np)
225                 np = of_find_node_by_name(NULL, "usb_bc");
226         if (!np)
227                 goto fail;
228         if (!pGRF_BASE)
229                 pGRF_BASE = get_grf_base(np);
230
231         if (of_device_is_compatible(np, "rockchip,ctrl")) {
232                 if (!pBC_UOC_FIELDS)
233                         uoc_init_rk(np);
234                 return usb_battery_charger_detect_rk(wait);
235         }
236
237         else if (of_device_is_compatible(np, "synopsys,phy")) {
238                 if (!pBC_UOC_FIELDS)
239                         uoc_init_synop(np);
240                 return usb_battery_charger_detect_synop(wait);
241         }
242
243         else if (of_device_is_compatible(np, "inno,phy")) {
244                 if (!pBC_UOC_FIELDS)
245                         uoc_init_inno(np);
246                 return usb_battery_charger_detect_inno(wait);
247         }
248 fail:
249         return -1;
250 }
251
252 EXPORT_SYMBOL(usb_battery_charger_detect);
253
254 int dwc_otg_check_dpdm(bool wait)
255 {
256         static struct device_node *np;
257         if (!np)
258                 np = of_find_node_by_name(NULL, "usb_bc");
259         if (!np)
260                 return -1;
261         if (!pGRF_BASE)
262                 pGRF_BASE = get_grf_base(np);
263
264         if (of_device_is_compatible(np, "rockchip,ctrl")) {
265                 if (!pBC_UOC_FIELDS)
266                         uoc_init_rk(np);
267                 if (!BC_GET(RK_BC_BVALID))
268                         rk_usb_charger_status = USB_BC_TYPE_DISCNT;
269
270         } else if (of_device_is_compatible(np, "synopsys,phy")) {
271                 if (!pBC_UOC_FIELDS)
272                         uoc_init_synop(np);
273                 if (!BC_GET(SYNOP_BC_BVALID))
274                         rk_usb_charger_status = USB_BC_TYPE_DISCNT;
275
276         } else if (of_device_is_compatible(np, "inno,phy")) {
277                 if (!pBC_UOC_FIELDS)
278                         uoc_init_inno(np);
279         }
280
281         return rk_usb_charger_status;
282 }
283 EXPORT_SYMBOL(dwc_otg_check_dpdm);
284
285 /* CALL BACK FUNCTION for USB CHARGER TYPE CHANGED */
286
287 void usb20otg_battery_charger_detect_cb(int charger_type_new)
288 {
289         static int charger_type = USB_BC_TYPE_DISCNT;
290         if (charger_type != charger_type_new) {
291                 switch (charger_type_new) {
292                 case USB_BC_TYPE_DISCNT:
293                         break;
294
295                 case USB_BC_TYPE_SDP:
296                         break;
297
298                 case USB_BC_TYPE_DCP:
299                         break;
300
301                 case USB_BC_TYPE_CDP:
302                         break;
303
304                 case USB_BC_TYPE_UNKNOW:
305                         break;
306
307                 default:
308                         break;
309                 }
310
311                 /* printk("%s , battery_charger_detect %d\n",
312                  *        __func__, charger_type_new);*/
313         }
314         charger_type = charger_type_new;
315 }