343acd2517440cec4c859660a6e084a61e77f205
[openwrt/staging/yousong.git] / target / linux / cns3xxx / files / drivers / usb / dwc / otg_attr.c
1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
3 * $Revision: #31 $
4 * $Date: 2008/07/15 $
5 * $Change: 1064918 $
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
50 The following table shows the attributes.
51 <table>
52 <tr>
53 <td><b> Name</b></td>
54 <td><b> Description</b></td>
55 <td><b> Access</b></td>
56 </tr>
57
58 <tr>
59 <td> mode </td>
60 <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
61 <td> Read</td>
62 </tr>
63
64 <tr>
65 <td> hnpcapable </td>
66 <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
67 Read returns the current value.</td>
68 <td> Read/Write</td>
69 </tr>
70
71 <tr>
72 <td> srpcapable </td>
73 <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
74 Read returns the current value.</td>
75 <td> Read/Write</td>
76 </tr>
77
78 <tr>
79 <td> hnp </td>
80 <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
81 <td> Read/Write</td>
82 </tr>
83
84 <tr>
85 <td> srp </td>
86 <td> Initiates the Session Request Protocol. Read returns the status.</td>
87 <td> Read/Write</td>
88 </tr>
89
90 <tr>
91 <td> buspower </td>
92 <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
93 <td> Read/Write</td>
94 </tr>
95
96 <tr>
97 <td> bussuspend </td>
98 <td> Suspends the USB bus.</td>
99 <td> Read/Write</td>
100 </tr>
101
102 <tr>
103 <td> busconnected </td>
104 <td> Gets the connection status of the bus</td>
105 <td> Read</td>
106 </tr>
107
108 <tr>
109 <td> gotgctl </td>
110 <td> Gets or sets the Core Control Status Register.</td>
111 <td> Read/Write</td>
112 </tr>
113
114 <tr>
115 <td> gusbcfg </td>
116 <td> Gets or sets the Core USB Configuration Register</td>
117 <td> Read/Write</td>
118 </tr>
119
120 <tr>
121 <td> grxfsiz </td>
122 <td> Gets or sets the Receive FIFO Size Register</td>
123 <td> Read/Write</td>
124 </tr>
125
126 <tr>
127 <td> gnptxfsiz </td>
128 <td> Gets or sets the non-periodic Transmit Size Register</td>
129 <td> Read/Write</td>
130 </tr>
131
132 <tr>
133 <td> gpvndctl </td>
134 <td> Gets or sets the PHY Vendor Control Register</td>
135 <td> Read/Write</td>
136 </tr>
137
138 <tr>
139 <td> ggpio </td>
140 <td> Gets the value in the lower 16-bits of the General Purpose IO Register
141 or sets the upper 16 bits.</td>
142 <td> Read/Write</td>
143 </tr>
144
145 <tr>
146 <td> guid </td>
147 <td> Gets or sets the value of the User ID Register</td>
148 <td> Read/Write</td>
149 </tr>
150
151 <tr>
152 <td> gsnpsid </td>
153 <td> Gets the value of the Synopsys ID Regester</td>
154 <td> Read</td>
155 </tr>
156
157 <tr>
158 <td> devspeed </td>
159 <td> Gets or sets the device speed setting in the DCFG register</td>
160 <td> Read/Write</td>
161 </tr>
162
163 <tr>
164 <td> enumspeed </td>
165 <td> Gets the device enumeration Speed.</td>
166 <td> Read</td>
167 </tr>
168
169 <tr>
170 <td> hptxfsiz </td>
171 <td> Gets the value of the Host Periodic Transmit FIFO</td>
172 <td> Read</td>
173 </tr>
174
175 <tr>
176 <td> hprt0 </td>
177 <td> Gets or sets the value in the Host Port Control and Status Register</td>
178 <td> Read/Write</td>
179 </tr>
180
181 <tr>
182 <td> regoffset </td>
183 <td> Sets the register offset for the next Register Access</td>
184 <td> Read/Write</td>
185 </tr>
186
187 <tr>
188 <td> regvalue </td>
189 <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
190 <td> Read/Write</td>
191 </tr>
192
193 <tr>
194 <td> remote_wakeup </td>
195 <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
196 wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
197 Wakeup signalling bit in the Device Control Register is set for 1
198 milli-second.</td>
199 <td> Read/Write</td>
200 </tr>
201
202 <tr>
203 <td> regdump </td>
204 <td> Dumps the contents of core registers.</td>
205 <td> Read</td>
206 </tr>
207
208 <tr>
209 <td> spramdump </td>
210 <td> Dumps the contents of core registers.</td>
211 <td> Read</td>
212 </tr>
213
214 <tr>
215 <td> hcddump </td>
216 <td> Dumps the current HCD state.</td>
217 <td> Read</td>
218 </tr>
219
220 <tr>
221 <td> hcd_frrem </td>
222 <td> Shows the average value of the Frame Remaining
223 field in the Host Frame Number/Frame Remaining register when an SOF interrupt
224 occurs. This can be used to determine the average interrupt latency. Also
225 shows the average Frame Remaining value for start_transfer and the "a" and
226 "b" sample points. The "a" and "b" sample points may be used during debugging
227 bto determine how long it takes to execute a section of the HCD code.</td>
228 <td> Read</td>
229 </tr>
230
231 <tr>
232 <td> rd_reg_test </td>
233 <td> Displays the time required to read the GNPTXFSIZ register many times
234 (the output shows the number of times the register is read).
235 <td> Read</td>
236 </tr>
237
238 <tr>
239 <td> wr_reg_test </td>
240 <td> Displays the time required to write the GNPTXFSIZ register many times
241 (the output shows the number of times the register is written).
242 <td> Read</td>
243 </tr>
244
245 </table>
246
247 Example usage:
248 To get the current mode:
249 cat /sys/devices/lm0/mode
250
251 To power down the USB:
252 echo 0 > /sys/devices/lm0/buspower
253 */
254
255 #include <linux/kernel.h>
256 #include <linux/module.h>
257 #include <linux/moduleparam.h>
258 #include <linux/init.h>
259 #include <linux/device.h>
260 #include <linux/platform_device.h>
261 #include <linux/errno.h>
262 #include <linux/types.h>
263 #include <linux/stat.h> /* permission constants */
264 #include <linux/version.h>
265
266 #include <asm/sizes.h>
267 #include <asm/io.h>
268 #include <asm/sizes.h>
269
270 #include "otg_plat.h"
271 #include "otg_attr.h"
272 #include "otg_driver.h"
273 #include "otg_pcd.h"
274 #include "otg_hcd.h"
275
276 /*
277 * MACROs for defining sysfs attribute
278 */
279 #define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
280 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
281 { \
282 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
283 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
284 uint32_t val; \
285 val = dwc_read_reg32 (_addr_); \
286 val = (val & (_mask_)) >> _shift_; \
287 return sprintf (buf, "%s = 0x%x\n", _string_, val); \
288 }
289 #define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
290 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
291 const char *buf, size_t count) \
292 { \
293 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
294 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
295 uint32_t set = simple_strtoul(buf, NULL, 16); \
296 uint32_t clear = set; \
297 clear = ((~clear) << _shift_) & _mask_; \
298 set = (set << _shift_) & _mask_; \
299 dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
300 dwc_modify_reg32(_addr_, clear, set); \
301 return count; \
302 }
303
304 /*
305 * MACROs for defining sysfs attribute for 32-bit registers
306 */
307 #define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
308 static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
309 { \
310 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
311 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
312 uint32_t val; \
313 val = dwc_read_reg32 (_addr_); \
314 return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
315 }
316 #define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
317 static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
318 const char *buf, size_t count) \
319 { \
320 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
321 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
322 uint32_t val = simple_strtoul(buf, NULL, 16); \
323 dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
324 dwc_write_reg32(_addr_, val); \
325 return count; \
326 }
327
328 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
329 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
330 DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
331 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
332
333 #define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
334 DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
335 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
336
337 #define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
338 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
339 DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
340 DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
341
342 #define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
343 DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
344 DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
345
346
347 /** @name Functions for Show/Store of Attributes */
348 /**@{*/
349
350 /**
351 * Show the register offset of the Register Access.
352 */
353 static ssize_t regoffset_show( struct device *_dev,
354 struct device_attribute *attr,
355 char *buf)
356 {
357 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
358 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
359 return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
360 }
361
362 /**
363 * Set the register offset for the next Register Access Read/Write
364 */
365 static ssize_t regoffset_store( struct device *_dev,
366 struct device_attribute *attr,
367 const char *buf,
368 size_t count )
369 {
370 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
371 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
372 uint32_t offset = simple_strtoul(buf, NULL, 16);
373 //dev_dbg(_dev, "Offset=0x%08x\n", offset);
374 if (offset < SZ_256K ) {
375 otg_dev->reg_offset = offset;
376 }
377 else {
378 dev_err( _dev, "invalid offset\n" );
379 }
380
381 return count;
382 }
383 DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, (void *)regoffset_show, regoffset_store);
384
385
386 /**
387 * Show the value of the register at the offset in the reg_offset
388 * attribute.
389 */
390 static ssize_t regvalue_show( struct device *_dev,
391 struct device_attribute *attr,
392 char *buf)
393 {
394 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
395 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
396 uint32_t val;
397 volatile uint32_t *addr;
398
399 if (otg_dev->reg_offset != 0xFFFFFFFF &&
400 0 != otg_dev->base) {
401 /* Calculate the address */
402 addr = (uint32_t*)(otg_dev->reg_offset +
403 (uint8_t*)otg_dev->base);
404 //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
405 val = dwc_read_reg32( addr );
406 return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
407 "Reg@0x%06x = 0x%08x\n",
408 otg_dev->reg_offset, val);
409 }
410 else {
411 dev_err(_dev, "Invalid offset (0x%0x)\n",
412 otg_dev->reg_offset);
413 return sprintf(buf, "invalid offset\n" );
414 }
415 }
416
417 /**
418 * Store the value in the register at the offset in the reg_offset
419 * attribute.
420 *
421 */
422 static ssize_t regvalue_store( struct device *_dev,
423 struct device_attribute *attr,
424 const char *buf,
425 size_t count )
426 {
427 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
428 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
429 volatile uint32_t * addr;
430 uint32_t val = simple_strtoul(buf, NULL, 16);
431 //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
432 if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
433 /* Calculate the address */
434 addr = (uint32_t*)(otg_dev->reg_offset +
435 (uint8_t*)otg_dev->base);
436 //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
437 dwc_write_reg32( addr, val );
438 }
439 else {
440 dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
441 otg_dev->reg_offset);
442 }
443 return count;
444 }
445 DEVICE_ATTR(regvalue, S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
446
447 /*
448 * Attributes
449 */
450 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
451 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
452 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
453
454 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
455 //DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
456 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
457
458 DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
459 DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
460 DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
461 DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
462 DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
463 DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
464 DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
465 DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
466 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
467 DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
468
469 DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
470 DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
471
472
473 /**
474 * @todo Add code to initiate the HNP.
475 */
476 /**
477 * Show the HNP status bit
478 */
479 static ssize_t hnp_show( struct device *_dev,
480 struct device_attribute *attr,
481 char *buf)
482 {
483 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
484 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
485 gotgctl_data_t val;
486 val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
487 return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
488 }
489
490 /**
491 * Set the HNP Request bit
492 */
493 static ssize_t hnp_store( struct device *_dev,
494 struct device_attribute *attr,
495 const char *buf,
496 size_t count )
497 {
498 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
499 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
500 uint32_t in = simple_strtoul(buf, NULL, 16);
501 uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
502 gotgctl_data_t mem;
503 mem.d32 = dwc_read_reg32(addr);
504 mem.b.hnpreq = in;
505 dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
506 dwc_write_reg32(addr, mem.d32);
507 return count;
508 }
509 DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
510
511 /**
512 * @todo Add code to initiate the SRP.
513 */
514 /**
515 * Show the SRP status bit
516 */
517 static ssize_t srp_show( struct device *_dev,
518 struct device_attribute *attr,
519 char *buf)
520 {
521 #ifndef DWC_HOST_ONLY
522 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
523 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
524 gotgctl_data_t val;
525 val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
526 return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
527 #else
528 return sprintf(buf, "Host Only Mode!\n");
529 #endif
530 }
531
532
533
534 /**
535 * Set the SRP Request bit
536 */
537 static ssize_t srp_store( struct device *_dev,
538 struct device_attribute *attr,
539 const char *buf,
540 size_t count )
541 {
542 #ifndef DWC_HOST_ONLY
543 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
544 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
545 dwc_otg_pcd_initiate_srp(otg_dev->pcd);
546 #endif
547 return count;
548 }
549 DEVICE_ATTR(srp, 0644, srp_show, srp_store);
550
551 /**
552 * @todo Need to do more for power on/off?
553 */
554 /**
555 * Show the Bus Power status
556 */
557 static ssize_t buspower_show( struct device *_dev,
558 struct device_attribute *attr,
559 char *buf)
560 {
561 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
562 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
563 hprt0_data_t val;
564 val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
565 return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
566 }
567
568
569 /**
570 * Set the Bus Power status
571 */
572 static ssize_t buspower_store( struct device *_dev,
573 struct device_attribute *attr,
574 const char *buf,
575 size_t count )
576 {
577 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
578 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
579 uint32_t on = simple_strtoul(buf, NULL, 16);
580 uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
581 hprt0_data_t mem;
582
583 mem.d32 = dwc_read_reg32(addr);
584 mem.b.prtpwr = on;
585
586 //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
587 dwc_write_reg32(addr, mem.d32);
588
589 return count;
590 }
591 DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
592
593 /**
594 * @todo Need to do more for suspend?
595 */
596 /**
597 * Show the Bus Suspend status
598 */
599 static ssize_t bussuspend_show( struct device *_dev,
600 struct device_attribute *attr,
601 char *buf)
602 {
603 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
604 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
605 hprt0_data_t val;
606 val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
607 return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
608 }
609
610 /**
611 * Set the Bus Suspend status
612 */
613 static ssize_t bussuspend_store( struct device *_dev,
614 struct device_attribute *attr,
615 const char *buf,
616 size_t count )
617 {
618 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
619 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
620 uint32_t in = simple_strtoul(buf, NULL, 16);
621 uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
622 hprt0_data_t mem;
623 mem.d32 = dwc_read_reg32(addr);
624 mem.b.prtsusp = in;
625 dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
626 dwc_write_reg32(addr, mem.d32);
627 return count;
628 }
629 DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
630
631 /**
632 * Show the status of Remote Wakeup.
633 */
634 static ssize_t remote_wakeup_show( struct device *_dev,
635 struct device_attribute *attr,
636 char *buf)
637 {
638 #ifndef DWC_HOST_ONLY
639 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
640 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
641 dctl_data_t val;
642 val.d32 =
643 dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
644 return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n",
645 val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
646 #else
647 return sprintf(buf, "Host Only Mode!\n");
648 #endif
649 }
650 /**
651 * Initiate a remote wakeup of the host. The Device control register
652 * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
653 * flag is set.
654 *
655 */
656 static ssize_t remote_wakeup_store( struct device *_dev,
657 struct device_attribute *attr,
658 const char *buf,
659 size_t count )
660 {
661 #ifndef DWC_HOST_ONLY
662 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
663 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
664 uint32_t val = simple_strtoul(buf, NULL, 16);
665 if (val&1) {
666 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
667 }
668 else {
669 dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
670 }
671 #endif
672 return count;
673 }
674 DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
675 remote_wakeup_store);
676
677 /**
678 * Dump global registers and either host or device registers (depending on the
679 * current mode of the core).
680 */
681 static ssize_t regdump_show( struct device *_dev,
682 struct device_attribute *attr,
683 char *buf)
684 {
685 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
686 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
687 dwc_otg_dump_global_registers( otg_dev->core_if);
688 if (dwc_otg_is_host_mode(otg_dev->core_if)) {
689 dwc_otg_dump_host_registers( otg_dev->core_if);
690 } else {
691 dwc_otg_dump_dev_registers( otg_dev->core_if);
692
693 }
694 return sprintf( buf, "Register Dump\n" );
695 }
696
697 DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
698
699 /**
700 * Dump global registers and either host or device registers (depending on the
701 * current mode of the core).
702 */
703 static ssize_t spramdump_show( struct device *_dev,
704 struct device_attribute *attr,
705 char *buf)
706 {
707 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
708 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
709 dwc_otg_dump_spram( otg_dev->core_if);
710
711 return sprintf( buf, "SPRAM Dump\n" );
712 }
713
714 DEVICE_ATTR(spramdump, S_IRUGO|S_IWUSR, spramdump_show, 0);
715
716 /**
717 * Dump the current hcd state.
718 */
719 static ssize_t hcddump_show( struct device *_dev,
720 struct device_attribute *attr,
721 char *buf)
722 {
723 #ifndef DWC_DEVICE_ONLY
724 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
725 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
726 dwc_otg_hcd_dump_state(otg_dev->hcd);
727 #endif
728 return sprintf( buf, "HCD Dump\n" );
729 }
730
731 DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
732
733 /**
734 * Dump the average frame remaining at SOF. This can be used to
735 * determine average interrupt latency. Frame remaining is also shown for
736 * start transfer and two additional sample points.
737 */
738 static ssize_t hcd_frrem_show( struct device *_dev,
739 struct device_attribute *attr,
740 char *buf)
741 {
742 #ifndef DWC_DEVICE_ONLY
743 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
744 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
745 dwc_otg_hcd_dump_frrem(otg_dev->hcd);
746 #endif
747 return sprintf( buf, "HCD Dump Frame Remaining\n" );
748 }
749
750 DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
751
752 /**
753 * Displays the time required to read the GNPTXFSIZ register many times (the
754 * output shows the number of times the register is read).
755 */
756 #define RW_REG_COUNT 10000000
757 #define MSEC_PER_JIFFIE 1000/HZ
758 static ssize_t rd_reg_test_show( struct device *_dev,
759 struct device_attribute *attr,
760 char *buf)
761 {
762 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
763 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
764 int i;
765 int time;
766 int start_jiffies;
767
768 printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
769 HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
770 start_jiffies = jiffies;
771 for (i = 0; i < RW_REG_COUNT; i++) {
772 dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
773 }
774 time = jiffies - start_jiffies;
775 return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
776 RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
777 }
778
779 DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
780
781 /**
782 * Displays the time required to write the GNPTXFSIZ register many times (the
783 * output shows the number of times the register is written).
784 */
785 static ssize_t wr_reg_test_show( struct device *_dev,
786 struct device_attribute *attr,
787 char *buf)
788 {
789 struct platform_device *pdev = container_of(_dev, struct platform_device, dev); \
790 dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); \
791 uint32_t reg_val;
792 int i;
793 int time;
794 int start_jiffies;
795
796 printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
797 HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
798 reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
799 start_jiffies = jiffies;
800 for (i = 0; i < RW_REG_COUNT; i++) {
801 dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
802 }
803 time = jiffies - start_jiffies;
804 return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
805 RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
806 }
807
808 DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
809 /**@}*/
810
811 /**
812 * Create the device files
813 */
814 void dwc_otg_attr_create (struct platform_device *pdev)
815 {
816 struct device *dev = &pdev->dev;
817 int error;
818
819 error = device_create_file(dev, &dev_attr_regoffset);
820 error = device_create_file(dev, &dev_attr_regvalue);
821 error = device_create_file(dev, &dev_attr_mode);
822 error = device_create_file(dev, &dev_attr_hnpcapable);
823 error = device_create_file(dev, &dev_attr_srpcapable);
824 error = device_create_file(dev, &dev_attr_hnp);
825 error = device_create_file(dev, &dev_attr_srp);
826 error = device_create_file(dev, &dev_attr_buspower);
827 error = device_create_file(dev, &dev_attr_bussuspend);
828 error = device_create_file(dev, &dev_attr_busconnected);
829 error = device_create_file(dev, &dev_attr_gotgctl);
830 error = device_create_file(dev, &dev_attr_gusbcfg);
831 error = device_create_file(dev, &dev_attr_grxfsiz);
832 error = device_create_file(dev, &dev_attr_gnptxfsiz);
833 error = device_create_file(dev, &dev_attr_gpvndctl);
834 error = device_create_file(dev, &dev_attr_ggpio);
835 error = device_create_file(dev, &dev_attr_guid);
836 error = device_create_file(dev, &dev_attr_gsnpsid);
837 error = device_create_file(dev, &dev_attr_devspeed);
838 error = device_create_file(dev, &dev_attr_enumspeed);
839 error = device_create_file(dev, &dev_attr_hptxfsiz);
840 error = device_create_file(dev, &dev_attr_hprt0);
841 error = device_create_file(dev, &dev_attr_remote_wakeup);
842 error = device_create_file(dev, &dev_attr_regdump);
843 error = device_create_file(dev, &dev_attr_spramdump);
844 error = device_create_file(dev, &dev_attr_hcddump);
845 error = device_create_file(dev, &dev_attr_hcd_frrem);
846 error = device_create_file(dev, &dev_attr_rd_reg_test);
847 error = device_create_file(dev, &dev_attr_wr_reg_test);
848 }
849
850 /**
851 * Remove the device files
852 */
853 void dwc_otg_attr_remove (struct platform_device *pdev)
854 {
855 struct device *dev = &pdev->dev;
856
857 device_remove_file(dev, &dev_attr_regoffset);
858 device_remove_file(dev, &dev_attr_regvalue);
859 device_remove_file(dev, &dev_attr_mode);
860 device_remove_file(dev, &dev_attr_hnpcapable);
861 device_remove_file(dev, &dev_attr_srpcapable);
862 device_remove_file(dev, &dev_attr_hnp);
863 device_remove_file(dev, &dev_attr_srp);
864 device_remove_file(dev, &dev_attr_buspower);
865 device_remove_file(dev, &dev_attr_bussuspend);
866 device_remove_file(dev, &dev_attr_busconnected);
867 device_remove_file(dev, &dev_attr_gotgctl);
868 device_remove_file(dev, &dev_attr_gusbcfg);
869 device_remove_file(dev, &dev_attr_grxfsiz);
870 device_remove_file(dev, &dev_attr_gnptxfsiz);
871 device_remove_file(dev, &dev_attr_gpvndctl);
872 device_remove_file(dev, &dev_attr_ggpio);
873 device_remove_file(dev, &dev_attr_guid);
874 device_remove_file(dev, &dev_attr_gsnpsid);
875 device_remove_file(dev, &dev_attr_devspeed);
876 device_remove_file(dev, &dev_attr_enumspeed);
877 device_remove_file(dev, &dev_attr_hptxfsiz);
878 device_remove_file(dev, &dev_attr_hprt0);
879 device_remove_file(dev, &dev_attr_remote_wakeup);
880 device_remove_file(dev, &dev_attr_regdump);
881 device_remove_file(dev, &dev_attr_spramdump);
882 device_remove_file(dev, &dev_attr_hcddump);
883 device_remove_file(dev, &dev_attr_hcd_frrem);
884 device_remove_file(dev, &dev_attr_rd_reg_test);
885 device_remove_file(dev, &dev_attr_wr_reg_test);
886 }