aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/westbridge/astoria/device
diff options
context:
space:
mode:
authorDavid Cross <david.cross@cypress.com>2010-08-06 17:29:03 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-30 17:20:53 -0700
commit81eb669b9516b85a2acf4c342db2322bed37d70c (patch)
treed5339b0c1d371b6bfeb0984678ca03054f3a8339 /drivers/staging/westbridge/astoria/device
parent760ffce8ab13510bb1bf0af22f88df3f855bfa6b (diff)
downloadkernel_samsung_smdk4412-81eb669b9516b85a2acf4c342db2322bed37d70c.zip
kernel_samsung_smdk4412-81eb669b9516b85a2acf4c342db2322bed37d70c.tar.gz
kernel_samsung_smdk4412-81eb669b9516b85a2acf4c342db2322bed37d70c.tar.bz2
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: David Cross <david.cross@cypress.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/westbridge/astoria/device')
-rw-r--r--drivers/staging/westbridge/astoria/device/Kconfig9
-rw-r--r--drivers/staging/westbridge/astoria/device/Makefile23
-rw-r--r--drivers/staging/westbridge/astoria/device/cyandevice_export.h132
-rw-r--r--drivers/staging/westbridge/astoria/device/cyasdevice.c394
4 files changed, 558 insertions, 0 deletions
diff --git a/drivers/staging/westbridge/astoria/device/Kconfig b/drivers/staging/westbridge/astoria/device/Kconfig
new file mode 100644
index 0000000..cc99658
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/Kconfig
@@ -0,0 +1,9 @@
+#
+# West Bridge block driver configuration
+#
+
+config WESTBRIDGE_DEVICE_DRIVER
+ tristate "West Bridge Device Driver"
+ help
+ Include the West Bridge based device driver
+
diff --git a/drivers/staging/westbridge/astoria/device/Makefile b/drivers/staging/westbridge/astoria/device/Makefile
new file mode 100644
index 0000000..7af8b5b
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/Makefile
@@ -0,0 +1,23 @@
+#
+# Makefile for the kernel westbridge device driver
+#
+
+ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y)
+ EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG
+endif
+
+obj-$(CONFIG_WESTBRIDGE_DEVICE_DRIVER) += cyasdev.o
+
+
+ifeq ($(CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL),y)
+#moved for staging compatbility
+#cyasdev-y := ../../../arch/arm/mach-omap2/cyashalomap_kernel.o cyasdevice.o
+cyasdev-y := ../arch/arm/mach-omap2/cyashalomap_kernel.o cyasdevice.o \
+ ../api/src/cyasdma.o ../api/src/cyasintr.o ../api/src/cyaslep2pep.o \
+ ../api/src/cyaslowlevel.o ../api/src/cyasmisc.o ../api/src/cyasmtp.o \
+ ../api/src/cyasstorage.o ../api/src/cyasusb.o
+
+else
+# should not get here, need to be built with some hal
+cyasdev-y := cyasdevice.o
+endif
diff --git a/drivers/staging/westbridge/astoria/device/cyandevice_export.h b/drivers/staging/westbridge/astoria/device/cyandevice_export.h
new file mode 100644
index 0000000..fc9dee9
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/cyandevice_export.h
@@ -0,0 +1,132 @@
+/*
+## cyandevice_export.h - Linux Antioch device driver file
+##
+## ===========================
+## 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.
+## ===========================
+*/
+
+/*
+ * Export Misc APIs that can be used from the other driver modules.
+ * The APIs to create a device handle and download firmware are not exported
+ * because they are expected to be used only by this kernel module.
+ */
+EXPORT_SYMBOL(cy_as_misc_get_firmware_version) ;
+EXPORT_SYMBOL(cy_as_misc_read_m_c_u_register) ;
+EXPORT_SYMBOL(cy_as_misc_reset) ;
+EXPORT_SYMBOL(cy_as_misc_acquire_resource) ;
+EXPORT_SYMBOL(cy_as_misc_release_resource) ;
+EXPORT_SYMBOL(cy_as_misc_enter_standby) ;
+EXPORT_SYMBOL(cy_as_misc_leave_standby) ;
+EXPORT_SYMBOL(cy_as_misc_enter_suspend) ;
+EXPORT_SYMBOL(cy_as_misc_leave_suspend) ;
+EXPORT_SYMBOL(cy_as_misc_storage_changed) ;
+EXPORT_SYMBOL(cy_as_misc_heart_beat_control) ;
+EXPORT_SYMBOL(cy_as_misc_get_gpio_value) ;
+EXPORT_SYMBOL(cy_as_misc_set_gpio_value) ;
+EXPORT_SYMBOL(cy_as_misc_set_low_speed_sd_freq) ;
+EXPORT_SYMBOL(cy_as_misc_set_high_speed_sd_freq) ;
+
+/*
+ * Export the USB APIs that can be used by the dependent kernel modules.
+ */
+EXPORT_SYMBOL(cy_as_usb_set_end_point_config) ;
+EXPORT_SYMBOL(cy_as_usb_read_data_async) ;
+EXPORT_SYMBOL(cy_as_usb_write_data_async) ;
+EXPORT_SYMBOL(cy_as_usb_cancel_async) ;
+EXPORT_SYMBOL(cy_as_usb_set_stall) ;
+EXPORT_SYMBOL(cy_as_usb_clear_stall) ;
+EXPORT_SYMBOL(cy_as_usb_connect) ;
+EXPORT_SYMBOL(cy_as_usb_disconnect) ;
+EXPORT_SYMBOL(cy_as_usb_start) ;
+EXPORT_SYMBOL(cy_as_usb_stop) ;
+EXPORT_SYMBOL(cy_as_usb_set_enum_config) ;
+EXPORT_SYMBOL(cy_as_usb_get_enum_config) ;
+EXPORT_SYMBOL(cy_as_usb_set_physical_configuration) ;
+EXPORT_SYMBOL(cy_as_usb_register_callback) ;
+EXPORT_SYMBOL(cy_as_usb_commit_config) ;
+EXPORT_SYMBOL(cy_as_usb_set_descriptor) ;
+EXPORT_SYMBOL(cy_as_usb_clear_descriptors) ;
+EXPORT_SYMBOL(cy_as_usb_get_descriptor) ;
+EXPORT_SYMBOL(cy_as_usb_get_end_point_config) ;
+EXPORT_SYMBOL(cy_as_usb_read_data) ;
+EXPORT_SYMBOL(cy_as_usb_write_data) ;
+EXPORT_SYMBOL(cy_as_usb_get_stall) ;
+EXPORT_SYMBOL(cy_as_usb_set_nak) ;
+EXPORT_SYMBOL(cy_as_usb_clear_nak) ;
+EXPORT_SYMBOL(cy_as_usb_get_nak) ;
+EXPORT_SYMBOL(cy_as_usb_signal_remote_wakeup) ;
+EXPORT_SYMBOL(cy_as_usb_set_m_s_report_threshold) ;
+EXPORT_SYMBOL(cy_as_usb_select_m_s_partitions) ;
+
+/*
+ * Export all Storage APIs that can be used by dependent kernel modules.
+ */
+EXPORT_SYMBOL(cy_as_storage_start) ;
+EXPORT_SYMBOL(cy_as_storage_stop) ;
+EXPORT_SYMBOL(cy_as_storage_register_callback) ;
+EXPORT_SYMBOL(cy_as_storage_query_bus) ;
+EXPORT_SYMBOL(cy_as_storage_query_media) ;
+EXPORT_SYMBOL(cy_as_storage_query_device) ;
+EXPORT_SYMBOL(cy_as_storage_query_unit) ;
+EXPORT_SYMBOL(cy_as_storage_device_control) ;
+EXPORT_SYMBOL(cy_as_storage_claim) ;
+EXPORT_SYMBOL(cy_as_storage_release) ;
+EXPORT_SYMBOL(cy_as_storage_read) ;
+EXPORT_SYMBOL(cy_as_storage_write) ;
+EXPORT_SYMBOL(cy_as_storage_read_async) ;
+EXPORT_SYMBOL(cy_as_storage_write_async) ;
+EXPORT_SYMBOL(cy_as_storage_cancel_async) ;
+EXPORT_SYMBOL(cy_as_storage_sd_register_read) ;
+EXPORT_SYMBOL(cy_as_storage_create_p_partition) ;
+EXPORT_SYMBOL(cy_as_storage_remove_p_partition) ;
+EXPORT_SYMBOL(cy_as_storage_get_transfer_amount) ;
+EXPORT_SYMBOL(cy_as_storage_erase) ;
+
+EXPORT_SYMBOL(cy_as_sdio_query_card);
+EXPORT_SYMBOL(cy_as_sdio_init_function);
+EXPORT_SYMBOL(cy_as_sdio_set_blocksize);
+EXPORT_SYMBOL(cy_as_sdio_direct_read);
+EXPORT_SYMBOL(cy_as_sdio_direct_write);
+EXPORT_SYMBOL(cy_as_sdio_extended_read);
+EXPORT_SYMBOL(cy_as_sdio_extended_write);
+
+EXPORT_SYMBOL(cy_as_hal_alloc) ;
+EXPORT_SYMBOL(cy_as_hal_free) ;
+EXPORT_SYMBOL(cy_as_hal_sleep) ;
+EXPORT_SYMBOL(cy_as_hal_create_sleep_channel) ;
+EXPORT_SYMBOL(cy_as_hal_destroy_sleep_channel) ;
+EXPORT_SYMBOL(cy_as_hal_sleep_on) ;
+EXPORT_SYMBOL(cy_as_hal_wake) ;
+EXPORT_SYMBOL(cy_as_hal_mem_set);
+
+EXPORT_SYMBOL(cy_as_mtp_storage_only_start);
+EXPORT_SYMBOL(cy_as_mtp_storage_only_stop);
+EXPORT_SYMBOL(cy_as_mtp_start);
+EXPORT_SYMBOL(cy_as_mtp_init_send_object);
+EXPORT_SYMBOL(cy_as_mtp_init_get_object);
+EXPORT_SYMBOL(cy_as_mtp_cancel_send_object);
+EXPORT_SYMBOL(cy_as_mtp_cancel_get_object);
+
+#ifdef __CY_ASTORIA_SCM_KERNEL_HAL__
+/* Functions in the SCM kernel HAL implementation only. */
+EXPORT_SYMBOL(cy_as_hal_enable_scatter_list) ;
+EXPORT_SYMBOL(cy_as_hal_disable_scatter_list) ;
+#endif
+
+/*[]*/
diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice.c b/drivers/staging/westbridge/astoria/device/cyasdevice.c
new file mode 100644
index 0000000..cd0f7cb
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/device/cyasdevice.c
@@ -0,0 +1,394 @@
+/*
+## cyandevice.c - Linux Antioch device driver file
+## ===========================
+## 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 <linux/delay.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+#include <linux/scatterlist.h>
+#include <linux/err.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* moved for staging location
+ * update/patch submission
+#include <linux/westbridge/cyastoria.h>
+#include <linux/westbridge/cyashal.h>
+#include <linux/westbridge/cyasregs.h>
+*/
+
+#include "../include/linux/westbridge/cyastoria.h"
+#include "../include/linux/westbridge/cyashal.h"
+#include "../include/linux/westbridge/cyasregs.h"
+
+/* API exports include file */
+#include "cyandevice_export.h"
+
+typedef struct cyasdevice {
+ /* Handle to the Antioch device */
+ cy_as_device_handle dev_handle;
+ /* Handle to the HAL */
+ cy_as_hal_device_tag hal_tag;
+} cyasdevice ;
+
+/* global ptr to astoria device */
+static cyasdevice *cy_as_device_controller ;
+int cy_as_device_init_done;
+const char *dev_handle_name = "cy_astoria_dev_handle" ;
+
+#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+extern void cy_as_hal_config_c_s_mux(void);
+#endif
+
+static void cyasdevice_deinit(cyasdevice *cy_as_dev)
+{
+ cy_as_hal_print_message("<1>_cy_as_device deinitialize called\n") ;
+ if (!cy_as_dev) {
+ cy_as_hal_print_message("<1>_cy_as_device_deinit: "
+ "device handle %x is invalid\n", (uint32_t)cy_as_dev) ;
+ return ;
+ }
+
+ /* stop west_brige */
+ if (cy_as_dev->dev_handle) {
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "cy_as_misc_destroy_device called\n") ;
+ if (cy_as_misc_destroy_device(cy_as_dev->dev_handle) !=
+ CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: destroying failed\n");
+ }
+ }
+
+ if (cy_as_dev->hal_tag) {
+
+ #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ if (stop_o_m_a_p_kernel(dev_handle_name,
+ cy_as_dev->hal_tag) != 0)
+ cy_as_hal_print_message("<1>_cy_as_device: stopping "
+ "OMAP kernel HAL failed\n");
+
+ #endif
+ }
+ cy_as_hal_print_message("<1>_cy_as_device:HAL layer stopped\n") ;
+
+ kfree(cy_as_dev) ;
+ cy_as_device_controller = NULL ;
+ cy_as_hal_print_message("<1>_cy_as_device: deinitialized\n") ;
+}
+
+/*called from src/cyasmisc.c:MyMiscCallback() as a func
+ * pointer [dev_p->misc_event_cb] which was previously
+ * registered by CyAsLLRegisterRequestCallback(...,
+ * MyMiscCallback) ; called from CyAsMiscConfigureDevice()
+ * which is in turn called from cyasdevice_initialize() in
+ * this src
+ */
+static void cy_misc_callback(cy_as_device_handle h,
+ cy_as_misc_event_type evtype, void *evdata)
+{
+ (void)h ;
+ (void)evdata ;
+
+ switch (evtype) {
+ case cy_as_event_misc_initialized:
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "initialization done callback triggered\n") ;
+ cy_as_device_init_done = 1 ;
+ break ;
+
+ case cy_as_event_misc_awake:
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "cy_as_event_misc_awake event callback triggered\n") ;
+ cy_as_device_init_done = 1 ;
+ break ;
+ default:
+ break ;
+ }
+}
+
+/* reset astoria and reinit all regs */
+ #define PNAND_REG_CFG_INIT_VAL 0x0000
+void hal_reset(cy_as_hal_device_tag tag)
+{
+ cy_as_hal_print_message("<1> send soft hard rst: "
+ "MEM_RST_CTRL_REG_HARD...\n");
+ cy_as_hal_write_register(tag, CY_AS_MEM_RST_CTRL_REG,
+ CY_AS_MEM_RST_CTRL_REG_HARD) ;
+ mdelay(60);
+
+ cy_as_hal_print_message("<1> after RST: si_rev_REG:%x, "
+ "PNANDCFG_reg:%x\n",
+ cy_as_hal_read_register(tag, CY_AS_MEM_CM_WB_CFG_ID),
+ cy_as_hal_read_register(tag, CY_AS_MEM_PNAND_CFG)
+ );
+
+ /* set it to LBD */
+ cy_as_hal_write_register(tag, CY_AS_MEM_PNAND_CFG,
+ PNAND_REG_CFG_INIT_VAL) ;
+}
+EXPORT_SYMBOL(hal_reset);
+
+
+/* below structures and functions primarily
+ * implemented for firmware loading */
+static struct platform_device *westbridge_pd;
+
+static int __devinit wb_probe(struct platform_device *devptr)
+{
+ cy_as_hal_print_message("%s called\n", __func__);
+ return 0;
+}
+
+static int __devexit wb_remove(struct platform_device *devptr)
+{
+ cy_as_hal_print_message("%s called\n", __func__);
+ return 0;
+}
+
+static struct platform_driver west_bridge_driver = {
+ .probe = wb_probe,
+ .remove = __devexit_p(wb_remove),
+ .driver = {
+ .name = "west_bridge_dev"},
+};
+
+/* west bridge device driver main init */
+static int cyasdevice_initialize(void)
+{
+ cyasdevice *cy_as_dev = 0 ;
+ int ret = 0 ;
+ int retval = 0 ;
+ cy_as_device_config config ;
+ cy_as_hal_sleep_channel channel ;
+ cy_as_get_firmware_version_data ver_data = {0};
+ const char *str = "" ;
+ int spin_lim;
+ const struct firmware *fw_entry;
+
+ cy_as_device_init_done = 0;
+
+ cy_as_misc_set_log_level(8);
+
+ cy_as_hal_print_message("<1>_cy_as_device initialize called\n") ;
+
+ if (cy_as_device_controller != 0) {
+ cy_as_hal_print_message("<1>_cy_as_device: the device "
+ "has already been initilaized. ignoring\n") ;
+ return -EBUSY ;
+ }
+
+ /* cy_as_dev = CyAsHalAlloc (sizeof(cyasdevice), SLAB_KERNEL); */
+ cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice));
+ if (cy_as_dev == NULL) {
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "memmory allocation failed\n") ;
+ return -ENOMEM;
+ }
+ memset(cy_as_dev, 0, sizeof(cyasdevice));
+
+
+ /* Init the HAL & CyAsDeviceHandle */
+
+ #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ /* start OMAP HAL init instsnce */
+
+ if (!start_o_m_a_p_kernel(dev_handle_name,
+ &(cy_as_dev->hal_tag), cy_false)) {
+
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: start OMAP34xx HAL failed\n") ;
+ goto done;
+ }
+ #endif
+
+ /* Now create the device */
+ if (cy_as_misc_create_device(&(cy_as_dev->dev_handle),
+ cy_as_dev->hal_tag) != CY_AS_ERROR_SUCCESS) {
+
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: create device failed\n") ;
+ goto done ;
+ }
+
+ memset(&config, 0, sizeof(config));
+ config.dmaintr = cy_true;
+
+ ret = cy_as_misc_configure_device(cy_as_dev->dev_handle, &config) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+
+ cy_as_hal_print_message(
+ "<1>_cy_as_device: configure device "
+ "failed. reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ ret = cy_as_misc_register_callback(cy_as_dev->dev_handle,
+ cy_misc_callback) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_device: "
+ "cy_as_misc_register_callback failed. "
+ "reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ ret = platform_driver_register(&west_bridge_driver);
+ if (unlikely(ret < 0))
+ return ret;
+ westbridge_pd = platform_device_register_simple(
+ "west_bridge_dev", -1, NULL, 0);
+
+ if (IS_ERR(westbridge_pd)) {
+ platform_driver_unregister(&west_bridge_driver);
+ return PTR_ERR(westbridge_pd);
+ }
+ /* Load the firmware */
+ ret = request_firmware(&fw_entry,
+ "west bridge fw", &westbridge_pd->dev);
+ if (ret) {
+ cy_as_hal_print_message("cy_as_device: "
+ "request_firmware failed return val = %d\n", ret);
+ } else {
+ cy_as_hal_print_message("cy_as_device: "
+ "got the firmware %d size=0x%x\n", ret, fw_entry->size);
+
+ ret = cy_as_misc_download_firmware(
+ cy_as_dev->dev_handle,
+ fw_entry->data,
+ fw_entry->size ,
+ 0, 0) ;
+ }
+
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_device: cannot download "
+ "firmware. reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ /* spin until the device init is completed */
+ /* 50 -MAX wait time for the FW load & init
+ * to complete is 5sec*/
+ spin_lim = 50;
+
+ cy_as_hal_create_sleep_channel(&channel) ;
+ while (!cy_as_device_init_done) {
+
+ cy_as_hal_sleep_on(&channel, 100) ;
+
+ if (spin_lim-- <= 0) {
+ cy_as_hal_print_message(
+ "<1>\n_e_r_r_o_r!: "
+ "wait for FW init has timed out !!!");
+ break;
+ }
+ }
+ cy_as_hal_destroy_sleep_channel(&channel) ;
+
+ if (spin_lim > 0)
+ cy_as_hal_print_message(
+ "cy_as_device: astoria firmware is loaded\n") ;
+
+ ret = cy_as_misc_get_firmware_version(cy_as_dev->dev_handle,
+ &ver_data, 0, 0) ;
+ if (ret != CY_AS_ERROR_SUCCESS) {
+ cy_as_hal_print_message("<1>_cy_as_device: cannot get firmware "
+ "version. reason code: %d\n", ret) ;
+ goto done;
+ }
+
+ if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x06))
+ str = "nand and SD/MMC." ;
+ else if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x08))
+ str = "nand and CEATA." ;
+ else if (ver_data.media_type & 0x01)
+ str = "nand." ;
+ else if (ver_data.media_type & 0x08)
+ str = "CEATA." ;
+ else
+ str = "SD/MMC." ;
+
+ cy_as_hal_print_message("<1> cy_as_device:_firmware version: %s "
+ "major=%d minor=%d build=%d,\n_media types supported:%s\n",
+ ((ver_data.is_debug_mode) ? "debug" : "release"),
+ ver_data.major, ver_data.minor, ver_data.build, str) ;
+
+ /* done now */
+ cy_as_device_controller = cy_as_dev ;
+
+ return 0 ;
+
+done:
+ if (cy_as_dev)
+ cyasdevice_deinit(cy_as_dev) ;
+
+ return -EINVAL ;
+}
+
+cy_as_device_handle cyasdevice_getdevhandle(void)
+{
+ if (cy_as_device_controller) {
+ #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
+ cy_as_hal_config_c_s_mux();
+ #endif
+
+ return cy_as_device_controller->dev_handle ;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(cyasdevice_getdevhandle) ;
+
+cy_as_hal_device_tag cyasdevice_gethaltag(void)
+{
+ if (cy_as_device_controller)
+ return (cy_as_hal_device_tag)
+ cy_as_device_controller->hal_tag ;
+
+ return NULL;
+}
+EXPORT_SYMBOL(cyasdevice_gethaltag) ;
+
+
+/*init Westbridge device driver **/
+static int __init cyasdevice_init(void)
+{
+ if (cyasdevice_initialize() != 0)
+ return ENODEV;
+
+ return 0 ;
+}
+
+
+static void __exit cyasdevice_cleanup(void)
+{
+
+ cyasdevice_deinit(cy_as_device_controller) ;
+}
+
+
+MODULE_DESCRIPTION("west bridge device driver");
+MODULE_AUTHOR("cypress semiconductor");
+MODULE_LICENSE("GPL");
+
+module_init(cyasdevice_init);
+module_exit(cyasdevice_cleanup);
+
+/*[]*/