Fix common misspellings
[linux-flexiantxendom0-3.2.10.git] / drivers / staging / westbridge / astoria / include / linux / westbridge / cyashaldoc.h
1 /* Cypress West Bridge API header file (cyashaldoc.h)
2 ## ===========================
3 ## Copyright (C) 2010  Cypress Semiconductor
4 ##
5 ## This program is free software; you can redistribute it and/or
6 ## modify it under the terms of the GNU General Public License
7 ## as published by the Free Software Foundation; either version 2
8 ## of the License, or (at your option) any later version.
9 ##
10 ## This program is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ## GNU General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program; if not, write to the Free Software
17 ## Foundation, Inc., 51 Franklin Street
18 ## Fifth Floor, Boston, MA  02110-1301, USA.
19 ## ===========================
20 */
21
22 #ifndef _INCLUDED_CYASHALDOC_H_
23 #define _INCLUDED_CYASHALDOC_H_
24
25 #include "cyashaldef.h"
26
27 /*@@Hardware Abstraction Layer (HAL)
28         Summary
29         This software module is supplied by the user of the West Bridge
30         API.  This module contains the software that is specific to the
31         hardware implementation or operating system of the client
32         system.
33
34         * Sleep Channels *
35         A sleep channel is a operating system object that provides that
36         capability for one thread or process to sleep while waiting on
37         the completion of some hardware event. The hardware event is
38         usually processed by a hardware interrupt and the interrupt
39         handler then wakes the thread or process that is sleeping.
40
41         A sleep channel provides the mechanism for this operation.  A
42         sleep channel is created and initialized during the API
43         initialization. When the API needs to wait for the hardware,
44         the API performs a SleepOn() operation on the sleep channel.
45         When hardware event occurs, an interrupt handler processes the
46         event and then performs a Wake() operation on the sleep channel
47         to wake the sleeping process or thread.
48
49         * DMA Model *
50         When the West Bridge API needs to transfer USB or storage data
51         to/from the West Bridge device, this is done using a "DMA"
52         operation.  In this context the term DMA is used loosely as the
53         West Bridge API does not really care if the data is transferred
54         using a burst read or write operation, or if the data is
55         transferred using programmed I/O operations.  When a "DMA"
56         operation is needed, the West Bridge API calls either
57         CyAsHalDmaSetupRead() or CyAsHalDmaSetupWrite() depending on the
58         direction of the data flow.  The West Bridge API expects the
59         "DMA" operation requested in the call to be completed and the
60         registered "DMA complete" callback to be called.
61
62         The West Bridge API looks at several factors to determine the
63         size of the "DMA" request to pass to the HAL layer.  First the
64         West Bridge API calls CyAsHalDmaMaxRequestSize() to determine
65         the maximum amount of data the HAL layer can accept for a "DMA"
66         operation on the requested endpoint.  The West Bridge API will
67         never exceed this value in a "DMA" request to the HAL layer.
68         The West Bridge API also sends the maximum amount of data the
69         West Bridge device can accept as part of the "DMA" request. If
70         the amount of data in the "DMA" request to the HAL layer
71         exceeds the amount of data the West Bridge device can accept,
72         it is expected that the HAL layer has the ability to break the
73         request into multiple operations.
74
75         If the HAL implementation requires the API to handle the size
76         of the "DMA" requests for one or more endpoints, the value
77         CY_AS_DMA_MAX_SIZE_HW_SIZE can be returned from the
78         CyAsHalDmaMaxRequestSize() call.  In this case, the API assumes
79         that the maximum size of each "DMA" request should be limited
80         to the maximum that can be accepted by the endpoint in question.
81
82         Notes
83         See the <install>/api/hal/scm_kernel/cyashalscm_kernel.c file
84         for an example of how the DMA request size can be managed by
85         the HAL implementation.
86
87         * Interrupt Handling *
88         The HAL implementation is required to handle interrupts arriving
89         from the West Bridge device, and call the appropriate handlers.
90         If the interrupt arriving is one of PLLLOCKINT, PMINT, MBINT or
91         MCUINT, the CyAsIntrServiceInterrupt API should be called to
92         service the interrupt.  If the interrupt arriving is DRQINT, the
93         HAL should identify the endpoint corresponding to which the DRQ
94         is being generated and perform the read/write transfer from the
95         West Bridge. See the <install>/api/hal/scm_kernel/
96         cyashalscm_kernel.c or <install>/api/hal/fpga/cyashalfpga.c
97         reference HAL implementations for examples.
98
99         The HAL implementation can choose to poll the West Bridge
100         interrupt status register instead of using interrupts.  In this
101         case, the polling has to be performed from a different thread/
102         task than the one running the APIs.  This is required because
103         there are API calls that block on the reception of data from the
104         West Bridge, which is delivered only through the interrupt
105         handlers.
106
107         * Required Functions *
108         This section defines the types and functions that must be
109         supplied in order to provide a complete HAL layer for the
110         West Bridge API.
111
112         Types that must be supplied:
113         * CyAsHalSleepChannel
114
115         Hardware functions that must be supplied:
116         * CyAsHalWriteRegister
117         * CyAsHalReadRegister
118         * CyAsHalDmaSetupWrite
119         * CyAsHalDmaSetupRead
120         * CyAsHalDmaCancelRequest
121         * CyAsHalDmaRegisterCallback
122         * CyAsHalDmaMaxRequestSize
123         * CyAsHalSetWakeupPin
124         * CyAsHalSyncDeviceClocks
125         * CyAsHalInitDevRegisters
126         * CyAsHalReadRegsBeforeStandby
127         * CyAsHalRestoreRegsAfterStandby
128
129         Operating system functions that must be supplied:
130         * CyAsHalAlloc
131         * CyAsHalFree
132         * CyAsHalCBAlloc
133         * CyAsHalCBFree
134         * CyAsHalMemSet
135         * CyAsHalCreateSleepChannel
136         * CyAsHalDestroySleepChannel
137         * CyAsHalSleepOn
138         * CyAsHalWake
139         * CyAsHalDisableInterrupts
140         * CyAsHalEnableInterrupts
141         * CyAsHalSleep150
142         * CyAsHalSleep
143         * CyAsHalAssert
144         * CyAsHalPrintMessage
145         * CyAsHalIsPolling
146 */
147
148 /* Summary
149    This is the type that represents a sleep channel
150
151    Description
152    A sleep channel is an operating system object that, when a
153    thread of control waits on the sleep channel, the thread
154    sleeps until another thread signals the sleep object. This
155    object is generally used when a high level API is called
156    and must wait for a response that is supplied in an interrupt
157    handler.  The thread calling the API is put into a sleep
158    state and when the reply arrives via the interrupt handler,
159    the interrupt handler wakes the sleeping thread to indicate
160    that the expect reply is available.
161 */
162 typedef struct cy_as_hal_sleep_channel {
163         /* This structure is filled in with OS specific information
164         to implementat a sleep channel */
165         int                                     m_channel;
166 } cy_as_hal_sleep_channel;
167
168 /* Summary
169    This function is called to write a register value
170
171    Description
172    This function is called to write a specific register to a
173    specific value.  The tag identifies the device of interest.
174    The address is relative to the base address of the West
175    Bridge device.
176
177    Returns
178    Nothing
179
180    See Also
181    * CyAsHalDeviceTag
182    * CyAsHalReadRegister
183 */
184 EXTERN void
185 cy_as_hal_write_register(
186 /* The tag to ID a specific West Bridge device */
187         cy_as_hal_device_tag                    tag,
188         /* The address we are writing to */
189         uint16_t                                addr,
190         /* The value to write to the register */
191         uint16_t                                value
192         );
193
194 /* Summary
195    This function is called to read a register value
196
197    Description
198    This function is called to read the contents of a specific
199    register. The tag identifies the device of interest. The
200    address is relative to the base address of the West Bridge
201    device.
202
203    Returns
204    Contents of the register
205
206    See Also
207    * CyAsHalDeviceTag
208    * CyAsHalWriteRegister
209 */
210 EXTERN uint16_t
211 cy_as_hal_read_register(
212         /* The tag to ID a specific West Bridge device */
213         cy_as_hal_device_tag tag,
214         /* The address we are writing to */
215         uint16_t addr
216         );
217
218 /* Summary
219    This function initiates a DMA write operation to write
220    to West Bridge
221
222    Description
223    This function initiates a DMA write operation.  The request
224    size will not exceed the value the HAL layer returned via
225    CyAsHalDmaMaxRequestSize().  This request size may exceed
226    the size of what the West Bridge device will accept as on
227    packet and the HAL layer may need to divide the request
228    into multiple hardware DMA operations.
229
230    Returns
231    None
232
233    See Also
234    * CyAsHalDmaSetupRead
235    * CyAsHalDmaMaxRequestSize
236 */
237 EXTERN void
238 cy_as_hal_dma_setup_write(
239         /* The tag to ID a specific West Bridge device */
240         cy_as_hal_device_tag                    tag,
241         /* The endpoint we are writing to */
242         cy_as_end_point_number_t                ep,
243         /* The data to write via DMA */
244         void *buf_p,
245         /* The size of the data at buf_p */
246         uint32_t                                size,
247         /* The maximum amount of data that the endpoint
248          * can accept as one packet */
249         uint16_t                                maxsize
250         );
251
252 /* Summary
253    This function initiates a DMA read operation from West Bridge
254
255    Description
256    This function initiates a DMA read operation.  The request
257    size will not exceed the value the HAL layer returned via
258    CyAsHalDmaMaxRequestSize().  This request size may exceed
259    the size of what the Anitoch will accept as one packet and
260    the HAL layer may need to divide the request into multiple
261    hardware DMA operations.
262
263    Returns
264    None
265
266    See Also
267    * CyAsHalDmaSetupRead
268    * CyAsHalDmaMaxRequestSize
269 */
270 EXTERN void
271 cy_as_hal_dma_setup_read(
272         /* The tag to ID a specific West Bridge device */
273         cy_as_hal_device_tag                    tag,
274         /* The endpoint we are reading from */
275         cy_as_end_point_number_t                ep,
276         /* The buffer to read data into */
277         void *buf_p,
278         /* The amount of data to read */
279         uint32_t                                size,
280         /* The maximum amount of data that the endpoint
281          * can provide in one DMA operation */
282         uint16_t                                maxsize
283         );
284
285 /* Summary
286    This function cancels a pending DMA request
287
288    Description
289    This function cancels a pending DMA request that has been
290    passed down to the hardware.  The HAL layer can elect to
291    physically cancel the request if possible, or just ignore
292    the results of the request if it is not possible.
293
294    Returns
295    None
296 */
297 EXTERN void
298 cy_as_hal_dma_cancel_request(
299         /* The tag to ID a specific West Bridge device */
300         cy_as_hal_device_tag                    tag,
301         /* The endpoint we are reading from */
302         cy_as_end_point_number_t                ep
303         );
304
305 /* Summary
306    This function registers a callback function to be called when
307    a DMA request is completed
308
309    Description
310    This function registers a callback that is called when a request
311    issued via CyAsHalDmaSetupWrite() or CyAsHalDmaSetupRead() has
312    completed.
313
314    Returns
315    None
316
317    See Also
318    * CyAsHalDmaSetupWrite
319    * CyAsHalDmaSetupRead
320 */
321 EXTERN void
322 cy_as_hal_dma_register_callback(
323         /* The tag to ID a specific West Bridge device */
324         cy_as_hal_device_tag tag,
325         /* The callback to call when a request has completed */
326         cy_as_hal_dma_complete_callback         cb
327         );
328
329 /* Summary
330    This function returns the maximum size of a DMA request that can
331    be handled by the HAL.
332
333    Description
334    When DMA requests are passed to the HAL layer for processing,
335    the HAL layer may have a limit on the size of the request that
336    can be handled.  This function is called by the DMA manager for
337    an endpoint when DMA is enabled to get the maximum size of data
338    the HAL layer can handle. The DMA manager insures that a request
339    is never sent to the HAL layer that exceeds the size returned by
340    this function.
341
342    Returns
343    the maximum size of DMA request the HAL layer can handle
344 */
345 EXTERN uint32_t
346 cy_as_hal_dma_max_request_size(
347         /* The tag to ID a specific West Bridge device */
348         cy_as_hal_device_tag tag,
349         /* The endpoint of interest */
350         cy_as_end_point_number_t ep
351         );
352
353 /* Summary
354    This function sets the WAKEUP pin to a specific state on the
355    West Bridge device.
356
357    Description
358    In order to enter the standby mode, the WAKEUP pin must be
359    de-asserted.  In order to resume from standby mode, the WAKEUP
360    pin must be asserted.  This function provides the mechanism to
361    do this.
362
363    Returns
364    1 if the pin was changed, 0 if the HAL layer does not support
365    changing this pin
366 */
367 EXTERN uint32_t
368 cy_as_hal_set_wakeup_pin(
369         /* The tag to ID a specific West Bridge device */
370         cy_as_hal_device_tag tag,
371         /* The desired state of the wakeup pin */
372         cy_bool state
373         );
374
375 /* Summary
376    Synchronise the West Bridge device clocks to re-establish device
377    connectivity.
378
379    Description
380    When the Astoria bridge device is working in SPI mode, a long
381    period of inactivity can cause a loss of serial synchronisation
382    between the processor and Astoria.  This function is called by
383    the API when it detects such a condition, and is expected to take
384    the action required to re-establish clock synchronisation between
385    the devices.
386
387    Returns
388    CyTrue if the attempt to re-synchronise is successful,
389    CyFalse if not.
390  */
391 EXTERN cy_bool
392 cy_as_hal_sync_device_clocks(
393         /* The tag to ID a specific West Bridge device */
394         cy_as_hal_device_tag tag,
395         );
396
397 /* Summary
398    Initialize West Bridge device registers that may have been
399    modified while the device was in standby.
400
401    Description
402    The content of some West Bridge registers may be lost when
403    the device is placed in standby mode.  This function restores
404    these register contents so that the device can continue to
405    function normally after it wakes up from standby mode.
406
407    This function is required to perform operations only when the
408    API is being used with the Astoria device in one of the PNAND
409    modes or in the PSPI mode.  It can be a no-operation in all
410    other cases.
411
412    Returns
413    None
414  */
415 EXTERN void
416 cy_as_hal_init_dev_registers(
417         /* The tag to ID a specific West Bridge device */
418         cy_as_hal_device_tag tag,
419         /* Indicates whether this is a wake-up from standby. */
420         cy_bool is_standby_wakeup
421         );
422
423 /* Summary
424    This function reads a set of P-port accessible device registers and
425    stores their value for later use.
426
427    Description
428    The West Bridge Astoria device silicon has a known problem when
429    operating in SPI mode on the P-port, where some of the device
430    registers lose their value when the device goes in and out of
431    standby mode.  The suggested work-around is to reset the Astoria
432    device as part of the wakeup procedure from standby.
433
434    This requires that the values of some of the P-port accessible
435    registers be restored to their pre-standby values after it has
436    been reset.  This HAL function can be used to read and store
437    the values of these registers at the point where the device is
438    being placed in standby mode.
439
440    Returns
441    None
442
443    See Also
444    * CyAsHalRestoreRegsAfterStandby
445  */
446 EXTERN void
447 cy_as_hal_read_regs_before_standby(
448         /* The tag to ID a specific West Bridge device */
449         cy_as_hal_device_tag tag
450         );
451
452 /* Summary
453    This function restores the old values to a set of P-port
454    accessible device registers.
455
456    Description
457    This function is part of the work-around to a known West
458    Bridge Astoria device error when operating in SPI mode on
459    the P-port.  This function is used to restore a set of
460    P-port accessible registers to the values they had before
461    the device was placed in standby mode.
462
463    Returns
464    None
465
466    See Also
467    * CyAsHalRestoreRegsAfterStandby
468  */
469 EXTERN void
470 cy_as_hal_restore_regs_after_standby(
471         /* The tag to ID a specific West Bridge device */
472         cy_as_hal_device_tag tag
473         );
474
475 /*
476  * The functions below this comment are part of the HAL layer,
477  * as the HAL layer consists of the abstraction to both the
478  * hardware platform and the operating system.  However; the
479  * functions below this comment all relate to the operating
480  * environment and not specifically to the hardware platform
481  * or specific device.
482  */
483
484 /* Summary
485    This function allocates a block of memory
486
487    Description
488    This is the HAL layer equivalent of the malloc() function.
489
490    Returns
491    a pointer to a block of memory
492
493    See Also
494    * CyAsHalFree
495 */
496 EXTERN void *
497 cy_as_hal_alloc(
498         /* The size of the memory block to allocate */
499         uint32_t                                size
500         );
501
502 /* Summary
503    This function frees a previously allocated block of memory
504
505    Description
506    This is the HAL layer equivalent of the free() function.
507
508    Returns
509    None
510
511    See Also
512    * CyAsHalAlloc
513 */
514 EXTERN void
515 cy_as_hal_free(
516         /* Pointer to a memory block to free */
517         void *ptr
518         );
519
520 /* Summary
521    This function is a malloc equivalent that can be used from an
522    interrupt context.
523
524    Description
525    This function is a malloc equivalent that will be called from the
526    API in callbacks. This function is required to be able to provide
527    memory in interrupt context.
528
529    Notes
530    For platforms where it is not possible to allocate memory in interrupt
531    context, we provide a reference allocator that takes memory during
532    initialization and implements malloc/free using this memory.
533    See the <install>/api/hal/fpga/cyashalblkalloc.[ch] files for the
534    implementation, and the <install>/api/hal/fpga/cyashalfpga.c file
535    for an example of the use of this allocator.
536
537    Returns
538    A pointer to the allocated block of memory
539
540    See Also
541    * CyAsHalCBFree
542    * CyAsHalAlloc
543 */
544 EXTERN void *
545 cy_as_hal_c_b_alloc(
546         /* The size of the memory block to allocate */
547         uint32_t size
548         );
549
550 /* Summary
551    This function frees the memory allocated through the CyAsHalCBAlloc
552    call.
553
554    Description
555    This function frees memory allocated through the CyAsHalCBAlloc
556    call, and is also required to support calls from interrupt
557    context.
558
559    Returns
560    None
561
562    See Also
563    * CyAsHalCBAlloc
564    * CyAsHalFree
565 */
566 EXTERN void
567 cy_as_hal_c_b_free(
568         /* Pointer to the memory block to be freed */
569         void *ptr
570         );
571
572 /* Summary
573    This function sets a block of memory to a specific value
574
575    Description
576    This function is the HAL layer equivalent of the memset() function.
577
578    Returns
579    None
580 */
581 EXTERN void
582 cy_as_mem_set(
583         /* A pointer to a block of memory to set */
584         void *ptr,
585         /* The value to set the memory to */
586         uint8_t value,
587         /* The number of bytes to set */
588         uint32_t cnt
589         );
590
591 /* Summary
592    This function creates or initializes a sleep channel
593
594    Description
595    This function creates or initializes a sleep channel. The
596    sleep channel defined using the HAL data structure
597    CyAsHalSleepChannel.
598
599    Returns
600    CyTrue is the initialization was successful, and CyFalse otherwise
601
602    See Also
603    * CyAsHalSleepChannel
604    * CyAsHalDestroySleepChannel
605    * CyAsHalSleepOn
606    * CyAsHalWake
607 */
608 EXTERN cy_bool
609 cy_as_hal_create_sleep_channel(
610         /* Pointer to the sleep channel to create/initialize */
611         cy_as_hal_sleep_channel *chan
612         );
613
614 /* Summary
615    This function destroys an existing sleep channel
616
617    Description
618    This function destroys an existing sleep channel.  The sleep channel
619    is of type CyAsHalSleepChannel.
620
621    Returns
622    CyTrue if the channel was destroyed, and CyFalse otherwise
623
624    See Also
625    * CyAsHalSleepChannel
626    * CyAsHalCreateSleepChannel
627    * CyAsHalSleepOn
628    * CyAsHalWake
629 */
630 EXTERN cy_bool
631 cy_as_hal_destroy_sleep_channel(
632         /* The sleep channel to destroy */
633         cy_as_hal_sleep_channel         chan
634         );
635
636 /* Summary
637    This function causes the calling process or thread to sleep until
638    CyAsHalWake() is called
639
640    Description
641    This function causes the calling process or threadvto sleep.
642    When CyAsHalWake() is called on the same sleep channel, this
643    processes or thread is then wakened and allowed to run
644
645    Returns
646    CyTrue if the thread or process is asleep, and CyFalse otherwise
647
648    See Also
649    * CyAsHalSleepChannel
650    * CyAsHalWake
651 */
652 EXTERN cy_bool
653 cy_as_hal_sleep_on(
654         /* The sleep channel to sleep on */
655         cy_as_hal_sleep_channel chan,
656         /* The maximum time to sleep in milli-seconds */
657         uint32_t ms
658         );
659
660 /* Summary
661    This function casues the process or thread sleeping on the given
662    sleep channel to wake
663
664    Description
665    This function causes the process or thread sleeping on the given
666    sleep channel to wake.  The channel
667
668    Returns
669    CyTrue if the thread or process is awake, and CyFalse otherwise
670
671    See Also
672    * CyAsHalSleepChannel
673    * CyAsHalSleepOn
674 */
675 EXTERN cy_bool
676 cy_as_hal_wake(
677         /* The sleep channel to wake */
678         cy_as_hal_sleep_channel         chan
679         );
680
681 /* Summary
682    This function disables interrupts, insuring that short bursts
683    of code can be run without danger of interrupt handlers running.
684
685    Description
686    There are cases within the API when lists must be manipulated by
687    both the API and the associated interrupt handlers.  In these
688    cases, interrupts must be disabled to insure the integrity of the
689    list during the modification. This function is used to disable
690    interrupts during the short intervals where these lists are being
691    changed.
692
693    The HAL must have the ability to nest calls to
694    CyAsHalDisableInterrupts and CyAsHalEnableInterrupts.
695
696    Returns
697    Any interrupt related state value which will be passed back into
698    the subsequent CyAsHalEnableInterrupts call.
699
700    See Also
701    * CyAsHalEnableInterrupts
702 */
703 EXTERN uint32_t
704 cy_as_hal_disable_interrupts();
705
706 /* Summary
707    This function re-enables interrupts after a critical section of
708    code in the API has been completed.
709
710    Description
711    There are cases within the API when lists must be manipulated by
712    both the API and the associated interrupt handlers.  In these
713    cases, interrupts must be disabled to insure the integrity of the
714    list during the modification.  This function is used to enable
715    interrupts after the short intervals where these lists are being
716    changed.
717
718    See Also
719    * CyAsHalDisableInterrupts
720 */
721 EXTERN void
722 cy_as_hal_enable_interrupts(
723         /* Value returned by the previous CyAsHalDisableInterrupts call. */
724         uint32_t value
725         );
726
727 /* Summary
728    This function sleeps for 150 ns.
729
730    Description
731    This function sleeps for 150 ns before allowing the calling function
732    to continue.  This function is used for a specific purpose and the
733    sleep required is at least 150 ns.
734 */
735 EXTERN void
736 cy_as_hal_sleep150(
737                 );
738
739 /* Summary
740    This function sleeps for the given number of milliseconds
741
742    Description
743    This function sleeps for at least the given number of milliseonds
744 */
745 EXTERN void
746 cy_as_hal_sleep(
747                 uint32_t ms
748                 );
749
750 /* Summary
751    This function asserts when the condition evaluates to zero
752
753    Description
754    Within the API there are conditions which are checked to insure
755    the integrity of the code. These conditions are checked only
756    within a DEBUG build. This function is used to check the condition
757    and if the result evaluates to zero, it should be considered a
758    fatal error that should be reported to Cypress.
759 */
760 EXTERN void
761 cy_as_hal_assert(
762         /* The condition to evaluate */
763         cy_bool cond
764         );
765
766 /* Summary
767    This function prints a message from the API to a human readable device
768
769    Description
770    There are places within the West Bridge API where printing a message
771    is useful to the debug process.  This function provides the mechanism
772    to print a message.
773
774    Returns
775    NONE
776 */
777 EXTERN void
778 cy_as_hal_print_message(
779         /* The message to print */
780         const char *fmt_p,
781         ...     /* Variable arguments */
782         );
783
784 /* Summary
785    This function reports whether the HAL implementation uses
786    polling to service data coming from the West Bridge.
787
788    Description
789    This function reports whether the HAL implementation uses
790    polling to service data coming from the West Bridge.
791
792    Returns
793    CyTrue if the HAL polls the West Bridge Interrupt Status registers
794    to complete operations, CyFalse if the HAL is interrupt driven.
795  */
796 EXTERN cy_bool
797 cy_as_hal_is_polling(
798                 void);
799
800 #endif