2 * Copyright (C) 2013-2014 ROCKCHIP, Inc.
3 * Author: LIYUNZHI <lyz@rock-chips.com>
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.
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.
17 #include "usbdev_rk.h"
19 /****** GET and SET REGISTER FIELDS IN GRF UOC ******/
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)
24 uoc_field_t *pBC_UOC_FIELDS = NULL;
25 static void *pGRF_BASE = NULL;
27 /****** GET REGISTER FIELD INFO FROM Device Tree ******/
29 inline static void *get_grf_base(struct device_node *np)
31 void *grf_base = of_iomap(of_get_parent(np), 0);
32 if(of_machine_is_compatible("rockchip,rk3188"))
33 return (grf_base - 0xac);
34 else if(of_machine_is_compatible("rockchip,rk3288"))
35 return (grf_base - 0x284);
39 void grf_uoc_set_field(uoc_field_t *field, u32 value)
41 if(!uoc_field_valid(field))
43 grf_uoc_set(pGRF_BASE, field->b.offset, field->b.bitmap, field->b.mask, value);
46 u32 grf_uoc_get_field(uoc_field_t *field)
48 return grf_uoc_get(pGRF_BASE, field->b.offset, field->b.bitmap, field->b.mask);
51 inline static int uoc_init_field(struct device_node *np, const char* name, uoc_field_t *f)
53 of_property_read_u32_array(np, name, f->array, 3);
54 //printk("usb battery charger detect: uoc_init_field: 0x%08x %d %d \n",f->b.offset,f->b.bitmap,f->b.mask);
57 inline static void uoc_init_synop(struct device_node *np)
59 pBC_UOC_FIELDS = (uoc_field_t *)kzalloc(SYNOP_BC_MAX * sizeof(uoc_field_t), GFP_ATOMIC);
61 uoc_init_field(np, "rk_usb,bvalid", &pBC_UOC_FIELDS[SYNOP_BC_BVALID]);
62 uoc_init_field(np, "rk_usb,dcdenb", &pBC_UOC_FIELDS[SYNOP_BC_DCDENB]);
63 uoc_init_field(np, "rk_usb,vdatsrcenb", &pBC_UOC_FIELDS[SYNOP_BC_VDATSRCENB]);
64 uoc_init_field(np, "rk_usb,vdatdetenb", &pBC_UOC_FIELDS[SYNOP_BC_VDATDETENB]);
65 uoc_init_field(np, "rk_usb,chrgsel", &pBC_UOC_FIELDS[SYNOP_BC_CHRGSEL]);
66 uoc_init_field(np, "rk_usb,chgdet", &pBC_UOC_FIELDS[SYNOP_BC_CHGDET]);
69 inline static void uoc_init_rk(struct device_node *np)
71 pBC_UOC_FIELDS = (uoc_field_t *)kzalloc(RK_BC_MAX * sizeof(uoc_field_t), GFP_ATOMIC);
73 uoc_init_field(np, "rk_usb,bvalid", &pBC_UOC_FIELDS[RK_BC_BVALID]);
74 uoc_init_field(np, "rk_usb,line", &pBC_UOC_FIELDS[RK_BC_LINESTATE]);
75 uoc_init_field(np, "rk_usb,softctrl", &pBC_UOC_FIELDS[RK_BC_SOFTCTRL]);
76 uoc_init_field(np, "rk_usb,opmode", &pBC_UOC_FIELDS[RK_BC_OPMODE]);
77 uoc_init_field(np, "rk_usb,xcvrsel", &pBC_UOC_FIELDS[RK_BC_XCVRSELECT]);
78 uoc_init_field(np, "rk_usb,termsel", &pBC_UOC_FIELDS[RK_BC_TERMSELECT]);
81 inline static void uoc_init_inno(struct device_node *np)
86 /****** BATTERY CHARGER DETECT FUNCTIONS ******/
88 int usb_battery_charger_detect_rk(bool wait)
91 int port_type = USB_BC_TYPE_DISCNT;
93 if(BC_GET(RK_BC_BVALID))
96 BC_SET(RK_BC_SOFTCTRL, 1);
97 BC_SET(RK_BC_OPMODE, 0);
98 BC_SET(RK_BC_XCVRSELECT, 1);
99 BC_SET(RK_BC_TERMSELECT, 1);
102 switch (BC_GET(RK_BC_LINESTATE))
105 port_type = USB_BC_TYPE_SDP;
109 port_type = USB_BC_TYPE_DCP;
113 port_type = USB_BC_TYPE_SDP;
114 //printk("%s linestate = %d bad status\n", __func__, BC_GET(RK_BC_LINESTATE));
118 BC_SET(RK_BC_SOFTCTRL, 0);
120 //printk("%s , battery_charger_detect %d\n", __func__, port_type);
124 int usb_battery_charger_detect_inno(bool wait)
130 /* When do BC detect PCD pull-up register should be disabled */
131 //wait wait for dcd timeout 900ms
132 int usb_battery_charger_detect_synop(bool wait)
134 int port_type = USB_BC_TYPE_DISCNT;
138 if(BC_GET(SYNOP_BC_BVALID)) {
140 mdelay(wait ? T_DCD_TIMEOUT : 1);
144 BC_SET(SYNOP_BC_VDATSRCENB, 1);
145 BC_SET(SYNOP_BC_VDATDETENB, 1);
146 BC_SET(SYNOP_BC_CHRGSEL, 0);
148 timeout = T_BC_WAIT_CHGDET;
150 if(BC_GET(SYNOP_BC_CHGDET))
155 /* SDP and CDP/DCP distinguish */
156 if(BC_GET(SYNOP_BC_CHGDET)) {
157 /* Turn off VDPSRC */
158 BC_SET(SYNOP_BC_VDATSRCENB, 0);
159 BC_SET(SYNOP_BC_VDATDETENB, 0);
161 timeout = T_BC_SRC_OFF;
163 if(!BC_GET(SYNOP_BC_CHGDET))
169 BC_SET(SYNOP_BC_VDATSRCENB, 1);
170 BC_SET(SYNOP_BC_VDATDETENB, 1);
171 BC_SET(SYNOP_BC_CHRGSEL, 1);
173 if(BC_GET(SYNOP_BC_CHGDET))
174 port_type = USB_BC_TYPE_DCP;
176 port_type = USB_BC_TYPE_CDP;
178 port_type = USB_BC_TYPE_SDP;
180 BC_SET(SYNOP_BC_VDATSRCENB, 0);
181 BC_SET(SYNOP_BC_VDATDETENB, 0);
182 BC_SET(SYNOP_BC_CHRGSEL, 0);
186 //printk("%s , battery_charger_detect %d\n", __func__, port_type);
190 int usb_battery_charger_detect(bool wait)
192 static struct device_node *np = NULL;
194 np = of_find_node_by_name(NULL, "usb_bc");
198 pGRF_BASE = get_grf_base(np);
201 if(of_device_is_compatible(np,"rockchip,ctrl")) {
204 return usb_battery_charger_detect_rk(wait);
207 else if(of_device_is_compatible(np,"synopsys,phy")) {
210 return usb_battery_charger_detect_synop(wait);
213 else if(of_device_is_compatible(np,"inno,phy")) {
216 return usb_battery_charger_detect_inno(wait);
221 EXPORT_SYMBOL(usb_battery_charger_detect);
224 int dwc_otg_check_dpdm(bool wait)
226 return usb_battery_charger_detect(wait);
228 EXPORT_SYMBOL(dwc_otg_check_dpdm);
230 /* CALL BACK FUNCTION for USB CHARGER TYPE CHANGED */
232 void usb20otg_battery_charger_detect_cb(int charger_type_new)
234 static int charger_type = USB_BC_TYPE_DISCNT;
235 if(charger_type != charger_type_new) {
236 switch(charger_type_new) {
237 case USB_BC_TYPE_DISCNT:
240 case USB_BC_TYPE_SDP:
243 case USB_BC_TYPE_DCP:
246 case USB_BC_TYPE_CDP:
249 case USB_BC_TYPE_UNKNOW:
256 //printk("%s , battery_charger_detect %d\n", __func__, charger_type_new);
258 charger_type = charger_type_new;