1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "hdf_log.h"
32 #include "device_resource_if.h"
33 #include "hdf_usb.h"
34
35 #define USB_CONTROLLER_LIST_NAME "controller_list"
36 #define USB_NODE_MATCH_ATTR "hisilicon,hi35xx-xhci"
37 #define USB_MAX_CFG_LEN 8
38 #define USB_CONTROL_NAME_LEN 32
39 #define USB_CFG_UNIT 2
40
41 struct UsbConfig {
42 uint32_t type;
43 uint32_t unit;
44 uint32_t start;
45 uint32_t end;
46 uint32_t count;
47 };
48
49 struct UsbInfo {
50 struct UsbConfig cfg[USB_MAX_CFG_LEN];
51 uint32_t len;
52 };
53
GetHdfUsbNode(const struct DeviceResourceIface * instance)54 static const struct DeviceResourceNode *GetHdfUsbNode(const struct DeviceResourceIface *instance)
55 {
56 const struct DeviceResourceNode *root = instance->GetRootNode();
57
58 if (root == NULL) {
59 HDF_LOGE("%s get root node is null\n", __func__);
60 return NULL;
61 }
62
63 return instance->GetNodeByMatchAttr(root, USB_NODE_MATCH_ATTR);
64 }
65
GetUsbControllerParam(const struct DeviceResourceIface * instance,const struct DeviceResourceNode * node,struct UsbConfig * cfg)66 static int GetUsbControllerParam(const struct DeviceResourceIface *instance, const struct DeviceResourceNode *node,
67 struct UsbConfig *cfg)
68 {
69 int ret;
70
71 ret = instance->GetUint32(node, "res_type", &cfg->type, 0);
72 if (ret != HDF_SUCCESS) {
73 HDF_LOGE("%s: read res_type fail", __func__);
74 return HDF_FAILURE;
75 }
76 ret = instance->GetUint32(node, "res_unit", &cfg->unit, 0);
77 if (ret != HDF_SUCCESS) {
78 HDF_LOGE("%s: read res unit fail", __func__);
79 return HDF_FAILURE;
80 }
81 ret = instance->GetUint32(node, "res_start", &cfg->start, 0);
82 if (ret != HDF_SUCCESS) {
83 HDF_LOGE("%s: read res type fail", __func__);
84 return HDF_FAILURE;
85 }
86 ret = instance->GetUint32(node, "res_end", &cfg->end, 0);
87 if (ret != HDF_SUCCESS) {
88 HDF_LOGE("%s: read res end fail", __func__);
89 return HDF_FAILURE;
90 }
91 ret = instance->GetUint32(node, "res_count", &cfg->count, 0);
92 if (ret != HDF_SUCCESS) {
93 HDF_LOGE("%s: read res count fail", __func__);
94 return HDF_FAILURE;
95 }
96 return HDF_SUCCESS;
97 }
98
ProcControllorParam(const struct DeviceResourceIface * instance,const struct DeviceResourceNode * node,const char * name,add_res_callback_t callback,struct UsbInfo * info)99 static int ProcControllorParam(const struct DeviceResourceIface *instance, const struct DeviceResourceNode *node,
100 const char *name, add_res_callback_t callback, struct UsbInfo *info)
101 {
102 int32_t ret;
103 const struct DeviceResourceNode *subNode = NULL;
104 const char *ctrlName = NULL;
105 uint32_t index = 0;
106 struct UsbConfig *cfg = NULL;
107
108 subNode = node->child;
109 if (subNode == NULL) {
110 return HDF_FAILURE;
111 }
112
113 DEV_RES_NODE_FOR_EACH_CHILD_NODE(node, subNode) {
114 if (index >= info->len) {
115 break;
116 }
117
118 cfg = &(info->cfg[index]);
119 ret = instance->GetString(subNode, "controller", &ctrlName, NULL);
120 if (ret != HDF_SUCCESS) {
121 HDF_LOGE("%s: read res_type fail", __func__);
122 return HDF_FAILURE;
123 }
124
125 if (strcmp(name, ctrlName) != 0) {
126 HDF_LOGI("%s: no match name", __func__);
127 continue;
128 }
129
130 ret = GetUsbControllerParam(instance, subNode, cfg);
131 if (ret != HDF_SUCCESS) {
132 HDF_LOGE("%s: read controller param fail", __func__);
133 return HDF_FAILURE;
134 }
135 callback(name, cfg->type, cfg->unit, cfg->start, cfg->end, cfg->count);
136 index++;
137 }
138
139 return HDF_SUCCESS;
140 }
141
HdfUsbInitParam(device_t dev,add_res_callback_t callback)142 static void HdfUsbInitParam(device_t dev, add_res_callback_t callback)
143 {
144 const struct DeviceResourceIface *devResInstance = NULL;
145 const struct DeviceResourceNode *hdfUsbNode = NULL;
146 const char *ctrlName = NULL;
147 int32_t ret;
148 int32_t count;
149 int32_t i;
150 struct UsbInfo info = {0};
151
152 devResInstance = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
153 if (devResInstance == NULL) {
154 HDF_LOGE("%s get devResInstance node is null", __func__);
155 return;
156 }
157 hdfUsbNode = GetHdfUsbNode(devResInstance);
158 if (hdfUsbNode == NULL) {
159 HDF_LOGE("%s get hdf usb node is null", __func__);
160 return;
161 }
162
163 count = devResInstance->GetElemNum(hdfUsbNode, USB_CONTROLLER_LIST_NAME);
164 if ((count <= 0) || (count > USB_MAX_CFG_LEN / USB_CFG_UNIT)) {
165 HDF_LOGE("%s get elemnum failed", __func__);
166 return;
167 }
168
169 info.len = USB_MAX_CFG_LEN;
170 for (i = 0; i < count; i++) {
171 ret = devResInstance->GetStringArrayElem(hdfUsbNode, USB_CONTROLLER_LIST_NAME, i, &ctrlName, NULL);
172 if (ret != HDF_SUCCESS) {
173 HDF_LOGE("%s get hdf usb list name fail", __func__);
174 return;
175 }
176
177 device_add_child(dev, ctrlName, 0);
178 ret = ProcControllorParam(devResInstance, hdfUsbNode, ctrlName, callback, &info);
179 if (ret != HDF_SUCCESS) {
180 HDF_LOGI("%s proc usb controllor not match, goto next", __func__);
181 }
182 }
183 }
184
UsbResourceInit(device_t dev,add_res_callback_t callback)185 void UsbResourceInit(device_t dev, add_res_callback_t callback)
186 {
187 if (callback == NULL) {
188 HDF_LOGE("usb resource init failed");
189 return;
190 }
191
192 HdfUsbInitParam(dev, callback);
193 }
194