Merge branch develop-3.10 into develop-3.10-next
[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 char *bc_string[USB_BC_TYPE_MAX] = {"DISCONNECT",
20                                     "Stander Downstream Port",
21                                     "Dedicated Charging Port",
22                                     "Charging Downstream Port",
23                                     "UNKNOW"};
24
25 /****** GET and SET REGISTER FIELDS IN GRF UOC ******/
26 #define BC_GET(x) grf_uoc_get_field(&pBC_UOC_FIELDS[x])
27 #define BC_SET(x, v) grf_uoc_set_field(&pBC_UOC_FIELDS[x], v)
28
29 uoc_field_t *pBC_UOC_FIELDS;
30 static void *pGRF_BASE;
31 static struct mutex bc_mutex;
32
33 static enum bc_port_type usb_charger_status = USB_BC_TYPE_DISCNT;
34
35 /****** GET REGISTER FIELD INFO FROM Device Tree ******/
36
37 static inline void *get_grf_base(struct device_node *np)
38 {
39         void *grf_base = of_iomap(of_get_parent(np), 0);
40
41         if (of_machine_is_compatible("rockchip,rk3188"))
42                 grf_base -= 0xac;
43         else if (of_machine_is_compatible("rockchip,rk3288"))
44                 grf_base -= 0x284;
45
46         return grf_base;
47 }
48
49 void grf_uoc_set_field(uoc_field_t *field, u32 value)
50 {
51         if (!uoc_field_valid(field))
52                 return;
53         grf_uoc_set(pGRF_BASE, field->b.offset, field->b.bitmap, field->b.mask,
54                     value);
55 }
56
57 u32 grf_uoc_get_field(uoc_field_t *field)
58 {
59         return grf_uoc_get(pGRF_BASE, field->b.offset, field->b.bitmap,
60                            field->b.mask);
61 }
62
63 static inline int uoc_init_field(struct device_node *np, const char *name,
64                                  uoc_field_t *f)
65 {
66         of_property_read_u32_array(np, name, f->array, 3);
67         /* printk("usb battery charger detect: uoc_init_field: 0x%08x %d %d \n",
68          *        f->b.offset,f->b.bitmap,f->b.mask);*/
69         return 0;
70 }
71
72 static inline void uoc_init_synop(struct device_node *np)
73 {
74         pBC_UOC_FIELDS =
75             (uoc_field_t *) kzalloc(SYNOP_BC_MAX * sizeof(uoc_field_t),
76                                     GFP_ATOMIC);
77
78         uoc_init_field(np, "rk_usb,bvalid", &pBC_UOC_FIELDS[SYNOP_BC_BVALID]);
79         uoc_init_field(np, "rk_usb,iddig", &pBC_UOC_FIELDS[SYNOP_BC_IDDIG]);
80         uoc_init_field(np, "rk_usb,dcdenb", &pBC_UOC_FIELDS[SYNOP_BC_DCDENB]);
81         uoc_init_field(np, "rk_usb,vdatsrcenb",
82                        &pBC_UOC_FIELDS[SYNOP_BC_VDATSRCENB]);
83         uoc_init_field(np, "rk_usb,vdatdetenb",
84                        &pBC_UOC_FIELDS[SYNOP_BC_VDATDETENB]);
85         uoc_init_field(np, "rk_usb,chrgsel", &pBC_UOC_FIELDS[SYNOP_BC_CHRGSEL]);
86         uoc_init_field(np, "rk_usb,chgdet", &pBC_UOC_FIELDS[SYNOP_BC_CHGDET]);
87         uoc_init_field(np, "rk_usb,fsvplus", &pBC_UOC_FIELDS[SYNOP_BC_FSVPLUS]);
88         uoc_init_field(np, "rk_usb,fsvminus",
89                        &pBC_UOC_FIELDS[SYNOP_BC_FSVMINUS]);
90 }
91
92 static inline void uoc_init_rk(struct device_node *np)
93 {
94         pBC_UOC_FIELDS =
95             (uoc_field_t *) kzalloc(RK_BC_MAX * sizeof(uoc_field_t),
96                                     GFP_ATOMIC);
97
98         uoc_init_field(np, "rk_usb,bvalid", &pBC_UOC_FIELDS[RK_BC_BVALID]);
99         uoc_init_field(np, "rk_usb,iddig", &pBC_UOC_FIELDS[RK_BC_IDDIG]);
100         uoc_init_field(np, "rk_usb,line", &pBC_UOC_FIELDS[RK_BC_LINESTATE]);
101         uoc_init_field(np, "rk_usb,softctrl", &pBC_UOC_FIELDS[RK_BC_SOFTCTRL]);
102         uoc_init_field(np, "rk_usb,opmode", &pBC_UOC_FIELDS[RK_BC_OPMODE]);
103         uoc_init_field(np, "rk_usb,xcvrsel", &pBC_UOC_FIELDS[RK_BC_XCVRSELECT]);
104         uoc_init_field(np, "rk_usb,termsel", &pBC_UOC_FIELDS[RK_BC_TERMSELECT]);
105 }
106
107 static inline void uoc_init_inno(struct device_node *np)
108 {
109         pBC_UOC_FIELDS = (uoc_field_t *)
110                          kzalloc(INNO_BC_MAX * sizeof(uoc_field_t), GFP_ATOMIC);
111
112         uoc_init_field(np, "rk_usb,bvalid",
113                            &pBC_UOC_FIELDS[INNO_BC_BVALID]);
114         uoc_init_field(np, "rk_usb,iddig",
115                            &pBC_UOC_FIELDS[INNO_BC_IDDIG]);
116         uoc_init_field(np, "rk_usb,vdmsrcen",
117                            &pBC_UOC_FIELDS[INNO_BC_VDMSRCEN]);
118         uoc_init_field(np, "rk_usb,vdpsrcen",
119                            &pBC_UOC_FIELDS[INNO_BC_VDPSRCEN]);
120         uoc_init_field(np, "rk_usb,rdmpden",
121                            &pBC_UOC_FIELDS[INNO_BC_RDMPDEN]);
122         uoc_init_field(np, "rk_usb,idpsrcen",
123                            &pBC_UOC_FIELDS[INNO_BC_IDPSRCEN]);
124         uoc_init_field(np, "rk_usb,idmsinken",
125                            &pBC_UOC_FIELDS[INNO_BC_IDMSINKEN]);
126         uoc_init_field(np, "rk_usb,idpsinken",
127                            &pBC_UOC_FIELDS[INNO_BC_IDPSINKEN]);
128         uoc_init_field(np, "rk_usb,dpattach",
129                            &pBC_UOC_FIELDS[INNO_BC_DPATTACH]);
130         uoc_init_field(np, "rk_usb,cpdet",
131                            &pBC_UOC_FIELDS[INNO_BC_CPDET]);
132         uoc_init_field(np, "rk_usb,dcpattach",
133                            &pBC_UOC_FIELDS[INNO_BC_DCPATTACH]);
134 }
135
136 /****** BATTERY CHARGER DETECT FUNCTIONS ******/
137 bool is_connected(void)
138 {
139         if (!pGRF_BASE)
140                 return false;
141         if (BC_GET(BC_BVALID) && BC_GET(BC_IDDIG))
142                 return true;
143         return false;
144 }
145
146 enum bc_port_type usb_battery_charger_detect_rk(bool wait)
147 {
148
149         enum bc_port_type port_type = USB_BC_TYPE_DISCNT;
150
151         if (BC_GET(RK_BC_BVALID) &&
152             BC_GET(RK_BC_IDDIG)) {
153                 mdelay(10);
154                 BC_SET(RK_BC_SOFTCTRL, 1);
155                 BC_SET(RK_BC_OPMODE, 0);
156                 BC_SET(RK_BC_XCVRSELECT, 1);
157                 BC_SET(RK_BC_TERMSELECT, 1);
158
159                 mdelay(1);
160                 switch (BC_GET(RK_BC_LINESTATE)) {
161                 case 1:
162                         port_type = USB_BC_TYPE_SDP;
163                         break;
164
165                 case 3:
166                         port_type = USB_BC_TYPE_DCP;
167                         break;
168
169                 default:
170                         port_type = USB_BC_TYPE_SDP;
171                         /* printk("%s linestate = %d bad status\n",
172                          *        __func__, BC_GET(RK_BC_LINESTATE)); */
173                 }
174
175         }
176         BC_SET(RK_BC_SOFTCTRL, 0);
177
178         /* printk("%s , battery_charger_detect %d\n",
179          *        __func__, port_type); */
180         return port_type;
181 }
182
183 enum bc_port_type usb_battery_charger_detect_inno(bool wait)
184 {
185         enum bc_port_type port_type = USB_BC_TYPE_DISCNT;
186         int dcd_state = DCD_POSITIVE;
187         int timeout = 0, i = 0;
188
189         /* VBUS Valid detect */
190         if (BC_GET(INNO_BC_BVALID) &&
191                 BC_GET(INNO_BC_IDDIG)) {
192                 if (wait) {
193                         /* Do DCD */
194                         dcd_state = DCD_TIMEOUT;
195                         BC_SET(INNO_BC_RDMPDEN, 1);
196                         BC_SET(INNO_BC_IDPSRCEN, 1);
197                         timeout = T_DCD_TIMEOUT;
198                         while (timeout--) {
199                                 if (BC_GET(INNO_BC_DPATTACH))
200                                         i++;
201                                 if (i >= 3) {
202                                         /* It is a filter here to assure data
203                                          * lines contacted for at least 3ms */
204                                         dcd_state = DCD_POSITIVE;
205                                         break;
206                                 }
207                                 mdelay(1);
208                         }
209                         BC_SET(INNO_BC_RDMPDEN, 0);
210                         BC_SET(INNO_BC_IDPSRCEN, 0);
211                 } else {
212                         dcd_state = DCD_PASSED;
213                 }
214                 if (dcd_state == DCD_TIMEOUT) {
215                         port_type = USB_BC_TYPE_UNKNOW;
216                         goto out;
217                 }
218
219                 /* Turn on VDPSRC */
220                 /* Primary Detection */
221                 BC_SET(INNO_BC_VDPSRCEN, 1);
222                 BC_SET(INNO_BC_IDMSINKEN, 1);
223                 udelay(T_BC_CHGDET_VALID);
224
225                 /* SDP and CDP/DCP distinguish */
226                 if (BC_GET(INNO_BC_CPDET)) {
227                         /* Turn off VDPSRC */
228                         BC_SET(INNO_BC_VDPSRCEN, 0);
229                         BC_SET(INNO_BC_IDMSINKEN, 0);
230
231                         udelay(T_BC_CHGDET_VALID);
232
233                         /* Turn on VDMSRC */
234                         BC_SET(INNO_BC_VDMSRCEN, 1);
235                         BC_SET(INNO_BC_IDPSINKEN, 1);
236                         udelay(T_BC_CHGDET_VALID);
237                         if (BC_GET(INNO_BC_DCPATTACH))
238                                 port_type = USB_BC_TYPE_DCP;
239                         else
240                                 port_type = USB_BC_TYPE_CDP;
241                 } else {
242                         port_type = USB_BC_TYPE_SDP;
243                 }
244
245                 BC_SET(INNO_BC_VDPSRCEN, 0);
246                 BC_SET(INNO_BC_IDMSINKEN, 0);
247                 BC_SET(INNO_BC_VDMSRCEN, 0);
248                 BC_SET(INNO_BC_IDPSINKEN, 0);
249
250         }
251 out:
252         /*
253         printk("%s, Charger type %s, %s DCD, dcd_state = %d\n", __func__,
254                bc_string[port_type], wait ? "wait" : "pass", dcd_state);
255         */
256         return port_type;
257
258 }
259
260 /* When do BC detect PCD pull-up register should be disabled  */
261 /* wait wait for dcd timeout 900ms */
262 enum bc_port_type usb_battery_charger_detect_synop(bool wait)
263 {
264         enum bc_port_type port_type = USB_BC_TYPE_DISCNT;
265         int dcd_state = DCD_POSITIVE;
266         int timeout = 0, i = 0;
267
268         /* VBUS Valid detect */
269         if (BC_GET(SYNOP_BC_BVALID) &&
270             BC_GET(SYNOP_BC_IDDIG)) {
271                 if (wait) {
272                         /* Do DCD */
273                         dcd_state = DCD_TIMEOUT;
274                         BC_SET(SYNOP_BC_DCDENB, 1);
275                         timeout = T_DCD_TIMEOUT;
276                         while (timeout--) {
277                                 if (!BC_GET(SYNOP_BC_FSVPLUS))
278                                         i++;
279                                 if (i >= 3) {
280                                         /* It is a filter here to assure data
281                                          * lines contacted for at least 3ms */
282                                         dcd_state = DCD_POSITIVE;
283                                         break;
284                                 }
285
286                                 mdelay(1);
287                         }
288                         BC_SET(SYNOP_BC_DCDENB, 0);
289                 } else {
290                         dcd_state = DCD_PASSED;
291                 }
292                 if (dcd_state == DCD_TIMEOUT) {
293                         port_type = USB_BC_TYPE_UNKNOW;
294                         goto out;
295                 }
296
297                 /* Turn on VDPSRC */
298                 /* Primary Detection */
299                 BC_SET(SYNOP_BC_VDATSRCENB, 1);
300                 BC_SET(SYNOP_BC_VDATDETENB, 1);
301                 BC_SET(SYNOP_BC_CHRGSEL, 0);
302
303                 udelay(T_BC_CHGDET_VALID);
304
305                 /* SDP and CDP/DCP distinguish */
306                 if (BC_GET(SYNOP_BC_CHGDET)) {
307                         /* Turn off VDPSRC */
308                         BC_SET(SYNOP_BC_VDATSRCENB, 0);
309                         BC_SET(SYNOP_BC_VDATDETENB, 0);
310
311                         udelay(T_BC_CHGDET_VALID);
312
313                         /* Turn on VDMSRC */
314                         BC_SET(SYNOP_BC_VDATSRCENB, 1);
315                         BC_SET(SYNOP_BC_VDATDETENB, 1);
316                         BC_SET(SYNOP_BC_CHRGSEL, 1);
317                         udelay(T_BC_CHGDET_VALID);
318                         if (BC_GET(SYNOP_BC_CHGDET))
319                                 port_type = USB_BC_TYPE_DCP;
320                         else
321                                 port_type = USB_BC_TYPE_CDP;
322                 } else {
323                         port_type = USB_BC_TYPE_SDP;
324                 }
325                 BC_SET(SYNOP_BC_VDATSRCENB, 0);
326                 BC_SET(SYNOP_BC_VDATDETENB, 0);
327                 BC_SET(SYNOP_BC_CHRGSEL, 0);
328
329         }
330 out:
331         /*
332         printk("%s, Charger type %s, %s DCD, dcd_state = %d\n", __func__,
333                bc_string[port_type], wait ? "wait" : "pass", dcd_state);
334         */
335         return port_type;
336 }
337
338 enum bc_port_type usb_battery_charger_detect(bool wait)
339 {
340         static struct device_node *np;
341         enum bc_port_type ret = USB_BC_TYPE_DISCNT;
342
343         might_sleep();
344
345         if (!np)
346                 np = of_find_node_by_name(NULL, "usb_bc");
347         if (!np)
348                 return -1;
349         if (!pGRF_BASE) {
350                 pGRF_BASE = get_grf_base(np);
351                 mutex_init(&bc_mutex);
352         }
353
354         mutex_lock(&bc_mutex);
355         if (of_device_is_compatible(np, "rockchip,ctrl")) {
356                 if (!pBC_UOC_FIELDS)
357                         uoc_init_rk(np);
358                 ret = usb_battery_charger_detect_rk(wait);
359         }
360
361         else if (of_device_is_compatible(np, "synopsys,phy")) {
362                 if (!pBC_UOC_FIELDS)
363                         uoc_init_synop(np);
364                 ret = usb_battery_charger_detect_synop(wait);
365         }
366
367         else if (of_device_is_compatible(np, "inno,phy")) {
368                 if (!pBC_UOC_FIELDS)
369                         uoc_init_inno(np);
370                 ret = usb_battery_charger_detect_inno(wait);
371         }
372         if (ret == USB_BC_TYPE_UNKNOW)
373                 ret = USB_BC_TYPE_DCP;
374         mutex_unlock(&bc_mutex);
375         rk_battery_charger_detect_cb(ret);
376         return ret;
377 }
378
379 int dwc_otg_check_dpdm(bool wait)
380 {
381         return (is_connected() ? usb_charger_status : USB_BC_TYPE_DISCNT);
382 }
383 EXPORT_SYMBOL(dwc_otg_check_dpdm);
384
385 /* Call back function for USB charger type changed */
386 static ATOMIC_NOTIFIER_HEAD(rk_bc_notifier);
387
388 int rk_bc_detect_notifier_register(struct notifier_block *nb,
389                                            int *type)
390 {
391         *type = (int)usb_battery_charger_detect(0);
392         return atomic_notifier_chain_register(&rk_bc_notifier, nb);
393 }
394 EXPORT_SYMBOL(rk_bc_detect_notifier_register);
395
396 int rk_bc_detect_notifier_unregister(struct notifier_block *nb)
397 {
398         return atomic_notifier_chain_unregister(&rk_bc_notifier, nb);
399 }
400 EXPORT_SYMBOL(rk_bc_detect_notifier_unregister);
401
402 void rk_bc_detect_notifier_callback(int bc_mode)
403 {
404         atomic_notifier_call_chain(&rk_bc_notifier,bc_mode, NULL);
405 }
406
407 void rk_battery_charger_detect_cb(int new_type)
408 {
409         might_sleep();
410
411         if (usb_charger_status != new_type) {
412                 printk("%s , battery_charger_detect %d\n", __func__, new_type);
413                 atomic_notifier_call_chain(&rk_bc_notifier, new_type, NULL);
414         }
415         mutex_lock(&bc_mutex);
416         usb_charger_status = new_type;
417         mutex_unlock(&bc_mutex);
418 }