Commit 81eb669b authored by David Cross's avatar David Cross Committed by Greg Kroah-Hartman

Staging: add West Bridge Astoria Driver

This is a driver for the Cypress West Bridge companion chip. Its
function is analogous to the North/South Bridges of PC environments
applied to embedded devices, in that it expands I/O and storage
capabilities of an embedded processor. The Astoria version, which this
driver applies to, functions as a USB, embedded memory and SDIO
controller. The kernel that this patch was applied to is linux-2.6.35,
although it was tested using the android kernel 2.6.29 running on the
Zoom 2 platform. In this system, it was used primarily as a sideloading
accelerator enabling direct data transfers between a USB host PC and
embedded memory without system overheads.  Minor modifications were also
made to the kernel for this patch. These include changes such as
EXPORTing of fat_get_block in the kernel code. Another function,
mpage_cleardirty was also added to the memory management code. This
function is used to clear the dirty pages from a specific inode. This
allows for direct, file based DMA. None of these changes are believed to
have any negative impact on the kernel and may provide additional
benefit for other developers and drivers.

The driver, as submitted, was placed into the drivers/staging/westbridge
folder as the directory structure it will eventually reside in is not yet
defined. The driver, as placed in staging is divided into four parts:
1) gadget - this implements a gadget peripheral controller and includes IOCTLs
for MTP transfers
2) block -this implements a generic block device driver to enable access to
embedded memory
3) api -this is the Cypress SDK, and includes USB and Storage specific
functions. In addition, it includes common code for low level routines such as
message passing and common data transfer routines
4) hal - this should likely be included in the arch directory as it needs to
be modified for a given platform. The directory structure in the staging area
is meant to reflect the eventual location of where this code likely should be.
It is platform specific. In this case, the HAL included is for the Android
Zoom 2 platform. Here, West Bridge is connected to the GPMC (general purpose
memory controller) of the OMAP3. Specific timing needs to be enabled to ensure
reliable communication.
Many thanks to Greg KH for conducting initial reviews and providing pointers.
Please contact david.cross@cypress.com for questions, concerns or feedback.
Signed-off-by: default avatarDavid Cross <david.cross@cypress.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 760ffce8
...@@ -153,5 +153,7 @@ source "drivers/staging/tidspbridge/Kconfig" ...@@ -153,5 +153,7 @@ source "drivers/staging/tidspbridge/Kconfig"
source "drivers/staging/quickstart/Kconfig" source "drivers/staging/quickstart/Kconfig"
source "drivers/staging/westbridge/Kconfig"
endif # !STAGING_EXCLUDE_BUILD endif # !STAGING_EXCLUDE_BUILD
endif # STAGING endif # STAGING
...@@ -57,3 +57,4 @@ obj-$(CONFIG_EASYCAP) += easycap/ ...@@ -57,3 +57,4 @@ obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_SOLO6X10) += solo6x10/ obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/
#
# West Bridge configuration
#
menuconfig WESTBRIDGE
tristate "West Bridge support"
depends on HAS_IOMEM
help
This selects West Bridge Peripheral controller support.
If you want West Bridge support, you should say Y here.
menuconfig WESTBRIDGE_ASTORIA
bool "West Bridge Astoria support"
depends on WESTBRIDGE != n
help
This option enables support for West Bridge Astoria
if WESTBRIDGE_ASTORIA
source "drivers/staging/westbridge/astoria/Kconfig"
endif #WESTBRIDGE_ASTORIA
menuconfig MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
bool "WESTBRIDGE OMAP3430 Astoria PNAND HAL"
depends on ARCH_OMAP3 && WESTBRIDGE_ASTORIA
help
Include the OMAP3430 Linux Based HAL
config WESTBRIDGE_DEBUG
bool "West Bridge debugging"
depends on WESTBRIDGE != n
help
This is an option for use by developers; most people should
say N here. This enables WESTBRIDGE core and driver debugging.
\ No newline at end of file
TODO:
- checkpatch.pl fixes
- determine where to put the hal and common api code
- modify the driver directory structure in an intuitive way
Please send any patches to Greg Kroah-Hartman <gregkh@suse.de>
and David Cross <david.cross@cypress.com>.
#
# West Bridge configuration
#
source "drivers/staging/westbridge/astoria/device/Kconfig"
source "drivers/staging/westbridge/astoria/block/Kconfig"
source "drivers/staging/westbridge/astoria/gadget/Kconfig"
#
# Makefile for the kernel westbridge device drivers.
#
ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
EXTRA_CFLAGS += -WESTBRIDGE_NDEBUG
endif
obj-$(CONFIG_WESTBRIDGE) += device/
obj-$(CONFIG_WESTBRIDGE) += block/
obj-$(CONFIG_WESTBRIDGE) += gadget/
\ No newline at end of file
#
# Makefile for the kernel westbridge core.
#
ifeq ($(CONFIG_WESTBRIDGE_DEBUG),n)
EXTRA_CFLAGS += -NDEBUG
endif
obj-$(CONFIG_WESTBRIDGE_DEVICE_DRIVER) += cyasapi.o
cyasapi-y := src/cyasdma.o src/cyasintr.o src/cyaslep2pep.o \
src/cyaslowlevel.o src/cyasmisc.o src/cyasmtp.o \
src/cyasstorage.o src/cyasusb.o
This diff is collapsed.
/* Cypress West Bridge API source file (cyasintr.c)
## ===========================
## Copyright (C) 2010 Cypress Semiconductor
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor
## Boston, MA 02110-1301, USA.
## ===========================
*/
#include "../../include/linux/westbridge/cyashal.h"
#include "../../include/linux/westbridge/cyasdevice.h"
#include "../../include/linux/westbridge/cyasregs.h"
#include "../../include/linux/westbridge/cyaserr.h"
extern void cy_as_mail_box_interrupt_handler(cy_as_device *) ;
void
cy_as_mcu_interrupt_handler(cy_as_device *dev_p)
{
/* Read and clear the interrupt. */
uint16_t v ;
v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT) ;
v = v ;
}
void
cy_as_power_management_interrupt_handler(cy_as_device *dev_p)
{
uint16_t v ;
v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT) ;
v = v ;
}
void
cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p)
{
uint16_t v ;
v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT) ;
v = v ;
}
uint32_t cy_as_intr_start(cy_as_device *dev_p, cy_bool dmaintr)
{
uint16_t v ;
cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
if (cy_as_device_is_intr_running(dev_p) != 0)
return CY_AS_ERROR_ALREADY_RUNNING ;
v = CY_AS_MEM_P0_INT_MASK_REG_MMCUINT |
CY_AS_MEM_P0_INT_MASK_REG_MMBINT |
CY_AS_MEM_P0_INT_MASK_REG_MPMINT ;
if (dmaintr)
v |= CY_AS_MEM_P0_INT_MASK_REG_MDRQINT ;
/* Enable the interrupts of interest */
cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, v) ;
/* Mark the interrupt module as initialized */
cy_as_device_set_intr_running(dev_p) ;
return CY_AS_ERROR_SUCCESS ;
}
uint32_t cy_as_intr_stop(cy_as_device *dev_p)
{
cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
if (cy_as_device_is_intr_running(dev_p) == 0)
return CY_AS_ERROR_NOT_RUNNING ;
cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, 0) ;
cy_as_device_set_intr_stopped(dev_p) ;
return CY_AS_ERROR_SUCCESS ;
}
void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag)
{
uint16_t v ;
cy_as_device *dev_p ;
dev_p = cy_as_device_find_from_tag(tag) ;
/*
* only power management interrupts can occur before the
* antioch API setup is complete. if this is a PM interrupt
* handle it here; otherwise output a warning message.
*/
if (dev_p == 0) {
v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG) ;
if (v == CY_AS_MEM_P0_INTR_REG_PMINT) {
/* Read the PWR_MAGT_STAT register
* to clear this interrupt. */
v = cy_as_hal_read_register(tag,
CY_AS_MEM_PWR_MAGT_STAT) ;
} else
cy_as_hal_print_message("stray antioch "
"interrupt detected"
", tag not associated "
"with any created device.") ;
return ;
}
/* Make sure we got a valid object from CyAsDeviceFindFromTag */
cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG) ;
if (v & CY_AS_MEM_P0_INTR_REG_MCUINT)
cy_as_mcu_interrupt_handler(dev_p) ;
if (v & CY_AS_MEM_P0_INTR_REG_PMINT)
cy_as_power_management_interrupt_handler(dev_p) ;
if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
cy_as_pll_lock_loss_interrupt_handler(dev_p) ;
/* If the interrupt module is not running, no mailbox
* interrupts are expected from the west bridge. */
if (cy_as_device_is_intr_running(dev_p) == 0)
return ;
if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
cy_as_mail_box_interrupt_handler(dev_p) ;
}
/* Cypress West Bridge API source file (cyaslep2pep.c)
## ===========================
## Copyright (C) 2010 Cypress Semiconductor
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor
## Boston, MA 02110-1301, USA.
## ===========================
*/
#include "../../include/linux/westbridge/cyashal.h"
#include "../../include/linux/westbridge/cyasusb.h"
#include "../../include/linux/westbridge/cyaserr.h"
#include "../../include/linux/westbridge/cyaslowlevel.h"
#include "../../include/linux/westbridge/cyasdma.h"
typedef enum cy_as_physical_endpoint_state {
cy_as_e_p_free,
cy_as_e_p_in,
cy_as_e_p_out,
cy_as_e_p_iso_in,
cy_as_e_p_iso_out
} cy_as_physical_endpoint_state;
/*
* This map is used to map an index between 1 and 10
* to a logical endpoint number. This is used to map
* LEP register indexes into actual EP numbers.
*/
static cy_as_end_point_number_t end_point_map[] = {
3, 5, 7, 9, 10, 11, 12, 13, 14, 15 } ;
#define CY_AS_EPCFG_1024 (1 << 3)
#define CY_AS_EPCFG_DBL (0x02)
#define CY_AS_EPCFG_TRIPLE (0x03)
#define CY_AS_EPCFG_QUAD (0x00)
/*
* NB: This table contains the register values for PEP1
* and PEP3. PEP2 and PEP4 only have a bit to change the
* direction of the PEP and therefre are not represented
* in this table.
*/
static uint8_t pep_register_values[12][4] = {
/* Bit 1:0 buffering, 0 = quad, 2 = double, 3 = triple */
/* Bit 3 size, 0 = 512, 1 = 1024 */
{
CY_AS_EPCFG_DBL,
CY_AS_EPCFG_DBL,
},/* Config 1 - PEP1 (2 * 512), PEP2 (2 * 512),
* PEP3 (2 * 512), PEP4 (2 * 512) */
{
CY_AS_EPCFG_DBL,
CY_AS_EPCFG_QUAD,
}, /* Config 2 - PEP1 (2 * 512), PEP2 (2 * 512),
* PEP3 (4 * 512), PEP4 (N/A) */
{
CY_AS_EPCFG_DBL,
CY_AS_EPCFG_DBL | CY_AS_EPCFG_1024,
},/* Config 3 - PEP1 (2 * 512), PEP2 (2 * 512),
* PEP3 (2 * 1024), PEP4(N/A) */
{
CY_AS_EPCFG_QUAD,
CY_AS_EPCFG_DBL,
},/* Config 4 - PEP1 (4 * 512), PEP2 (N/A),
* PEP3 (2 * 512), PEP4 (2 * 512) */
{
CY_AS_EPCFG_QUAD,
CY_AS_EPCFG_QUAD,
},/* Config 5 - PEP1 (4 * 512), PEP2 (N/A),
* PEP3 (4 * 512), PEP4 (N/A) */
{
CY_AS_EPCFG_QUAD,
CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
},/* Config 6 - PEP1 (4 * 512), PEP2 (N/A),
* PEP3 (2 * 1024), PEP4 (N/A) */
{
CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
CY_AS_EPCFG_DBL,
},/* Config 7 - PEP1 (2 * 1024), PEP2 (N/A),
* PEP3 (2 * 512), PEP4 (2 * 512) */
{
CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
CY_AS_EPCFG_QUAD,
},/* Config 8 - PEP1 (2 * 1024), PEP2 (N/A),
* PEP3 (4 * 512), PEP4 (N/A) */
{
CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL,
},/* Config 9 - PEP1 (2 * 1024), PEP2 (N/A),
* PEP3 (2 * 1024), PEP4 (N/A)*/
{
CY_AS_EPCFG_TRIPLE,
CY_AS_EPCFG_TRIPLE,
},/* Config 10 - PEP1 (3 * 512), PEP2 (N/A),
* PEP3 (3 * 512), PEP4 (2 * 512)*/
{
CY_AS_EPCFG_TRIPLE | CY_AS_EPCFG_1024,
CY_AS_EPCFG_DBL,
},/* Config 11 - PEP1 (3 * 1024), PEP2 (N/A),
* PEP3 (N/A), PEP4 (2 * 512) */
{
CY_AS_EPCFG_QUAD | CY_AS_EPCFG_1024,
CY_AS_EPCFG_DBL,
},/* Config 12 - PEP1 (4 * 1024), PEP2 (N/A),
* PEP3 (N/A), PEP4 (N/A) */
} ;
static cy_as_return_status_t
find_endpoint_directions(cy_as_device *dev_p,
cy_as_physical_endpoint_state epstate[4])
{
int i ;
cy_as_physical_endpoint_state desired ;
/*
* note, there is no error checking here becuase
* ISO error checking happens when the API is called.
*/
for (i = 0 ; i < 10 ; i++) {
int epno = end_point_map[i] ;
if (dev_p->usb_config[epno].enabled) {
int pep = dev_p->usb_config[epno].physical ;
if (dev_p->usb_config[epno].type == cy_as_usb_iso) {
/*
* marking this as an ISO endpoint, removes the
* physical EP from consideration when
* mapping the remaining E_ps.
*/
if (dev_p->usb_config[epno].dir == cy_as_usb_in)
desired = cy_as_e_p_iso_in ;
else
desired = cy_as_e_p_iso_out ;
} else {
if (dev_p->usb_config[epno].dir == cy_as_usb_in)
desired = cy_as_e_p_in ;
else
desired = cy_as_e_p_out ;
}
/*
* NB: Note the API calls insure that an ISO endpoint
* has a physical and logical EP number that are the
* same, therefore this condition is not enforced here.
*/
if (epstate[pep - 1] !=
cy_as_e_p_free && epstate[pep - 1] != desired)
return CY_AS_ERROR_INVALID_CONFIGURATION ;
epstate[pep - 1] = desired ;
}
}
/*
* create the EP1 config values directly.
* both EP1OUT and EP1IN are invalid by default.
*/
dev_p->usb_ep1cfg[0] = 0 ;
dev_p->usb_ep1cfg[1] = 0 ;
if (dev_p->usb_config[1].enabled) {
if ((dev_p->usb_config[1].dir == cy_as_usb_out) ||
(dev_p->usb_config[1].dir == cy_as_usb_in_out)) {
/* Set the valid bit and type field. */
dev_p->usb_ep1cfg[0] = (1 << 7) ;
if (dev_p->usb_config[1].type == cy_as_usb_bulk)
dev_p->usb_ep1cfg[0] |= (2 << 4) ;
else
dev_p->usb_ep1cfg[0] |= (3 << 4) ;
}
if ((dev_p->usb_config[1].dir == cy_as_usb_in) ||
(dev_p->usb_config[1].dir == cy_as_usb_in_out)) {
/* Set the valid bit and type field. */
dev_p->usb_ep1cfg[1] = (1 << 7) ;
if (dev_p->usb_config[1].type == cy_as_usb_bulk)
dev_p->usb_ep1cfg[1] |= (2 << 4) ;
else
dev_p->usb_ep1cfg[1] |= (3 << 4) ;
}
}
return CY_AS_ERROR_SUCCESS ;
}
static void
create_register_settings(cy_as_device *dev_p,
cy_as_physical_endpoint_state epstate[4])
{
int i ;
uint8_t v ;
for (i = 0 ; i < 4 ; i++) {
if (i == 0) {
/* Start with the values that specify size */
dev_p->usb_pepcfg[i] =
pep_register_values
[dev_p->usb_phy_config - 1][0] ;
} else if (i == 2) {
/* Start with the values that specify size */
dev_p->usb_pepcfg[i] =
pep_register_values
[dev_p->usb_phy_config - 1][1] ;
} else
dev_p->usb_pepcfg[i] = 0 ;
/* Adjust direction if it is in */
if (epstate[i] == cy_as_e_p_iso_in ||
epstate[i] == cy_as_e_p_in)
dev_p->usb_pepcfg[i] |= (1 << 6) ;
}
/* Configure the logical EP registers */
for (i = 0 ; i < 10 ; i++) {
int val ;
int epnum = end_point_map[i] ;
v = 0x10 ; /* PEP 1, Bulk Endpoint, EP not valid */
if (dev_p->usb_config[epnum].enabled) {
v |= (1 << 7) ; /* Enabled */
val = dev_p->usb_config[epnum].physical - 1 ;
cy_as_hal_assert(val >= 0 && val <= 3) ;
v |= (val << 5) ;
switch (dev_p->usb_config[epnum].type) {
case cy_as_usb_bulk:
val = 2 ;
break ;
case cy_as_usb_int:
val = 3 ;
break ;
case cy_as_usb_iso:
val = 1 ;
break ;
default:
cy_as_hal_assert(cy_false) ;
break ;
}
v |= (val << 3) ;
}
dev_p->usb_lepcfg[i] = v ;
}
}
cy_as_return_status_t
cy_as_usb_map_logical2_physical(cy_as_device *dev_p)
{
cy_as_return_status_t ret ;
/* Physical EPs 3 5 7 9 respectively in the array */
cy_as_physical_endpoint_state epstate[4] = {
cy_as_e_p_free, cy_as_e_p_free,
cy_as_e_p_free, cy_as_e_p_free } ;
/* Find the direction for the endpoints */
ret = find_endpoint_directions(dev_p, epstate) ;
if (ret != CY_AS_ERROR_SUCCESS)
return ret ;
/*
* now create the register settings based on the given
* assigned of logical E_ps to physical endpoints.
*/
create_register_settings(dev_p, epstate) ;
return ret ;
}
static uint16_t
get_max_dma_size(cy_as_device *dev_p, cy_as_end_point_number_t ep)
{
uint16_t size = dev_p->usb_config[ep].size ;
if (size == 0) {
switch (dev_p->usb_config[ep].type) {
case cy_as_usb_control:
size = 64 ;
break ;
case cy_as_usb_bulk:
size = cy_as_device_is_usb_high_speed(dev_p) ?
512 : 64 ;
break ;
case cy_as_usb_int:
size = cy_as_device_is_usb_high_speed(dev_p) ?
1024 : 64 ;
break ;
case cy_as_usb_iso:
size = cy_as_device_is_usb_high_speed(dev_p) ?
1024 : 1023 ;
break ;
}
}
return size ;
}
cy_as_return_status_t
cy_as_usb_set_dma_sizes(cy_as_device *dev_p)
{
cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
uint32_t i ;
for (i = 0 ; i < 10 ; i++) {
cy_as_usb_end_point_config *config_p =
&dev_p->usb_config[end_point_map[i]] ;
if (config_p->enabled) {
ret = cy_as_dma_set_max_dma_size(dev_p,
end_point_map[i],
get_max_dma_size(dev_p, end_point_map[i])) ;
if (ret != CY_AS_ERROR_SUCCESS)
break ;
}
}
return ret ;
}
cy_as_return_status_t
cy_as_usb_setup_dma(cy_as_device *dev_p)
{
cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS ;
uint32_t i ;
for (i = 0 ; i < 10 ; i++) {
cy_as_usb_end_point_config *config_p =
&dev_p->usb_config[end_point_map[i]] ;
if (config_p->enabled) {
/* Map the endpoint direction to the DMA direction */
cy_as_dma_direction dir = cy_as_direction_out ;
if (config_p->dir == cy_as_usb_in)
dir = cy_as_direction_in ;
ret = cy_as_dma_enable_end_point(dev_p,
end_point_map[i], cy_true, dir) ;
if (ret != CY_AS_ERROR_SUCCESS)
break ;
}
}
return ret ;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Cypress West Bridge API header file (cyashaldef.h)
## ===========================
## Copyright (C) 2010 Cypress Semiconductor
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor
## Boston, MA 02110-1301, USA.
## ===========================
*/
#ifndef _INCLUDED_CYASHALDEF_H_
#define _INCLUDED_CYASHALDEF_H_
/* Summary
* If set to TRUE, the basic numeric types are defined by the
* West Bridge API code
*
* Description
* The West Bridge API relies on some basic integral types to be
* defined. These types include uint8_t, int8_t, uint16_t,
* int16_t, uint32_t, and int32_t. If this macro is defined the
* West Bridge API will define these types based on some basic
* assumptions. If this value is set and the West Bridge API is
* used to set these types, the definition of these types must be
* examined to insure that they are appropriate for the given
* target architecture and compiler.
*
* Notes
* It is preferred that if the basic platform development
* environment defines these types that the CY_DEFINE_BASIC_TYPES
* macro be undefined and the appropriate target system header file
* be added to the file cyashaldef.h.
*/
#include <linux/types.h>
#if !defined(__doxygen__)
typedef int cy_bool ;
#define cy_true (1)
#define cy_false (0)
#endif
#endif /* _INCLUDED_CYASHALDEF_H_ */
/* Cypress Antioch HAL for OMAP KERNEL header file (cyashalomapkernel.h)
## ===========================
## Copyright (C) 2010 Cypress Semiconductor
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor
## Boston, MA 02110-1301, USA.
## ===========================
*/
/*
* This file contains the defintion of the hardware abstraction
* layer on OMAP3430 talking to the West Bridge Astoria device
*/
#ifndef _INCLUDED_CYASHALOMAP_KERNEL_H_
#define _INCLUDED_CYASHALOMAP_KERNEL_H_
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/string.h>
/* include does not seem to work
* moving for patch submission
#include <mach/gpmc.h>
*/
#include <linux/../../arch/arm/plat-omap/include/plat/gpmc.h>
typedef struct cy_as_hal_sleep_channel_t {
wait_queue_head_t wq ;
} cy_as_hal_sleep_channel ;
/* moved to staging location, eventual location
* considered is here
#include <mach/westbridge/cyashaldef.h>
#include <linux/westbridge/cyastypes.h>
#include <linux/westbridge/cyas_cplus_start.h>
*/
#include "../cyashaldef.h"
#include "../../../../../../../include/linux/westbridge/cyastypes.h"
#include "../../../../../../../include/linux/westbridge/cyas_cplus_start.h"
#include "cyasomapdev_kernel.h"
/*
* Below are the data structures that must be defined by the HAL layer
*/
/*
* The HAL layer must define a TAG for identifying a specific Astoria
* device in the system. In this case the tag is a void * which is
* really an OMAP device pointer
*/
typedef void *cy_as_hal_device_tag ;
/* This must be included after the CyAsHalDeviceTag type is defined */
/* moved to staging location, eventual location
* considered is here
* #include <linux/westbridge/cyashalcb.h>
*/
#include "../../../../../../../include/linux/westbridge/cyashalcb.h"
/*
* Below are the functions that communicate with the West Bridge
* device. These are system dependent and must be defined by
* the HAL layer for a given system.
*/
/*
* This function must be defined to write a register within the Antioch
* device. The addr value is the address of the register to write with
* respect to the base address of the Antioch device.
*/
void
cy_as_hal_write_register(cy_as_hal_device_tag tag,
uint16_t addr, uint16_t data) ;
/*
* This function must be defined to read a register from
* the west bridge device. The addr value is the address of
* the register to read with respect to the base address
* of the west bridge device.
*/
uint16_t
cy_as_hal_read_register(cy_as_hal_device_tag tag, uint16_t addr) ;
/*
* This function must be defined to transfer a block of data
* to the west bridge device. This function can use the burst write
* (DMA) capabilities of Antioch to do this, or it can just copy
* the data using writes.
*/
void
cy_as_hal_dma_setup_write(cy_as_hal_device_tag tag,
uint8_t ep, void *buf, uint32_t size, uint16_t maxsize) ;
/*
* This function must be defined to transfer a block of data
* from the Antioch device. This function can use the burst
* read (DMA) capabilities of Antioch to do this, or it can
* just copy the data using reads.
*/
void
cy_as_hal_dma_setup_read(cy_as_hal_device_tag tag, uint8_t ep,
void *buf, uint32_t size, uint16_t maxsize) ;
/*
* This function must be defined to cancel any pending DMA request.
*/
void
cy_as_hal_dma_cancel_request(cy_as_hal_device_tag tag, uint8_t ep) ;
/*
* This function must be defined to allow the Antioch API to
* register a callback function that is called when a DMA transfer
* is complete.
*/
void
cy_as_hal_dma_register_callback(cy_as_hal_device_tag tag,
cy_as_hal_dma_complete_callback cb) ;
/*
* This function must be defined to return the maximum size of DMA
* request that can be handled on the given endpoint. The return
* value should be the maximum size in bytes that the DMA module can
* handle.
*/
uint32_t
cy_as_hal_dma_max_request_size(cy_as_hal_device_tag tag,
cy_as_end_point_number_t ep) ;
/*
* This function must be defined to set the state of the WAKEUP pin
* on the Antioch device. Generally this is done via a GPIO of some
* type.
*/
cy_bool
cy_as_hal_set_wakeup_pin(cy_as_hal_device_tag tag, cy_bool state) ;
/*
* This function is called when the Antioch PLL loses lock, because
* of a problem in the supply voltage or the input clock.
*/
void
cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag) ;
/**********************************************************************
*
* Below are the functions that must be defined to provide the basic
* operating system services required by the API.
*
***********************************************************************/
/*
* This function is required by the API to allocate memory. This function
* is expected to work exactly like malloc().
*/
void *
cy_as_hal_alloc(uint32_t cnt) ;
/*
* This function is required by the API to free memory allocated with
* CyAsHalAlloc(). This function is expected to work exacly like free().
*/
void
cy_as_hal_free(void *mem_p) ;
/*
* This function is required by the API to allocate memory during a
* callback. This function must be able to provide storage at inturupt
* time.
*/
void *
cy_as_hal_c_b_alloc(uint32_t cnt) ;
/*
* This function is required by the API to free memory allocated with
* CyAsCBHalAlloc().
*/
void
cy_as_hal_c_b_free(void *ptr) ;
/*
* This function is required to set a block of memory to a specific
* value. This function is expected to work exactly like memset()
*/
void
cy_as_hal_mem_set(void *ptr, uint8_t value, uint32_t cnt) ;
/*
* This function is expected to create a sleep channel. The data
* structure that represents the sleep channel is given by the
* pointer in the argument.
*/
cy_bool
cy_as_hal_create_sleep_channel(cy_as_hal_sleep_channel *channel) ;
/*
* This function is expected to destroy a sleep channel. The data
* structure that represents the sleep channel is given by
* the pointer in the argument.
*/
cy_bool
cy_as_hal_destroy_sleep_channel(cy_as_hal_sleep_channel *channel) ;
cy_bool
cy_as_hal_sleep_on(cy_as_hal_sleep_channel *channel, uint32_t ms) ;
cy_bool
cy_as_hal_wake(cy_as_hal_sleep_channel *channel) ;
uint32_t
cy_as_hal_disable_interrupts(void) ;
void
cy_as_hal_enable_interrupts(uint32_t);
void
cy_as_hal_sleep150(void);
void
cy_as_hal_sleep(uint32_t ms);
cy_bool
cy_as_hal_is_polling(void);
void cy_as_hal_init_dev_registers(cy_as_hal_device_tag tag,
cy_bool is_standby_wakeup);
/*
* required only in spi mode
*/
cy_bool cy_as_hal_sync_device_clocks(cy_as_hal_device_tag tag);
void cy_as_hal_read_regs_before_standby(cy_as_hal_device_tag tag);
#ifndef NDEBUG
#define cy_as_hal_assert(cond) if (!(cond))\
printk(KERN_WARNING"assertion failed at %s:%d\n", __FILE__, __LINE__);
#else
#define cy_as_hal_assert(cond)
#endif
#define cy_as_hal_print_message printk
/* removable debug printks */
#ifndef WESTBRIDGE_NDEBUG
#define DBG_PRINT_ENABLED
#endif
/*#define MBOX_ACCESS_DBG_PRINT_ENABLED*/
#ifdef DBG_PRINT_ENABLED
/* Debug printing enabled */
#define DBGPRN(...) printk(__VA_ARGS__)
#define DBGPRN_FUNC_NAME printk("<1> %x:_func: %s\n", \
current->pid, __func__)
#else
/** NO DEBUG PRINTING **/
#define DBGPRN(...)
#define DBGPRN_FUNC_NAME
#endif
/*
CyAsMiscSetLogLevel(uint8_t level)
{
debug_level = level ;
}
#ifdef CY_AS_LOG_SUPPORT
void
cy_as_log_debug_message(int level, const char *str)
{
if (level <= debug_level)
cy_as_hal_print_message("log %d: %s\n", level, str) ;
}
*/
/*
* print buffer helper
*/
void cyashal_prn_buf(void *buf, uint16_t offset, int len);
/*
* These are the functions that are not part of the HAL layer,
* but are required to be called for this HAL.
*/
int start_o_m_a_p_kernel(const char *pgm,
cy_as_hal_device_tag *tag, cy_bool debug) ;
int stop_o_m_a_p_kernel(const char *pgm, cy_as_hal_device_tag tag) ;
int omap_start_intr(cy_as_hal_device_tag tag) ;
void cy_as_hal_set_ep_dma_mode(uint8_t ep, bool sg_xfer_enabled);
/* moved to staging location
#include <linux/westbridge/cyas_cplus_end.h>
*/
#include "../../../../../../../include/linux/westbridge/cyas_cplus_start.h"
#endif
/* Cypress Antioch OMAP KERNEL file (cyanomapdev_kernel.h)
## ===========================
## Copyright (C) 2010 Cypress Semiconductor
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor,
## Boston, MA 02110-1301, USA.
## ===========================
*/
#ifndef __CY_AS_OMAP_DEV_KERNEL_H__
#define __CY_AS_OMAP_DEV_KERNEL_H__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/completion.h>
/* include does not seem to work
* moving for patch submission
#include <mach/gpmc.h>
*/
#include <linux/../../arch/arm/plat-omap/include/plat/gpmc.h>
/*
* Constants
*/
#define CY_AS_OMAP_KERNEL_HAL_SIG (0x1441)
/*
* Data structures
*/
typedef struct cy_as_omap_dev_kernel {
/* This is the signature for this data structure */
unsigned int m_sig ;
/* Address base of Antioch Device */
void *m_addr_base;
/* This is a pointer to the next Antioch device in the system */
struct cy_as_omap_dev_kernel *m_next_p;
/* This is for thread sync */
struct completion thread_complete;
/* This is for thread to wait for interrupts */
cy_as_hal_sleep_channel thread_sc;
/* This is for thread to exit upon StopOmapKernel */
int thread_flag; /* set 1 to exit */
int dma_ch;
/* This is for dma sync */
struct completion dma_complete;
} cy_as_omap_dev_kernel;
#endif
/*[]*/
#
# West Bridge block driver configuration
#
config WESTBRIDGE_BLOCK_DRIVER
tristate "West Bridge Block Driver"
help
Include the West Bridge based block driver
#
# Makefile for the kernel westbridge block driver
#
ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG
endif
obj-$(CONFIG_WESTBRIDGE_BLOCK_DRIVER) += cyasblkdev.o
cyasblkdev-y := cyasblkdev_block.o cyasblkdev_queue.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# West Bridge block driver configuration
#
config WESTBRIDGE_DEVICE_DRIVER
tristate "West Bridge Device Driver"
help
Include the West Bridge based device driver
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# West Bridge gadget driver configuration
#
config WESTBRIDGE_GADGET_DRIVER
tristate "West Bridge Gadget Driver"
help
Include the West Bridge based gadget peripheral controller driver
#
# Makefile for the kernel westbridge hal
#
ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG
endif
obj-$(CONFIG_WESTBRIDGE_GADGET_DRIVER) += cyasgadgetctrl.o
cyasgadgetctrl-y := cyasgadget.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment