Branch data Line data Source code
1 : : /* ==========================================================================
2 : : * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
3 : : * $Revision: #44 $
4 : : * $Date: 2010/11/29 $
5 : : * $Change: 1636033 $
6 : : *
7 : : * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8 : : * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9 : : * otherwise expressly agreed to in writing between Synopsys and you.
10 : : *
11 : : * The Software IS NOT an item of Licensed Software or Licensed Product under
12 : : * any End User Software License Agreement or Agreement for Licensed Product
13 : : * with Synopsys or any supplement thereto. You are permitted to use and
14 : : * redistribute this Software in source and binary forms, with or without
15 : : * modification, provided that redistributions of source code must retain this
16 : : * notice. You may not view, use, disclose, copy or distribute this file or
17 : : * any information contained herein except pursuant to this license grant from
18 : : * Synopsys. If you do not agree with this notice, including the disclaimer
19 : : * below, then you are not authorized to use the Software.
20 : : *
21 : : * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22 : : * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : : * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25 : : * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 : : * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 : : * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 : : * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 : : * DAMAGE.
32 : : * ========================================================================== */
33 : :
34 : : /** @file
35 : : *
36 : : * The diagnostic interface will provide access to the controller for
37 : : * bringing up the hardware and testing. The Linux driver attributes
38 : : * feature will be used to provide the Linux Diagnostic
39 : : * Interface. These attributes are accessed through sysfs.
40 : : */
41 : :
42 : : /** @page "Linux Module Attributes"
43 : : *
44 : : * The Linux module attributes feature is used to provide the Linux
45 : : * Diagnostic Interface. These attributes are accessed through sysfs.
46 : : * The diagnostic interface will provide access to the controller for
47 : : * bringing up the hardware and testing.
48 : :
49 : : The following table shows the attributes.
50 : : <table>
51 : : <tr>
52 : : <td><b> Name</b></td>
53 : : <td><b> Description</b></td>
54 : : <td><b> Access</b></td>
55 : : </tr>
56 : :
57 : : <tr>
58 : : <td> mode </td>
59 : : <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
60 : : <td> Read</td>
61 : : </tr>
62 : :
63 : : <tr>
64 : : <td> hnpcapable </td>
65 : : <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
66 : : Read returns the current value.</td>
67 : : <td> Read/Write</td>
68 : : </tr>
69 : :
70 : : <tr>
71 : : <td> srpcapable </td>
72 : : <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
73 : : Read returns the current value.</td>
74 : : <td> Read/Write</td>
75 : : </tr>
76 : :
77 : : <tr>
78 : : <td> hsic_connect </td>
79 : : <td> Gets or sets the "HSIC-Connect" bit in the GLPMCFG Register.
80 : : Read returns the current value.</td>
81 : : <td> Read/Write</td>
82 : : </tr>
83 : :
84 : : <tr>
85 : : <td> inv_sel_hsic </td>
86 : : <td> Gets or sets the "Invert Select HSIC" bit in the GLPMFG Register.
87 : : Read returns the current value.</td>
88 : : <td> Read/Write</td>
89 : : </tr>
90 : :
91 : : <tr>
92 : : <td> hnp </td>
93 : : <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
94 : : <td> Read/Write</td>
95 : : </tr>
96 : :
97 : : <tr>
98 : : <td> srp </td>
99 : : <td> Initiates the Session Request Protocol. Read returns the status.</td>
100 : : <td> Read/Write</td>
101 : : </tr>
102 : :
103 : : <tr>
104 : : <td> buspower </td>
105 : : <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
106 : : <td> Read/Write</td>
107 : : </tr>
108 : :
109 : : <tr>
110 : : <td> bussuspend </td>
111 : : <td> Suspends the USB bus.</td>
112 : : <td> Read/Write</td>
113 : : </tr>
114 : :
115 : : <tr>
116 : : <td> busconnected </td>
117 : : <td> Gets the connection status of the bus</td>
118 : : <td> Read</td>
119 : : </tr>
120 : :
121 : : <tr>
122 : : <td> gotgctl </td>
123 : : <td> Gets or sets the Core Control Status Register.</td>
124 : : <td> Read/Write</td>
125 : : </tr>
126 : :
127 : : <tr>
128 : : <td> gusbcfg </td>
129 : : <td> Gets or sets the Core USB Configuration Register</td>
130 : : <td> Read/Write</td>
131 : : </tr>
132 : :
133 : : <tr>
134 : : <td> grxfsiz </td>
135 : : <td> Gets or sets the Receive FIFO Size Register</td>
136 : : <td> Read/Write</td>
137 : : </tr>
138 : :
139 : : <tr>
140 : : <td> gnptxfsiz </td>
141 : : <td> Gets or sets the non-periodic Transmit Size Register</td>
142 : : <td> Read/Write</td>
143 : : </tr>
144 : :
145 : : <tr>
146 : : <td> gpvndctl </td>
147 : : <td> Gets or sets the PHY Vendor Control Register</td>
148 : : <td> Read/Write</td>
149 : : </tr>
150 : :
151 : : <tr>
152 : : <td> ggpio </td>
153 : : <td> Gets the value in the lower 16-bits of the General Purpose IO Register
154 : : or sets the upper 16 bits.</td>
155 : : <td> Read/Write</td>
156 : : </tr>
157 : :
158 : : <tr>
159 : : <td> guid </td>
160 : : <td> Gets or sets the value of the User ID Register</td>
161 : : <td> Read/Write</td>
162 : : </tr>
163 : :
164 : : <tr>
165 : : <td> gsnpsid </td>
166 : : <td> Gets the value of the Synopsys ID Regester</td>
167 : : <td> Read</td>
168 : : </tr>
169 : :
170 : : <tr>
171 : : <td> devspeed </td>
172 : : <td> Gets or sets the device speed setting in the DCFG register</td>
173 : : <td> Read/Write</td>
174 : : </tr>
175 : :
176 : : <tr>
177 : : <td> enumspeed </td>
178 : : <td> Gets the device enumeration Speed.</td>
179 : : <td> Read</td>
180 : : </tr>
181 : :
182 : : <tr>
183 : : <td> hptxfsiz </td>
184 : : <td> Gets the value of the Host Periodic Transmit FIFO</td>
185 : : <td> Read</td>
186 : : </tr>
187 : :
188 : : <tr>
189 : : <td> hprt0 </td>
190 : : <td> Gets or sets the value in the Host Port Control and Status Register</td>
191 : : <td> Read/Write</td>
192 : : </tr>
193 : :
194 : : <tr>
195 : : <td> regoffset </td>
196 : : <td> Sets the register offset for the next Register Access</td>
197 : : <td> Read/Write</td>
198 : : </tr>
199 : :
200 : : <tr>
201 : : <td> regvalue </td>
202 : : <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
203 : : <td> Read/Write</td>
204 : : </tr>
205 : :
206 : : <tr>
207 : : <td> remote_wakeup </td>
208 : : <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
209 : : wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
210 : : Wakeup signalling bit in the Device Control Register is set for 1
211 : : milli-second.</td>
212 : : <td> Read/Write</td>
213 : : </tr>
214 : :
215 : : <tr>
216 : : <td> rem_wakeup_pwrdn </td>
217 : : <td> On read, shows the status core - hibernated or not. On write, initiates
218 : : a remote wakeup of the device from Hibernation. </td>
219 : : <td> Read/Write</td>
220 : : </tr>
221 : :
222 : : <tr>
223 : : <td> mode_ch_tim_en </td>
224 : : <td> This bit is used to enable or disable the host core to wait for 200 PHY
225 : : clock cycles at the end of Resume to change the opmode signal to the PHY to 00
226 : : after Suspend or LPM. </td>
227 : : <td> Read/Write</td>
228 : : </tr>
229 : :
230 : : <tr>
231 : : <td> fr_interval </td>
232 : : <td> On read, shows the value of HFIR Frame Interval. On write, dynamically
233 : : reload HFIR register during runtime. The application can write a value to this
234 : : register only after the Port Enable bit of the Host Port Control and Status
235 : : register (HPRT.PrtEnaPort) has been set </td>
236 : : <td> Read/Write</td>
237 : : </tr>
238 : :
239 : : <tr>
240 : : <td> disconnect_us </td>
241 : : <td> On read, shows the status of disconnect_device_us. On write, sets disconnect_us
242 : : which causes soft disconnect for 100us. Applicable only for device mode of operation.</td>
243 : : <td> Read/Write</td>
244 : : </tr>
245 : :
246 : : <tr>
247 : : <td> regdump </td>
248 : : <td> Dumps the contents of core registers.</td>
249 : : <td> Read</td>
250 : : </tr>
251 : :
252 : : <tr>
253 : : <td> spramdump </td>
254 : : <td> Dumps the contents of core registers.</td>
255 : : <td> Read</td>
256 : : </tr>
257 : :
258 : : <tr>
259 : : <td> hcddump </td>
260 : : <td> Dumps the current HCD state.</td>
261 : : <td> Read</td>
262 : : </tr>
263 : :
264 : : <tr>
265 : : <td> hcd_frrem </td>
266 : : <td> Shows the average value of the Frame Remaining
267 : : field in the Host Frame Number/Frame Remaining register when an SOF interrupt
268 : : occurs. This can be used to determine the average interrupt latency. Also
269 : : shows the average Frame Remaining value for start_transfer and the "a" and
270 : : "b" sample points. The "a" and "b" sample points may be used during debugging
271 : : bto determine how long it takes to execute a section of the HCD code.</td>
272 : : <td> Read</td>
273 : : </tr>
274 : :
275 : : <tr>
276 : : <td> rd_reg_test </td>
277 : : <td> Displays the time required to read the GNPTXFSIZ register many times
278 : : (the output shows the number of times the register is read).
279 : : <td> Read</td>
280 : : </tr>
281 : :
282 : : <tr>
283 : : <td> wr_reg_test </td>
284 : : <td> Displays the time required to write the GNPTXFSIZ register many times
285 : : (the output shows the number of times the register is written).
286 : : <td> Read</td>
287 : : </tr>
288 : :
289 : : <tr>
290 : : <td> lpm_response </td>
291 : : <td> Gets or sets lpm_response mode. Applicable only in device mode.
292 : : <td> Write</td>
293 : : </tr>
294 : :
295 : : <tr>
296 : : <td> sleep_status </td>
297 : : <td> Shows sleep status of device.
298 : : <td> Read</td>
299 : : </tr>
300 : :
301 : : </table>
302 : :
303 : : Example usage:
304 : : To get the current mode:
305 : : cat /sys/devices/lm0/mode
306 : :
307 : : To power down the USB:
308 : : echo 0 > /sys/devices/lm0/buspower
309 : : */
310 : :
311 : : #include "dwc_otg_os_dep.h"
312 : : #include "dwc_os.h"
313 : : #include "dwc_otg_driver.h"
314 : : #include "dwc_otg_attr.h"
315 : : #include "dwc_otg_core_if.h"
316 : : #include "dwc_otg_pcd_if.h"
317 : : #include "dwc_otg_hcd_if.h"
318 : :
319 : : /*
320 : : * MACROs for defining sysfs attribute
321 : : */
322 : : #ifdef LM_INTERFACE
323 : :
324 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
325 : : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
326 : : { \
327 : : struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
328 : : dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
329 : : uint32_t val; \
330 : : val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
331 : : return sprintf (buf, "%s = 0x%x\n", _string_, val); \
332 : : }
333 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
334 : : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
335 : : const char *buf, size_t count) \
336 : : { \
337 : : struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
338 : : dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
339 : : uint32_t set = simple_strtoul(buf, NULL, 16); \
340 : : dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
341 : : return count; \
342 : : }
343 : :
344 : : #elif defined(PCI_INTERFACE)
345 : :
346 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
347 : : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
348 : : { \
349 : : dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
350 : : uint32_t val; \
351 : : val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
352 : : return sprintf (buf, "%s = 0x%x\n", _string_, val); \
353 : : }
354 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
355 : : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
356 : : const char *buf, size_t count) \
357 : : { \
358 : : dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
359 : : uint32_t set = simple_strtoul(buf, NULL, 16); \
360 : : dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
361 : : return count; \
362 : : }
363 : :
364 : : #elif defined(PLATFORM_INTERFACE)
365 : :
366 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
367 : : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
368 : : { \
369 : : struct platform_device *platform_dev = \
370 : : container_of(_dev, struct platform_device, dev); \
371 : : dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
372 : : uint32_t val; \
373 : : DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
374 : : __func__, _dev, platform_dev, otg_dev); \
375 : : val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
376 : : return sprintf (buf, "%s = 0x%x\n", _string_, val); \
377 : : }
378 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
379 : : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
380 : : const char *buf, size_t count) \
381 : : { \
382 : : struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
383 : : dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
384 : : uint32_t set = simple_strtoul(buf, NULL, 16); \
385 : : dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
386 : : return count; \
387 : : }
388 : : #endif
389 : :
390 : : /*
391 : : * MACROs for defining sysfs attribute for 32-bit registers
392 : : */
393 : : #ifdef LM_INTERFACE
394 : : #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
395 : : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
396 : : { \
397 : : struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
398 : : dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
399 : : uint32_t val; \
400 : : val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
401 : : return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
402 : : }
403 : : #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
404 : : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
405 : : const char *buf, size_t count) \
406 : : { \
407 : : struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
408 : : dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
409 : : uint32_t val = simple_strtoul(buf, NULL, 16); \
410 : : dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
411 : : return count; \
412 : : }
413 : : #elif defined(PCI_INTERFACE)
414 : : #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
415 : : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
416 : : { \
417 : : dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
418 : : uint32_t val; \
419 : : val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
420 : : return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
421 : : }
422 : : #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
423 : : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
424 : : const char *buf, size_t count) \
425 : : { \
426 : : dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev); \
427 : : uint32_t val = simple_strtoul(buf, NULL, 16); \
428 : : dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
429 : : return count; \
430 : : }
431 : :
432 : : #elif defined(PLATFORM_INTERFACE)
433 : : #include "dwc_otg_dbg.h"
434 : : #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
435 : : static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
436 : : { \
437 : : struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
438 : : dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
439 : : uint32_t val; \
440 : : DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
441 : : __func__, _dev, platform_dev, otg_dev); \
442 : : val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
443 : : return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
444 : : }
445 : : #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
446 : : static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
447 : : const char *buf, size_t count) \
448 : : { \
449 : : struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
450 : : dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
451 : : uint32_t val = simple_strtoul(buf, NULL, 16); \
452 : : dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
453 : : return count; \
454 : : }
455 : :
456 : : #endif
457 : :
458 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_string_) \
459 : : DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
460 : : DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
461 : : DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
462 : :
463 : : #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_string_) \
464 : : DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
465 : : DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
466 : :
467 : : #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
468 : : DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
469 : : DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
470 : : DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
471 : :
472 : : #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
473 : : DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
474 : : DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
475 : :
476 : : /** @name Functions for Show/Store of Attributes */
477 : : /**@{*/
478 : :
479 : : /**
480 : : * Helper function returning the otg_device structure of the given device
481 : : */
482 : : static dwc_otg_device_t *dwc_otg_drvdev(struct device *_dev)
483 : : {
484 : : dwc_otg_device_t *otg_dev;
485 : : DWC_OTG_GETDRVDEV(otg_dev, _dev);
486 : : return otg_dev;
487 : : }
488 : :
489 : : /**
490 : : * Show the register offset of the Register Access.
491 : : */
492 : 0 : static ssize_t regoffset_show(struct device *_dev,
493 : : struct device_attribute *attr, char *buf)
494 : : {
495 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
496 : 0 : return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n",
497 : : otg_dev->os_dep.reg_offset);
498 : : }
499 : :
500 : : /**
501 : : * Set the register offset for the next Register Access Read/Write
502 : : */
503 : 0 : static ssize_t regoffset_store(struct device *_dev,
504 : : struct device_attribute *attr,
505 : : const char *buf, size_t count)
506 : : {
507 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
508 : 0 : uint32_t offset = simple_strtoul(buf, NULL, 16);
509 : : #if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE)
510 : 0 : if (offset < SZ_256K) {
511 : : #elif defined(PCI_INTERFACE)
512 : : if (offset < 0x00040000) {
513 : : #endif
514 : 0 : otg_dev->os_dep.reg_offset = offset;
515 : : } else {
516 : 0 : dev_err(_dev, "invalid offset\n");
517 : : }
518 : :
519 : 0 : return count;
520 : : }
521 : :
522 : : DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
523 : :
524 : : /**
525 : : * Show the value of the register at the offset in the reg_offset
526 : : * attribute.
527 : : */
528 : 0 : static ssize_t regvalue_show(struct device *_dev,
529 : : struct device_attribute *attr, char *buf)
530 : : {
531 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
532 : : uint32_t val;
533 : : volatile uint32_t *addr;
534 : :
535 : 0 : if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
536 : : /* Calculate the address */
537 : 0 : addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
538 : : (uint8_t *) otg_dev->os_dep.base);
539 : 0 : val = DWC_READ_REG32(addr);
540 : 0 : return snprintf(buf,
541 : : sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1,
542 : : "Reg@0x%06x = 0x%08x\n", otg_dev->os_dep.reg_offset,
543 : : val);
544 : : } else {
545 : 0 : dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->os_dep.reg_offset);
546 : 0 : return sprintf(buf, "invalid offset\n");
547 : : }
548 : : }
549 : :
550 : : /**
551 : : * Store the value in the register at the offset in the reg_offset
552 : : * attribute.
553 : : *
554 : : */
555 : 0 : static ssize_t regvalue_store(struct device *_dev,
556 : : struct device_attribute *attr,
557 : : const char *buf, size_t count)
558 : : {
559 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
560 : : volatile uint32_t *addr;
561 : 0 : uint32_t val = simple_strtoul(buf, NULL, 16);
562 : : //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
563 : 0 : if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
564 : : /* Calculate the address */
565 : 0 : addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
566 : : (uint8_t *) otg_dev->os_dep.base);
567 : 0 : DWC_WRITE_REG32(addr, val);
568 : : } else {
569 : 0 : dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
570 : : otg_dev->os_dep.reg_offset);
571 : : }
572 : 0 : return count;
573 : : }
574 : :
575 : : DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
576 : :
577 : : /*
578 : : * Attributes
579 : : */
580 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, "Mode");
581 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, "HNPCapable");
582 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, "SRPCapable");
583 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hsic_connect, "HSIC Connect");
584 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(inv_sel_hsic, "Invert Select HSIC");
585 : :
586 : : //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
587 : : //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
588 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, "Bus Connected");
589 : :
590 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, 0, "GOTGCTL");
591 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
592 : : &(otg_dev->core_if->core_global_regs->gusbcfg),
593 : : "GUSBCFG");
594 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
595 : : &(otg_dev->core_if->core_global_regs->grxfsiz),
596 : : "GRXFSIZ");
597 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
598 : : &(otg_dev->core_if->core_global_regs->gnptxfsiz),
599 : : "GNPTXFSIZ");
600 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
601 : : &(otg_dev->core_if->core_global_regs->gpvndctl),
602 : : "GPVNDCTL");
603 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
604 : : &(otg_dev->core_if->core_global_regs->ggpio),
605 : : "GGPIO");
606 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
607 : : "GUID");
608 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
609 : : &(otg_dev->core_if->core_global_regs->gsnpsid),
610 : : "GSNPSID");
611 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, "Device Speed");
612 : 0 : DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, "Device Enumeration Speed");
613 : :
614 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
615 : : &(otg_dev->core_if->core_global_regs->hptxfsiz),
616 : : "HPTXFSIZ");
617 : 0 : DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
618 : :
619 : : /**
620 : : * @todo Add code to initiate the HNP.
621 : : */
622 : : /**
623 : : * Show the HNP status bit
624 : : */
625 : 0 : static ssize_t hnp_show(struct device *_dev,
626 : : struct device_attribute *attr, char *buf)
627 : : {
628 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
629 : 0 : return sprintf(buf, "HstNegScs = 0x%x\n",
630 : : dwc_otg_get_hnpstatus(otg_dev->core_if));
631 : : }
632 : :
633 : : /**
634 : : * Set the HNP Request bit
635 : : */
636 : 0 : static ssize_t hnp_store(struct device *_dev,
637 : : struct device_attribute *attr,
638 : : const char *buf, size_t count)
639 : : {
640 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
641 : 0 : uint32_t in = simple_strtoul(buf, NULL, 16);
642 : 0 : dwc_otg_set_hnpreq(otg_dev->core_if, in);
643 : 0 : return count;
644 : : }
645 : :
646 : : DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
647 : :
648 : : /**
649 : : * @todo Add code to initiate the SRP.
650 : : */
651 : : /**
652 : : * Show the SRP status bit
653 : : */
654 : 0 : static ssize_t srp_show(struct device *_dev,
655 : : struct device_attribute *attr, char *buf)
656 : : {
657 : : #ifndef DWC_HOST_ONLY
658 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
659 : 0 : return sprintf(buf, "SesReqScs = 0x%x\n",
660 : : dwc_otg_get_srpstatus(otg_dev->core_if));
661 : : #else
662 : : return sprintf(buf, "Host Only Mode!\n");
663 : : #endif
664 : : }
665 : :
666 : : /**
667 : : * Set the SRP Request bit
668 : : */
669 : 0 : static ssize_t srp_store(struct device *_dev,
670 : : struct device_attribute *attr,
671 : : const char *buf, size_t count)
672 : : {
673 : : #ifndef DWC_HOST_ONLY
674 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
675 : 0 : dwc_otg_pcd_initiate_srp(otg_dev->pcd);
676 : : #endif
677 : 0 : return count;
678 : : }
679 : :
680 : : DEVICE_ATTR(srp, 0644, srp_show, srp_store);
681 : :
682 : : /**
683 : : * @todo Need to do more for power on/off?
684 : : */
685 : : /**
686 : : * Show the Bus Power status
687 : : */
688 : 0 : static ssize_t buspower_show(struct device *_dev,
689 : : struct device_attribute *attr, char *buf)
690 : : {
691 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
692 : 0 : return sprintf(buf, "Bus Power = 0x%x\n",
693 : : dwc_otg_get_prtpower(otg_dev->core_if));
694 : : }
695 : :
696 : : /**
697 : : * Set the Bus Power status
698 : : */
699 : 0 : static ssize_t buspower_store(struct device *_dev,
700 : : struct device_attribute *attr,
701 : : const char *buf, size_t count)
702 : : {
703 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
704 : 0 : uint32_t on = simple_strtoul(buf, NULL, 16);
705 : 0 : dwc_otg_set_prtpower(otg_dev->core_if, on);
706 : 0 : return count;
707 : : }
708 : :
709 : : DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
710 : :
711 : : /**
712 : : * @todo Need to do more for suspend?
713 : : */
714 : : /**
715 : : * Show the Bus Suspend status
716 : : */
717 : 0 : static ssize_t bussuspend_show(struct device *_dev,
718 : : struct device_attribute *attr, char *buf)
719 : : {
720 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
721 : 0 : return sprintf(buf, "Bus Suspend = 0x%x\n",
722 : : dwc_otg_get_prtsuspend(otg_dev->core_if));
723 : : }
724 : :
725 : : /**
726 : : * Set the Bus Suspend status
727 : : */
728 : 0 : static ssize_t bussuspend_store(struct device *_dev,
729 : : struct device_attribute *attr,
730 : : const char *buf, size_t count)
731 : : {
732 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
733 : 0 : uint32_t in = simple_strtoul(buf, NULL, 16);
734 : 0 : dwc_otg_set_prtsuspend(otg_dev->core_if, in);
735 : 0 : return count;
736 : : }
737 : :
738 : : DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
739 : :
740 : : /**
741 : : * Show the Mode Change Ready Timer status
742 : : */
743 : 0 : static ssize_t mode_ch_tim_en_show(struct device *_dev,
744 : : struct device_attribute *attr, char *buf)
745 : : {
746 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
747 : 0 : return sprintf(buf, "Mode Change Ready Timer Enable = 0x%x\n",
748 : : dwc_otg_get_mode_ch_tim(otg_dev->core_if));
749 : : }
750 : :
751 : : /**
752 : : * Set the Mode Change Ready Timer status
753 : : */
754 : 0 : static ssize_t mode_ch_tim_en_store(struct device *_dev,
755 : : struct device_attribute *attr,
756 : : const char *buf, size_t count)
757 : : {
758 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
759 : 0 : uint32_t in = simple_strtoul(buf, NULL, 16);
760 : 0 : dwc_otg_set_mode_ch_tim(otg_dev->core_if, in);
761 : 0 : return count;
762 : : }
763 : :
764 : : DEVICE_ATTR(mode_ch_tim_en, 0644, mode_ch_tim_en_show, mode_ch_tim_en_store);
765 : :
766 : : /**
767 : : * Show the value of HFIR Frame Interval bitfield
768 : : */
769 : 0 : static ssize_t fr_interval_show(struct device *_dev,
770 : : struct device_attribute *attr, char *buf)
771 : : {
772 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
773 : 0 : return sprintf(buf, "Frame Interval = 0x%x\n",
774 : : dwc_otg_get_fr_interval(otg_dev->core_if));
775 : : }
776 : :
777 : : /**
778 : : * Set the HFIR Frame Interval value
779 : : */
780 : 0 : static ssize_t fr_interval_store(struct device *_dev,
781 : : struct device_attribute *attr,
782 : : const char *buf, size_t count)
783 : : {
784 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
785 : 0 : uint32_t in = simple_strtoul(buf, NULL, 10);
786 : 0 : dwc_otg_set_fr_interval(otg_dev->core_if, in);
787 : 0 : return count;
788 : : }
789 : :
790 : : DEVICE_ATTR(fr_interval, 0644, fr_interval_show, fr_interval_store);
791 : :
792 : : /**
793 : : * Show the status of Remote Wakeup.
794 : : */
795 : 0 : static ssize_t remote_wakeup_show(struct device *_dev,
796 : : struct device_attribute *attr, char *buf)
797 : : {
798 : : #ifndef DWC_HOST_ONLY
799 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
800 : :
801 : 0 : return sprintf(buf,
802 : : "Remote Wakeup Sig = %d Enabled = %d LPM Remote Wakeup = %d\n",
803 : : dwc_otg_get_remotewakesig(otg_dev->core_if),
804 : 0 : dwc_otg_pcd_get_rmwkup_enable(otg_dev->pcd),
805 : : dwc_otg_get_lpm_remotewakeenabled(otg_dev->core_if));
806 : : #else
807 : : return sprintf(buf, "Host Only Mode!\n");
808 : : #endif /* DWC_HOST_ONLY */
809 : : }
810 : :
811 : : /**
812 : : * Initiate a remote wakeup of the host. The Device control register
813 : : * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
814 : : * flag is set.
815 : : *
816 : : */
817 : 0 : static ssize_t remote_wakeup_store(struct device *_dev,
818 : : struct device_attribute *attr,
819 : : const char *buf, size_t count)
820 : : {
821 : : #ifndef DWC_HOST_ONLY
822 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
823 : 0 : uint32_t val = simple_strtoul(buf, NULL, 16);
824 : :
825 : 0 : if (val & 1) {
826 : 0 : dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
827 : : } else {
828 : 0 : dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
829 : : }
830 : : #endif /* DWC_HOST_ONLY */
831 : 0 : return count;
832 : : }
833 : :
834 : : DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
835 : : remote_wakeup_store);
836 : :
837 : : /**
838 : : * Show the whether core is hibernated or not.
839 : : */
840 : 0 : static ssize_t rem_wakeup_pwrdn_show(struct device *_dev,
841 : : struct device_attribute *attr, char *buf)
842 : : {
843 : : #ifndef DWC_HOST_ONLY
844 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
845 : :
846 : 0 : if (dwc_otg_get_core_state(otg_dev->core_if)) {
847 : 0 : DWC_PRINTF("Core is in hibernation\n");
848 : : } else {
849 : 0 : DWC_PRINTF("Core is not in hibernation\n");
850 : : }
851 : : #endif /* DWC_HOST_ONLY */
852 : 0 : return 0;
853 : : }
854 : :
855 : : extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
856 : : int rem_wakeup, int reset);
857 : :
858 : : /**
859 : : * Initiate a remote wakeup of the device to exit from hibernation.
860 : : */
861 : 0 : static ssize_t rem_wakeup_pwrdn_store(struct device *_dev,
862 : : struct device_attribute *attr,
863 : : const char *buf, size_t count)
864 : : {
865 : : #ifndef DWC_HOST_ONLY
866 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
867 : 0 : dwc_otg_device_hibernation_restore(otg_dev->core_if, 1, 0);
868 : : #endif
869 : 0 : return count;
870 : : }
871 : :
872 : : DEVICE_ATTR(rem_wakeup_pwrdn, S_IRUGO | S_IWUSR, rem_wakeup_pwrdn_show,
873 : : rem_wakeup_pwrdn_store);
874 : :
875 : 0 : static ssize_t disconnect_us(struct device *_dev,
876 : : struct device_attribute *attr,
877 : : const char *buf, size_t count)
878 : : {
879 : :
880 : : #ifndef DWC_HOST_ONLY
881 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
882 : 0 : uint32_t val = simple_strtoul(buf, NULL, 16);
883 : 0 : DWC_PRINTF("The Passed value is %04x\n", val);
884 : :
885 : 0 : dwc_otg_pcd_disconnect_us(otg_dev->pcd, 50);
886 : :
887 : : #endif /* DWC_HOST_ONLY */
888 : 0 : return count;
889 : : }
890 : :
891 : : DEVICE_ATTR(disconnect_us, S_IWUSR, 0, disconnect_us);
892 : :
893 : : /**
894 : : * Dump global registers and either host or device registers (depending on the
895 : : * current mode of the core).
896 : : */
897 : 0 : static ssize_t regdump_show(struct device *_dev,
898 : : struct device_attribute *attr, char *buf)
899 : : {
900 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
901 : :
902 : 0 : dwc_otg_dump_global_registers(otg_dev->core_if);
903 : 0 : if (dwc_otg_is_host_mode(otg_dev->core_if)) {
904 : 0 : dwc_otg_dump_host_registers(otg_dev->core_if);
905 : : } else {
906 : 0 : dwc_otg_dump_dev_registers(otg_dev->core_if);
907 : :
908 : : }
909 : 0 : return sprintf(buf, "Register Dump\n");
910 : : }
911 : :
912 : : DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
913 : :
914 : : /**
915 : : * Dump global registers and either host or device registers (depending on the
916 : : * current mode of the core).
917 : : */
918 : 0 : static ssize_t spramdump_show(struct device *_dev,
919 : : struct device_attribute *attr, char *buf)
920 : : {
921 : : #if 0
922 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
923 : :
924 : : dwc_otg_dump_spram(otg_dev->core_if);
925 : : #endif
926 : :
927 : 0 : return sprintf(buf, "SPRAM Dump\n");
928 : : }
929 : :
930 : : DEVICE_ATTR(spramdump, S_IRUGO, spramdump_show, 0);
931 : :
932 : : /**
933 : : * Dump the current hcd state.
934 : : */
935 : 0 : static ssize_t hcddump_show(struct device *_dev,
936 : : struct device_attribute *attr, char *buf)
937 : : {
938 : : #ifndef DWC_DEVICE_ONLY
939 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
940 : 0 : dwc_otg_hcd_dump_state(otg_dev->hcd);
941 : : #endif /* DWC_DEVICE_ONLY */
942 : 0 : return sprintf(buf, "HCD Dump\n");
943 : : }
944 : :
945 : : DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
946 : :
947 : : /**
948 : : * Dump the average frame remaining at SOF. This can be used to
949 : : * determine average interrupt latency. Frame remaining is also shown for
950 : : * start transfer and two additional sample points.
951 : : */
952 : 0 : static ssize_t hcd_frrem_show(struct device *_dev,
953 : : struct device_attribute *attr, char *buf)
954 : : {
955 : : #ifndef DWC_DEVICE_ONLY
956 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
957 : :
958 : 0 : dwc_otg_hcd_dump_frrem(otg_dev->hcd);
959 : : #endif /* DWC_DEVICE_ONLY */
960 : 0 : return sprintf(buf, "HCD Dump Frame Remaining\n");
961 : : }
962 : :
963 : : DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
964 : :
965 : : /**
966 : : * Displays the time required to read the GNPTXFSIZ register many times (the
967 : : * output shows the number of times the register is read).
968 : : */
969 : : #define RW_REG_COUNT 10000000
970 : : #define MSEC_PER_JIFFIE 1000/HZ
971 : 0 : static ssize_t rd_reg_test_show(struct device *_dev,
972 : : struct device_attribute *attr, char *buf)
973 : : {
974 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
975 : : int i;
976 : : int time;
977 : : int start_jiffies;
978 : :
979 : 0 : printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
980 : : HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
981 : 0 : start_jiffies = jiffies;
982 : 0 : for (i = 0; i < RW_REG_COUNT; i++) {
983 : 0 : dwc_otg_get_gnptxfsiz(otg_dev->core_if);
984 : : }
985 : 0 : time = jiffies - start_jiffies;
986 : 0 : return sprintf(buf,
987 : : "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
988 : 0 : RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
989 : : }
990 : :
991 : : DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
992 : :
993 : : /**
994 : : * Displays the time required to write the GNPTXFSIZ register many times (the
995 : : * output shows the number of times the register is written).
996 : : */
997 : 0 : static ssize_t wr_reg_test_show(struct device *_dev,
998 : : struct device_attribute *attr, char *buf)
999 : : {
1000 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1001 : : uint32_t reg_val;
1002 : : int i;
1003 : : int time;
1004 : : int start_jiffies;
1005 : :
1006 : 0 : printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
1007 : : HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
1008 : 0 : reg_val = dwc_otg_get_gnptxfsiz(otg_dev->core_if);
1009 : 0 : start_jiffies = jiffies;
1010 : 0 : for (i = 0; i < RW_REG_COUNT; i++) {
1011 : 0 : dwc_otg_set_gnptxfsiz(otg_dev->core_if, reg_val);
1012 : : }
1013 : 0 : time = jiffies - start_jiffies;
1014 : 0 : return sprintf(buf,
1015 : : "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
1016 : 0 : RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
1017 : : }
1018 : :
1019 : : DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
1020 : :
1021 : : #ifdef CONFIG_USB_DWC_OTG_LPM
1022 : :
1023 : : /**
1024 : : * Show the lpm_response attribute.
1025 : : */
1026 : : static ssize_t lpmresp_show(struct device *_dev,
1027 : : struct device_attribute *attr, char *buf)
1028 : : {
1029 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1030 : :
1031 : : if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
1032 : : return sprintf(buf, "** LPM is DISABLED **\n");
1033 : :
1034 : : if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
1035 : : return sprintf(buf, "** Current mode is not device mode\n");
1036 : : }
1037 : : return sprintf(buf, "lpm_response = %d\n",
1038 : : dwc_otg_get_lpmresponse(otg_dev->core_if));
1039 : : }
1040 : :
1041 : : /**
1042 : : * Store the lpm_response attribute.
1043 : : */
1044 : : static ssize_t lpmresp_store(struct device *_dev,
1045 : : struct device_attribute *attr,
1046 : : const char *buf, size_t count)
1047 : : {
1048 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1049 : : uint32_t val = simple_strtoul(buf, NULL, 16);
1050 : :
1051 : : if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if)) {
1052 : : return 0;
1053 : : }
1054 : :
1055 : : if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
1056 : : return 0;
1057 : : }
1058 : :
1059 : : dwc_otg_set_lpmresponse(otg_dev->core_if, val);
1060 : : return count;
1061 : : }
1062 : :
1063 : : DEVICE_ATTR(lpm_response, S_IRUGO | S_IWUSR, lpmresp_show, lpmresp_store);
1064 : :
1065 : : /**
1066 : : * Show the sleep_status attribute.
1067 : : */
1068 : : static ssize_t sleepstatus_show(struct device *_dev,
1069 : : struct device_attribute *attr, char *buf)
1070 : : {
1071 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1072 : : return sprintf(buf, "Sleep Status = %d\n",
1073 : : dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if));
1074 : : }
1075 : :
1076 : : /**
1077 : : * Store the sleep_status attribure.
1078 : : */
1079 : : static ssize_t sleepstatus_store(struct device *_dev,
1080 : : struct device_attribute *attr,
1081 : : const char *buf, size_t count)
1082 : : {
1083 : : dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
1084 : : dwc_otg_core_if_t *core_if = otg_dev->core_if;
1085 : :
1086 : : if (dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)) {
1087 : : if (dwc_otg_is_host_mode(core_if)) {
1088 : :
1089 : : DWC_PRINTF("Host initiated resume\n");
1090 : : dwc_otg_set_prtresume(otg_dev->core_if, 1);
1091 : : }
1092 : : }
1093 : :
1094 : : return count;
1095 : : }
1096 : :
1097 : : DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show,
1098 : : sleepstatus_store);
1099 : :
1100 : : #endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */
1101 : :
1102 : : /**@}*/
1103 : :
1104 : : /**
1105 : : * Create the device files
1106 : : */
1107 : 3 : void dwc_otg_attr_create(
1108 : : #ifdef LM_INTERFACE
1109 : : struct lm_device *dev
1110 : : #elif defined(PCI_INTERFACE)
1111 : : struct pci_dev *dev
1112 : : #elif defined(PLATFORM_INTERFACE)
1113 : : struct platform_device *dev
1114 : : #endif
1115 : : )
1116 : : {
1117 : : int error;
1118 : :
1119 : 3 : error = device_create_file(&dev->dev, &dev_attr_regoffset);
1120 : 3 : error = device_create_file(&dev->dev, &dev_attr_regvalue);
1121 : 3 : error = device_create_file(&dev->dev, &dev_attr_mode);
1122 : 3 : error = device_create_file(&dev->dev, &dev_attr_hnpcapable);
1123 : 3 : error = device_create_file(&dev->dev, &dev_attr_srpcapable);
1124 : 3 : error = device_create_file(&dev->dev, &dev_attr_hsic_connect);
1125 : 3 : error = device_create_file(&dev->dev, &dev_attr_inv_sel_hsic);
1126 : 3 : error = device_create_file(&dev->dev, &dev_attr_hnp);
1127 : 3 : error = device_create_file(&dev->dev, &dev_attr_srp);
1128 : 3 : error = device_create_file(&dev->dev, &dev_attr_buspower);
1129 : 3 : error = device_create_file(&dev->dev, &dev_attr_bussuspend);
1130 : 3 : error = device_create_file(&dev->dev, &dev_attr_mode_ch_tim_en);
1131 : 3 : error = device_create_file(&dev->dev, &dev_attr_fr_interval);
1132 : 3 : error = device_create_file(&dev->dev, &dev_attr_busconnected);
1133 : 3 : error = device_create_file(&dev->dev, &dev_attr_gotgctl);
1134 : 3 : error = device_create_file(&dev->dev, &dev_attr_gusbcfg);
1135 : 3 : error = device_create_file(&dev->dev, &dev_attr_grxfsiz);
1136 : 3 : error = device_create_file(&dev->dev, &dev_attr_gnptxfsiz);
1137 : 3 : error = device_create_file(&dev->dev, &dev_attr_gpvndctl);
1138 : 3 : error = device_create_file(&dev->dev, &dev_attr_ggpio);
1139 : 3 : error = device_create_file(&dev->dev, &dev_attr_guid);
1140 : 3 : error = device_create_file(&dev->dev, &dev_attr_gsnpsid);
1141 : 3 : error = device_create_file(&dev->dev, &dev_attr_devspeed);
1142 : 3 : error = device_create_file(&dev->dev, &dev_attr_enumspeed);
1143 : 3 : error = device_create_file(&dev->dev, &dev_attr_hptxfsiz);
1144 : 3 : error = device_create_file(&dev->dev, &dev_attr_hprt0);
1145 : 3 : error = device_create_file(&dev->dev, &dev_attr_remote_wakeup);
1146 : 3 : error = device_create_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
1147 : 3 : error = device_create_file(&dev->dev, &dev_attr_disconnect_us);
1148 : 3 : error = device_create_file(&dev->dev, &dev_attr_regdump);
1149 : 3 : error = device_create_file(&dev->dev, &dev_attr_spramdump);
1150 : 3 : error = device_create_file(&dev->dev, &dev_attr_hcddump);
1151 : 3 : error = device_create_file(&dev->dev, &dev_attr_hcd_frrem);
1152 : 3 : error = device_create_file(&dev->dev, &dev_attr_rd_reg_test);
1153 : 3 : error = device_create_file(&dev->dev, &dev_attr_wr_reg_test);
1154 : : #ifdef CONFIG_USB_DWC_OTG_LPM
1155 : : error = device_create_file(&dev->dev, &dev_attr_lpm_response);
1156 : : error = device_create_file(&dev->dev, &dev_attr_sleep_status);
1157 : : #endif
1158 : 3 : }
1159 : :
1160 : : /**
1161 : : * Remove the device files
1162 : : */
1163 : 0 : void dwc_otg_attr_remove(
1164 : : #ifdef LM_INTERFACE
1165 : : struct lm_device *dev
1166 : : #elif defined(PCI_INTERFACE)
1167 : : struct pci_dev *dev
1168 : : #elif defined(PLATFORM_INTERFACE)
1169 : : struct platform_device *dev
1170 : : #endif
1171 : : )
1172 : : {
1173 : 0 : device_remove_file(&dev->dev, &dev_attr_regoffset);
1174 : 0 : device_remove_file(&dev->dev, &dev_attr_regvalue);
1175 : 0 : device_remove_file(&dev->dev, &dev_attr_mode);
1176 : 0 : device_remove_file(&dev->dev, &dev_attr_hnpcapable);
1177 : 0 : device_remove_file(&dev->dev, &dev_attr_srpcapable);
1178 : 0 : device_remove_file(&dev->dev, &dev_attr_hsic_connect);
1179 : 0 : device_remove_file(&dev->dev, &dev_attr_inv_sel_hsic);
1180 : 0 : device_remove_file(&dev->dev, &dev_attr_hnp);
1181 : 0 : device_remove_file(&dev->dev, &dev_attr_srp);
1182 : 0 : device_remove_file(&dev->dev, &dev_attr_buspower);
1183 : 0 : device_remove_file(&dev->dev, &dev_attr_bussuspend);
1184 : 0 : device_remove_file(&dev->dev, &dev_attr_mode_ch_tim_en);
1185 : 0 : device_remove_file(&dev->dev, &dev_attr_fr_interval);
1186 : 0 : device_remove_file(&dev->dev, &dev_attr_busconnected);
1187 : 0 : device_remove_file(&dev->dev, &dev_attr_gotgctl);
1188 : 0 : device_remove_file(&dev->dev, &dev_attr_gusbcfg);
1189 : 0 : device_remove_file(&dev->dev, &dev_attr_grxfsiz);
1190 : 0 : device_remove_file(&dev->dev, &dev_attr_gnptxfsiz);
1191 : 0 : device_remove_file(&dev->dev, &dev_attr_gpvndctl);
1192 : 0 : device_remove_file(&dev->dev, &dev_attr_ggpio);
1193 : 0 : device_remove_file(&dev->dev, &dev_attr_guid);
1194 : 0 : device_remove_file(&dev->dev, &dev_attr_gsnpsid);
1195 : 0 : device_remove_file(&dev->dev, &dev_attr_devspeed);
1196 : 0 : device_remove_file(&dev->dev, &dev_attr_enumspeed);
1197 : 0 : device_remove_file(&dev->dev, &dev_attr_hptxfsiz);
1198 : 0 : device_remove_file(&dev->dev, &dev_attr_hprt0);
1199 : 0 : device_remove_file(&dev->dev, &dev_attr_remote_wakeup);
1200 : 0 : device_remove_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
1201 : 0 : device_remove_file(&dev->dev, &dev_attr_disconnect_us);
1202 : 0 : device_remove_file(&dev->dev, &dev_attr_regdump);
1203 : 0 : device_remove_file(&dev->dev, &dev_attr_spramdump);
1204 : 0 : device_remove_file(&dev->dev, &dev_attr_hcddump);
1205 : 0 : device_remove_file(&dev->dev, &dev_attr_hcd_frrem);
1206 : 0 : device_remove_file(&dev->dev, &dev_attr_rd_reg_test);
1207 : 0 : device_remove_file(&dev->dev, &dev_attr_wr_reg_test);
1208 : : #ifdef CONFIG_USB_DWC_OTG_LPM
1209 : : device_remove_file(&dev->dev, &dev_attr_lpm_response);
1210 : : device_remove_file(&dev->dev, &dev_attr_sleep_status);
1211 : : #endif
1212 : 0 : }
|