staging: csr: remove sdioemb/
Nothing in the subdirectory is being used, so remove it, and the sdio_emb.c file which also isn't being built. Cc: Mikko Virkkilä <mikko.virkkila@bluegiga.com> Cc: Lauri Hintsala <Lauri.Hintsala@bluegiga.com> Cc: Riku Mettälä <riku.mettala@bluegiga.com> Cc: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
db03f1d2cb
commit
22c45f0b35
|
@ -1,891 +0,0 @@
|
|||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
* FILE: sdio_emb.c
|
||||
*
|
||||
* PURPOSE: Driver instantiation and deletion for SDIO on Linux.
|
||||
*
|
||||
* This file brings together the SDIO bus interface, the UniFi
|
||||
* driver core and the Linux net_device stack.
|
||||
*
|
||||
* Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "csr_wifi_hip_unifi.h"
|
||||
#include "unifi_priv.h"
|
||||
|
||||
#include "sdioemb/sdio_api.h"
|
||||
|
||||
/* The function driver context, i.e the UniFi Driver */
|
||||
static CsrSdioFunctionDriver *sdio_func_drv;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr);
|
||||
#endif
|
||||
|
||||
/* The Android wakelock is here for completeness. Typically the MMC driver is used
|
||||
* instead of sdioemb, but sdioemb may be used for CSPI.
|
||||
*/
|
||||
#ifdef ANDROID_BUILD
|
||||
struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
|
||||
#endif
|
||||
|
||||
/* sdioemb driver uses POSIX error codes */
|
||||
static CsrResult
|
||||
ConvertSdioToCsrSdioResult(int r)
|
||||
{
|
||||
CsrResult csrResult = CSR_RESULT_FAILURE;
|
||||
|
||||
switch (r) {
|
||||
case 0:
|
||||
csrResult = CSR_RESULT_SUCCESS;
|
||||
break;
|
||||
case -EIO:
|
||||
csrResult = CSR_SDIO_RESULT_CRC_ERROR;
|
||||
break;
|
||||
/* Timeout errors */
|
||||
case -ETIMEDOUT:
|
||||
case -EBUSY:
|
||||
csrResult = CSR_SDIO_RESULT_TIMEOUT;
|
||||
break;
|
||||
case -ENODEV:
|
||||
case -ENOMEDIUM:
|
||||
csrResult = CSR_SDIO_RESULT_NO_DEVICE;
|
||||
break;
|
||||
case -EINVAL:
|
||||
csrResult = CSR_SDIO_RESULT_INVALID_VALUE;
|
||||
break;
|
||||
case -ENOMEM:
|
||||
case -ENOSYS:
|
||||
case -EILSEQ:
|
||||
case -ERANGE:
|
||||
case -ENXIO:
|
||||
csrResult = CSR_RESULT_FAILURE;
|
||||
break;
|
||||
default:
|
||||
unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r);
|
||||
break;
|
||||
}
|
||||
|
||||
return csrResult;
|
||||
}
|
||||
|
||||
|
||||
CsrResult
|
||||
CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int err;
|
||||
err = sdioemb_read8(fdev, address, data);
|
||||
if (err) {
|
||||
return ConvertSdioToCsrSdioResult(err);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioRead8() */
|
||||
|
||||
CsrResult
|
||||
CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int err;
|
||||
err = sdioemb_write8(fdev, address, data);
|
||||
if (err) {
|
||||
return ConvertSdioToCsrSdioResult(err);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioWrite8() */
|
||||
|
||||
CsrResult
|
||||
CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
r = sdioemb_read16(fdev, address, data);
|
||||
if (r) {
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioRead16() */
|
||||
|
||||
CsrResult
|
||||
CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
r = sdioemb_write16(fdev, address, data);
|
||||
if (r) {
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioWrite16() */
|
||||
|
||||
|
||||
CsrResult
|
||||
CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int err;
|
||||
err = sdioemb_f0_read8(fdev, address, data);
|
||||
if (err) {
|
||||
return ConvertSdioToCsrSdioResult(err);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioF0Read8() */
|
||||
|
||||
|
||||
CsrResult
|
||||
CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int err;
|
||||
err = sdioemb_f0_write8(fdev, address, data);
|
||||
if (err) {
|
||||
return ConvertSdioToCsrSdioResult(err);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioF0Write8() */
|
||||
|
||||
CsrResult
|
||||
CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int err;
|
||||
err = sdioemb_read(fdev, address, data, length);
|
||||
if (err) {
|
||||
return ConvertSdioToCsrSdioResult(err);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioRead() */
|
||||
|
||||
CsrResult
|
||||
CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int err;
|
||||
err = sdioemb_write(fdev, address, data, length);
|
||||
if (err) {
|
||||
return ConvertSdioToCsrSdioResult(err);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioWrite() */
|
||||
|
||||
|
||||
CsrResult
|
||||
CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r = 0;
|
||||
|
||||
/* Module parameter overrides */
|
||||
if (sdio_block_size > -1) {
|
||||
blockSize = sdio_block_size;
|
||||
}
|
||||
|
||||
unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n",
|
||||
blockSize);
|
||||
|
||||
r = sdioemb_set_block_size(fdev, blockSize);
|
||||
if (r) {
|
||||
unifi_error(NULL, "Error %d setting block size\n", r);
|
||||
}
|
||||
|
||||
/* Determine the achieved block size to report to the core */
|
||||
function->blockSize = fdev->blocksize;
|
||||
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
} /* CsrSdioBlockSizeSet() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioMaxBusClockFrequencySet
|
||||
*
|
||||
* Set the maximum SDIO bus clock speed to use.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
* maxFrequency maximum clock speed in Hz
|
||||
*
|
||||
* Returns:
|
||||
* an error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
CsrResult
|
||||
CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
CsrUint32 max_khz = maxFrequency/1000;
|
||||
|
||||
if (!max_khz || max_khz > sdio_clock) {
|
||||
max_khz = sdio_clock;
|
||||
}
|
||||
unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", max_khz);
|
||||
sdioemb_set_max_bus_freq(fdev, 1000 * max_khz);
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioMaxBusClockFrequencySet() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioInterruptEnable
|
||||
* CsrSdioInterruptDisable
|
||||
*
|
||||
* Enable or disable the SDIO interrupt.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success or a UniFi driver error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
CsrResult
|
||||
CsrSdioInterruptEnable(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
r = sdioemb_interrupt_enable(fdev);
|
||||
if (r) {
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioInterruptEnable() */
|
||||
|
||||
CsrResult
|
||||
CsrSdioInterruptDisable(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
r = sdioemb_interrupt_disable(fdev);
|
||||
if (r) {
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioInterruptDisable() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioInterruptAcknowledge
|
||||
*
|
||||
* Acknowledge an SDIO interrupt.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success or a UniFi driver error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
void CsrSdioInterruptAcknowledge(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
|
||||
sdioemb_interrupt_acknowledge(fdev);
|
||||
} /* CsrSdioInterruptAcknowledge() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioFunctionEnable
|
||||
*
|
||||
* Enable i/o on this function.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* UniFi driver error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
CsrResult
|
||||
CsrSdioFunctionEnable(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
/* Enable UniFi function (the 802.11 part). */
|
||||
r = sdioemb_enable_function(fdev);
|
||||
if (r) {
|
||||
unifi_error(NULL, "Failed to enable SDIO function %d\n", fdev->function);
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioFunctionEnable() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioFunctionDisable
|
||||
*
|
||||
* Disable i/o on this function.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* UniFi driver error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
CsrResult
|
||||
CsrSdioFunctionDisable(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
/* Disable UniFi function (the 802.11 part). */
|
||||
r = sdioemb_disable_function(fdev);
|
||||
if (r) {
|
||||
unifi_error(NULL, "Failed to disable SDIO function %d\n", fdev->function);
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioFunctionDisable() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioFunctionActive
|
||||
*
|
||||
* No-op as the bus goes to an active state at the start of every
|
||||
* command.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
CsrSdioFunctionActive(CsrSdioFunction *function)
|
||||
{
|
||||
} /* CsrSdioFunctionActive() */
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioFunctionIdle
|
||||
*
|
||||
* Set the function as idle.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
CsrSdioFunctionIdle(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
|
||||
sdioemb_idle_function(fdev);
|
||||
} /* CsrSdioFunctionIdle() */
|
||||
|
||||
|
||||
CsrResult
|
||||
CsrSdioPowerOn(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
|
||||
if (disable_power_control != 1) {
|
||||
sdioemb_power_on(fdev);
|
||||
}
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioPowerOn() */
|
||||
|
||||
void
|
||||
CsrSdioPowerOff(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
if (disable_power_control != 1) {
|
||||
sdioemb_power_off(fdev);
|
||||
}
|
||||
} /* CsrSdioPowerOff() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioHardReset
|
||||
*
|
||||
* Hard Resets UniFi is possible.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* 1 if the SDIO driver is not capable of doing a hard reset.
|
||||
* 0 if a hard reset was successfully performed.
|
||||
* -CSR_EIO if an I/O error occured while re-initializing the card.
|
||||
* This is a fatal, non-recoverable error.
|
||||
* -CSR_ENODEV if the card is no longer present.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
CsrResult
|
||||
CsrSdioHardReset(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
int r;
|
||||
|
||||
/* Hard reset can be disabled by a module parameter */
|
||||
r = 1;
|
||||
if (disable_hw_reset != 1) {
|
||||
r = sdioemb_hard_reset(fdev); /* may return 1 if can't reset */
|
||||
if (r < 0) {
|
||||
return ConvertSdioToCsrSdioResult(r); /* fatal error */
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the SDIO bus width after a hard reset */
|
||||
if (buswidth == 1) {
|
||||
unifi_info(NULL, "Setting SDIO bus width to 1\n");
|
||||
sdioemb_set_bus_width(fdev, buswidth);
|
||||
} else if (buswidth == 4) {
|
||||
unifi_info(NULL, "Setting SDIO bus width to 4\n");
|
||||
sdioemb_set_bus_width(fdev, buswidth);
|
||||
}
|
||||
|
||||
if(r == 1)
|
||||
{
|
||||
return CSR_SDIO_RESULT_NOT_RESET;
|
||||
}
|
||||
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
|
||||
} /* CsrSdioHardReset() */
|
||||
|
||||
|
||||
int csr_sdio_linux_remove_irq(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
|
||||
return sdioemb_interrupt_disable(fdev);
|
||||
}
|
||||
|
||||
int csr_sdio_linux_install_irq(CsrSdioFunction *function)
|
||||
{
|
||||
struct sdioemb_dev *fdev = (struct sdioemb_dev *)function->priv;
|
||||
|
||||
return sdioemb_interrupt_enable(fdev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_glue_sdio_int_handler
|
||||
* Card interrupt callback.
|
||||
*
|
||||
* Arguments:
|
||||
* fdev SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
uf_glue_sdio_int_handler(struct sdioemb_dev *fdev)
|
||||
{
|
||||
CsrSdioFunction *sdio_ctx = fdev->drv_data;
|
||||
CsrSdioInterruptDsrCallback func_dsr_callback;
|
||||
|
||||
/* If the function driver has registered a handler, call it */
|
||||
if (sdio_func_drv && sdio_func_drv->intr) {
|
||||
/* The function driver may return a DSR. */
|
||||
func_dsr_callback = sdio_func_drv->intr(sdio_ctx);
|
||||
/* If it did return a DSR handle, call it */
|
||||
if (func_dsr_callback) {
|
||||
func_dsr_callback(sdio_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
/*
|
||||
* Power Management notifier
|
||||
*/
|
||||
struct uf_sdio_emb_pm_notifier
|
||||
{
|
||||
struct list_head list;
|
||||
|
||||
CsrSdioFunction *sdio_ctx;
|
||||
struct notifier_block pm_notifier;
|
||||
};
|
||||
|
||||
/* PM notifier list head */
|
||||
static struct uf_sdio_emb_pm_notifier uf_sdio_emb_pm_notifiers = {
|
||||
.sdio_ctx = NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_sdio_emb_register_pm_notifier
|
||||
* uf_sdio_emb_unregister_pm_notifier
|
||||
*
|
||||
* Register/unregister for power management events. A list is used to
|
||||
* allow multiple card instances to be supported.
|
||||
*
|
||||
* Arguments:
|
||||
* sdio_ctx - CSR SDIO context to associate PM notifier to
|
||||
*
|
||||
* Returns:
|
||||
* Register function returns NULL on error
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static struct uf_sdio_emb_pm_notifier *
|
||||
uf_sdio_emb_register_pm_notifier(CsrSdioFunction *sdio_ctx)
|
||||
{
|
||||
/* Allocate notifier context for this card instance */
|
||||
struct uf_sdio_emb_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_emb_pm_notifier), GFP_KERNEL);
|
||||
|
||||
if (notifier_ctx)
|
||||
{
|
||||
notifier_ctx->sdio_ctx = sdio_ctx;
|
||||
notifier_ctx->pm_notifier.notifier_call = uf_sdio_emb_power_event;
|
||||
|
||||
list_add(¬ifier_ctx->list, &uf_sdio_emb_pm_notifiers.list);
|
||||
|
||||
if (register_pm_notifier(¬ifier_ctx->pm_notifier)) {
|
||||
printk(KERN_ERR "unifi: register_pm_notifier failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
return notifier_ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
uf_sdio_emb_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
|
||||
{
|
||||
struct uf_sdio_emb_pm_notifier *notifier_ctx;
|
||||
struct list_head *node, *q;
|
||||
|
||||
list_for_each_safe(node, q, &uf_sdio_emb_pm_notifiers.list) {
|
||||
notifier_ctx = list_entry(node, struct uf_sdio_emb_pm_notifier, list);
|
||||
|
||||
/* If it matches, unregister and free the notifier context */
|
||||
if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
|
||||
{
|
||||
if (unregister_pm_notifier(¬ifier_ctx->pm_notifier)) {
|
||||
printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
|
||||
}
|
||||
|
||||
/* Remove from list */
|
||||
notifier_ctx->sdio_ctx = NULL;
|
||||
list_del(node);
|
||||
kfree(notifier_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_sdio_emb_power_event
|
||||
*
|
||||
* Handler for power management events.
|
||||
*
|
||||
* We need to handle suspend/resume events while the userspace is unsuspended
|
||||
* to allow the SME to run its suspend/resume state machines.
|
||||
*
|
||||
* Arguments:
|
||||
* event event ID
|
||||
*
|
||||
* Returns:
|
||||
* Status of the event handling
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr)
|
||||
{
|
||||
struct uf_sdio_emb_pm_notifier *notifier_ctx = container_of(this,
|
||||
struct uf_sdio_emb_pm_notifier,
|
||||
pm_notifier);
|
||||
|
||||
/* Call the CSR SDIO function driver's suspend/resume method
|
||||
* while the userspace is unsuspended.
|
||||
*/
|
||||
switch (event) {
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
|
||||
if (sdio_func_drv && sdio_func_drv->resume) {
|
||||
sdio_func_drv->resume(notifier_ctx->sdio_ctx);
|
||||
}
|
||||
break;
|
||||
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
|
||||
if (sdio_func_drv && sdio_func_drv->suspend) {
|
||||
sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_glue_sdio_probe
|
||||
*
|
||||
* Card insert callback.
|
||||
*
|
||||
* Arguments:
|
||||
* fdev SDIO context pointer
|
||||
*
|
||||
* Returns:
|
||||
* UniFi driver error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
uf_glue_sdio_probe(struct sdioemb_dev *fdev)
|
||||
{
|
||||
CsrSdioFunction *sdio_ctx;
|
||||
|
||||
unifi_info(NULL, "UniFi card inserted\n");
|
||||
|
||||
/* Allocate context and private in one lump */
|
||||
sdio_ctx = (CsrSdioFunction *)kmalloc(sizeof(CsrSdioFunction),
|
||||
GFP_KERNEL);
|
||||
if (sdio_ctx == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
sdio_ctx->sdioId.manfId = fdev->vendor_id;
|
||||
sdio_ctx->sdioId.cardId = fdev->device_id;
|
||||
sdio_ctx->sdioId.sdioFunction = fdev->function;
|
||||
sdio_ctx->sdioId.sdioInterface = 0;
|
||||
sdio_ctx->blockSize = fdev->blocksize;
|
||||
sdio_ctx->priv = (void *)fdev;
|
||||
sdio_ctx->features = 0;
|
||||
|
||||
/* Module parameter enables byte mode */
|
||||
if (sdio_byte_mode) {
|
||||
sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
|
||||
}
|
||||
|
||||
/* Set up pointer to func_priv in middle of lump */
|
||||
fdev->drv_data = sdio_ctx;
|
||||
|
||||
/* Always override default SDIO bus clock */
|
||||
unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
|
||||
sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* Register to get PM events */
|
||||
if (uf_sdio_emb_register_pm_notifier(sdio_ctx) == NULL) {
|
||||
unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Call the main UniFi driver inserted handler */
|
||||
if (sdio_func_drv && sdio_func_drv->inserted) {
|
||||
uf_add_os_device(fdev->slot_id, fdev->os_device);
|
||||
sdio_func_drv->inserted(sdio_ctx);
|
||||
}
|
||||
|
||||
#ifdef ANDROID_BUILD
|
||||
/* Take the wakelock */
|
||||
unifi_trace(NULL, UDBG1, "emb probe: take wake lock\n");
|
||||
wake_lock(&unifi_sdio_wake_lock);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} /* uf_glue_sdio_probe() */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_sdio_remove
|
||||
*
|
||||
* Card removal callback.
|
||||
*
|
||||
* Arguments:
|
||||
* fdev SDIO device
|
||||
*
|
||||
* Returns:
|
||||
* UniFi driver error code.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
uf_sdio_remove(struct sdioemb_dev *fdev)
|
||||
{
|
||||
CsrSdioFunction *sdio_ctx = fdev->drv_data;
|
||||
|
||||
unifi_info(NULL, "UniFi card removed\n");
|
||||
|
||||
/* Clean up the SDIO function driver */
|
||||
if (sdio_func_drv && sdio_func_drv->removed) {
|
||||
sdio_func_drv->removed(sdio_ctx);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* Unregister for PM events */
|
||||
uf_sdio_emb_unregister_pm_notifier(sdio_ctx);
|
||||
#endif
|
||||
|
||||
kfree(sdio_ctx);
|
||||
|
||||
} /* uf_sdio_remove */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_glue_sdio_suspend
|
||||
*
|
||||
* System suspend callback.
|
||||
*
|
||||
* Arguments:
|
||||
* fdev SDIO device
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
uf_glue_sdio_suspend(struct sdioemb_dev *fdev)
|
||||
{
|
||||
unifi_info(NULL, "Suspending...\n");
|
||||
|
||||
} /* uf_glue_sdio_suspend() */
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* uf_glue_sdio_resume
|
||||
*
|
||||
* System resume callback.
|
||||
*
|
||||
* Arguments:
|
||||
* fdev SDIO device
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
uf_glue_sdio_resume(struct sdioemb_dev *fdev)
|
||||
{
|
||||
unifi_info(NULL, "Resuming...\n");
|
||||
|
||||
#ifdef ANDROID_BUILD
|
||||
unifi_trace(NULL, UDBG1, "emb resume: take wakelock\n");
|
||||
wake_lock(&unifi_sdio_wake_lock);
|
||||
#endif
|
||||
|
||||
} /* uf_glue_sdio_resume() */
|
||||
|
||||
|
||||
|
||||
|
||||
static struct sdioemb_func_driver unifi_sdioemb = {
|
||||
.name = "unifi",
|
||||
.id_table = NULL, /* Filled in when main driver registers */
|
||||
|
||||
.probe = uf_glue_sdio_probe,
|
||||
.remove = uf_sdio_remove,
|
||||
.card_int_handler = uf_glue_sdio_int_handler,
|
||||
.suspend = uf_glue_sdio_suspend,
|
||||
.resume = uf_glue_sdio_resume,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* CsrSdioFunctionDriverRegister
|
||||
* CsrSdioFunctionDriverUnregister
|
||||
*
|
||||
* These functions are called from the main module load and unload
|
||||
* functions. They perform the appropriate operations for the
|
||||
* SDIOemb driver.
|
||||
*
|
||||
* Arguments:
|
||||
* None.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
CsrResult
|
||||
CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
|
||||
{
|
||||
int r;
|
||||
int i;
|
||||
|
||||
printk("Unifi: Using CSR embedded SDIO driver\n");
|
||||
|
||||
if (sdio_func_drv) {
|
||||
unifi_error(NULL, "sdio_emb: UniFi driver already registered\n");
|
||||
return CSR_SDIO_RESULT_INVALID_VALUE;
|
||||
}
|
||||
|
||||
/* Build ID table to pass to sdioemb */
|
||||
unifi_sdioemb.id_table = CsrPmemAlloc(sizeof(struct sdioemb_id_table) * (sdio_drv->idsCount + 1));
|
||||
if (unifi_sdioemb.id_table == NULL) {
|
||||
unifi_error(NULL, "sdio_emb: Failed to allocate memory for ID table (%d IDs)\n", sdio_drv->idsCount);
|
||||
return CSR_RESULT_FAILURE;
|
||||
}
|
||||
for (i = 0; i < sdio_drv->idsCount; i++) {
|
||||
unifi_sdioemb.id_table[i].vendor_id = sdio_drv->ids[i].manfId;
|
||||
unifi_sdioemb.id_table[i].device_id = sdio_drv->ids[i].cardId;
|
||||
unifi_sdioemb.id_table[i].function = sdio_drv->ids[i].sdioFunction;
|
||||
unifi_sdioemb.id_table[i].interface = sdio_drv->ids[i].sdioInterface;
|
||||
}
|
||||
unifi_sdioemb.id_table[i].vendor_id = 0;
|
||||
unifi_sdioemb.id_table[i].device_id = 0;
|
||||
unifi_sdioemb.id_table[i].function = 0;
|
||||
unifi_sdioemb.id_table[i].interface = 0;
|
||||
|
||||
/* Save the registered driver description */
|
||||
sdio_func_drv = sdio_drv;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* Initialise PM notifier list */
|
||||
INIT_LIST_HEAD(&uf_sdio_emb_pm_notifiers.list);
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID_BUILD
|
||||
wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
|
||||
#endif
|
||||
|
||||
/* Register ourself with sdioemb */
|
||||
r = sdioemb_driver_register(&unifi_sdioemb);
|
||||
if (r) {
|
||||
unifi_error(NULL, "Failed to register UniFi SDIO driver: %d\n", r);
|
||||
return ConvertSdioToCsrSdioResult(r);
|
||||
}
|
||||
|
||||
return CSR_RESULT_SUCCESS;
|
||||
} /* CsrSdioFunctionDriverRegister() */
|
||||
|
||||
|
||||
void
|
||||
CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
|
||||
{
|
||||
sdioemb_driver_unregister(&unifi_sdioemb);
|
||||
|
||||
#ifdef ANDROID_BUILD
|
||||
wake_lock_destroy(&unifi_sdio_wake_lock);
|
||||
#endif
|
||||
|
||||
sdio_func_drv = NULL;
|
||||
|
||||
CsrPmemFree(unifi_sdioemb.id_table);
|
||||
unifi_sdioemb.id_table = NULL;
|
||||
} /* CsrSdioFunctionDriverUnregister() */
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* CSPI definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef SDIOEMB_CSPI_H
|
||||
#define SDIOEMB_CSPI_H
|
||||
|
||||
/**
|
||||
* @addtogroup sdriver
|
||||
*@{*/
|
||||
|
||||
#define CSPI_FUNC(f) (f)
|
||||
#define CSPI_READ 0x10
|
||||
#define CSPI_WRITE 0x20
|
||||
#define CSPI_BURST 0x40
|
||||
#define CSPI_TYPE_MASK 0x70
|
||||
|
||||
/**
|
||||
* CSPI_MODE function 0 register.
|
||||
*
|
||||
* Various CSPI mode settings.
|
||||
*
|
||||
* @see CSPI specification (CS-110124-SP)
|
||||
*/
|
||||
#define CSPI_MODE 0xf7
|
||||
# define CSPI_MODE_PADDED_WRITE_HDRS (1 << 7)
|
||||
# define CSPI_MODE_PADDED_READ_HDRS (1 << 6)
|
||||
/**
|
||||
* BigEndianRegisters bit of \ref CSPI_MODE -- enable big-endian CSPI
|
||||
* register reads and writes.
|
||||
*
|
||||
* @warning This bit should never be set as it's not possible to use
|
||||
* this mode without knowledge of which registers are 8 bit and which
|
||||
* are 16 bit.
|
||||
*/
|
||||
# define CSPI_MODE_BE_REG (1 << 5)
|
||||
# define CSPI_MODE_BE_BURST (1 << 4)
|
||||
# define CSPI_MODE_INT_ACTIVE_HIGH (1 << 3)
|
||||
# define CSPI_MODE_INT_ON_ERR (1 << 2)
|
||||
# define CSPI_MODE_LEN_FIELD_PRESENT (1 << 1)
|
||||
# define CSPI_MODE_DRV_MISO_ON_RISING_CLK (1 << 0)
|
||||
|
||||
#define CSPI_STATUS 0xf8
|
||||
|
||||
#define CSPI_PADDING 0xf9
|
||||
# define CSPI_PADDING_REG(p) ((p) << 0)
|
||||
# define CSPI_PADDING_BURST(p) ((p) << 4)
|
||||
|
||||
#define CSPI_PADDING_MAX 15
|
||||
#define CSPI_PADDING_REG_DFLT 0
|
||||
#define CSPI_PADDING_BURST_DFLT 2
|
||||
|
||||
/* cmd byte, 3 byte addr, padding, error byte, data word */
|
||||
#define CSPI_REG_TRANSFER_LEN (1 + 3 + CSPI_PADDING_MAX + 1 + 2)
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* #ifndef SDIOEMB_CSPI_H */
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Synergy compatible API -- common result codes.
|
||||
*
|
||||
* Copyright (C) 2010 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef CSR_RESULT_H__
|
||||
#define CSR_RESULT_H__
|
||||
|
||||
typedef CsrUint16 CsrResult;
|
||||
#define CSR_RESULT_SUCCESS ((CsrResult) 0x0000)
|
||||
#define CSR_RESULT_FAILURE ((CsrResult) 0xffff)
|
||||
|
||||
#endif
|
|
@ -1,711 +0,0 @@
|
|||
/*
|
||||
* Synergy compatible API -- SDIO.
|
||||
*
|
||||
* Copyright (C) 2010 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef CSR_SDIO_H__
|
||||
#define CSR_SDIO_H__
|
||||
|
||||
#include "csr_types.h"
|
||||
#include "csr_result.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Result Codes */
|
||||
#define CSR_SDIO_RESULT_INVALID_VALUE ((CsrResult) 1) /* Invalid argument value */
|
||||
#define CSR_SDIO_RESULT_NO_DEVICE ((CsrResult) 2) /* The specified device is no longer present */
|
||||
#define CSR_SDIO_RESULT_CRC_ERROR ((CsrResult) 3) /* The transmitted/received data or command response contained a CRC error */
|
||||
#define CSR_SDIO_RESULT_TIMEOUT ((CsrResult) 4) /* No command response or data received from device, or function enable/disable did not succeed within timeout period */
|
||||
#define CSR_SDIO_RESULT_NOT_RESET ((CsrResult) 5) /* The device was not reset */
|
||||
|
||||
/* Features (for use in features member of CsrSdioFunction) */
|
||||
#define CSR_SDIO_FEATURE_BYTE_MODE 0x00000001 /* Transfer sizes do not have to be a multiple of block size */
|
||||
#define CSR_SDIO_FEATURE_DMA_CAPABLE_MEM_REQUIRED 0x00000002 /* Bulk operations require DMA friendly memory */
|
||||
|
||||
/* CsrSdioFunctionId wildcards (for use in CsrSdioFunctionId members) */
|
||||
#define CSR_SDIO_ANY_MANF_ID 0xFFFF
|
||||
#define CSR_SDIO_ANY_CARD_ID 0xFFFF
|
||||
#define CSR_SDIO_ANY_SDIO_FUNCTION 0xFF
|
||||
#define CSR_SDIO_ANY_SDIO_INTERFACE 0xFF
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioFunctionId
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This structure describes one or more functions of a device, based on
|
||||
* four qualitative measures. The CsrSdioFunctionId wildcard defines can be
|
||||
* used for making the CsrSdioFunctionId match more than one function.
|
||||
*
|
||||
* MEMBERS
|
||||
* manfId - Vendor ID (or CSR_SDIO_ANY_MANF_ID).
|
||||
* cardId - Device ID (or CSR_SDIO_ANY_CARD_ID).
|
||||
* sdioFunction - SDIO Function number (or CSR_SDIO_ANY_SDIO_FUNCTION).
|
||||
* sdioInterface - SDIO Standard Interface Code (or CSR_SDIO_ANY_SDIO_INTERFACE)
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
CsrUint16 manfId; /* Vendor ID to match or CSR_SDIO_ANY_MANF_ID */
|
||||
CsrUint16 cardId; /* Device ID to match or CSR_SDIO_ANY_CARD_ID */
|
||||
CsrUint8 sdioFunction; /* SDIO Function number to match or CSR_SDIO_ANY_SDIO_FUNCTION */
|
||||
CsrUint8 sdioInterface; /* SDIO Standard Interface Code to match or CSR_SDIO_ANY_SDIO_INTERFACE */
|
||||
} CsrSdioFunctionId;
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioFunction
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This structure represents a single function on a device.
|
||||
*
|
||||
* MEMBERS
|
||||
* sdioId - A CsrSdioFunctionId describing this particular function. The
|
||||
* subfield shall not contain any CsrSdioFunctionId wildcards. The
|
||||
* subfields shall describe the specific single function
|
||||
* represented by this structure.
|
||||
* blockSize - Actual configured block size, or 0 if unconfigured.
|
||||
* features - Bit mask with any of CSR_SDIO_FEATURE_* set.
|
||||
* driverData - For use by the Function Driver. The SDIO Driver shall not
|
||||
* attempt to dereference the pointer.
|
||||
* priv - For use by the SDIO Driver. The Function Driver shall not attempt
|
||||
* to dereference the pointer.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
CsrSdioFunctionId sdioId;
|
||||
CsrUint16 blockSize; /* Actual configured block size, or 0 if unconfigured */
|
||||
CsrUint32 features; /* Bit mask with any of CSR_SDIO_FEATURE_* set */
|
||||
void *cardHandle; /* An opaque handle for this function's card. */
|
||||
void *osDevice;
|
||||
void *driverData; /* For use by the Function Driver */
|
||||
void *priv; /* For use by the SDIO Driver */
|
||||
} CsrSdioFunction;
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioInsertedCallback, CsrSdioRemovedCallback
|
||||
*
|
||||
* DESCRIPTION
|
||||
* CsrSdioInsertedCallback is called when a function becomes available to
|
||||
* a registered Function Driver that supports the function.
|
||||
* CsrSdioRemovedCallback is called when a function is no longer available
|
||||
* to a Function Driver, either because the device has been removed, or the
|
||||
* Function Driver has been unregistered.
|
||||
*
|
||||
* NOTE: These functions are implemented by the Function Driver, and are
|
||||
* passed as function pointers in the CsrSdioFunctionDriver struct.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void (*CsrSdioInsertedCallback)(CsrSdioFunction *function);
|
||||
typedef void (*CsrSdioRemovedCallback)(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioInterruptDsrCallback, CsrSdioInterruptCallback
|
||||
*
|
||||
* DESCRIPTION
|
||||
* CsrSdioInterruptCallback is called when an interrupt occurs on the
|
||||
* the device associated with the specified function.
|
||||
*
|
||||
* NOTE: These functions are implemented by the Function Driver, and are
|
||||
* passed as function pointers in the CsrSdioFunctionDriver struct.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
*
|
||||
* RETURNS (only CsrSdioInterruptCallback)
|
||||
* A pointer to a CsrSdioInterruptDsrCallback function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void (*CsrSdioInterruptDsrCallback)(CsrSdioFunction *function);
|
||||
typedef CsrSdioInterruptDsrCallback (*CsrSdioInterruptCallback)(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioSuspendCallback, CsrSdioResumeCallback
|
||||
*
|
||||
* DESCRIPTION
|
||||
* CsrSdioSuspendCallback is called when the system is preparing to go
|
||||
* into a suspended state. CsrSdioResumeCallback is called when the system
|
||||
* has entered an active state again.
|
||||
*
|
||||
* NOTE: These functions are implemented by the Function Driver, and are
|
||||
* passed as function pointers in the CsrSdioFunctionDriver struct.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void (*CsrSdioSuspendCallback)(CsrSdioFunction *function);
|
||||
typedef void (*CsrSdioResumeCallback)(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioAsyncCallback, CsrSdioAsyncDsrCallback
|
||||
*
|
||||
* DESCRIPTION
|
||||
* CsrSdioAsyncCallback is called when an asynchronous operation completes.
|
||||
*
|
||||
* NOTE: These functions are implemented by the Function Driver, and are
|
||||
* passed as function pointers in the function calls that initiate
|
||||
* the operation.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* result - The result of the operation that completed. See the description
|
||||
* of the initiating function for possible result values.
|
||||
*
|
||||
* RETURNS (only CsrSdioAsyncCallback)
|
||||
* A pointer to a CsrSdioAsyncDsrCallback function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void (*CsrSdioAsyncDsrCallback)(CsrSdioFunction *function, CsrResult result);
|
||||
typedef CsrSdioAsyncDsrCallback (*CsrSdioAsyncCallback)(CsrSdioFunction *function, CsrResult result);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CsrSdioInsertedCallback inserted;
|
||||
CsrSdioRemovedCallback removed;
|
||||
CsrSdioInterruptCallback intr;
|
||||
CsrSdioSuspendCallback suspend;
|
||||
CsrSdioResumeCallback resume;
|
||||
CsrSdioFunctionId *ids;
|
||||
CsrUint8 idsCount;
|
||||
void *priv;
|
||||
} CsrSdioFunctionDriver;
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioFunctionDriverRegister
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Register a Function Driver.
|
||||
*
|
||||
* PARAMETERS
|
||||
* functionDriver - Pointer to struct describing the Function Driver.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The Function Driver was successfully
|
||||
* registered.
|
||||
* CSR_RESULT_FAILURE - Unable to register the function driver,
|
||||
* because of an unspecified/unknown error. The
|
||||
* Function Driver has not been registered.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - The specified Function Driver pointer
|
||||
* does not point at a valid Function
|
||||
* Driver structure, or some of the members
|
||||
* contain invalid entries.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *functionDriver);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioFunctionDriverUnregister
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Unregister a previously registered Function Driver.
|
||||
*
|
||||
* PARAMETERS
|
||||
* functionDriver - pointer to struct describing the Function Driver.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *functionDriver);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioFunctionEnable, CsrSdioFunctionDisable
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Enable/disable the specified function by setting/clearing the
|
||||
* corresponding bit in the I/O Enable register in function 0, and then
|
||||
* periodically reading the related bit in the I/O Ready register until it
|
||||
* is set/clear, limited by an implementation defined timeout.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The specified function was enabled/disabled.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The state of the
|
||||
* related bit in the I/O Enable register is
|
||||
* undefined.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device, or the related
|
||||
* bit in the I/O ready register was not
|
||||
* set/cleared within the timeout period.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and either of the
|
||||
* FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
|
||||
* is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioFunctionEnable(CsrSdioFunction *function);
|
||||
CsrResult CsrSdioFunctionDisable(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioInterruptEnable, CsrSdioInterruptDisable
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Enable/disable the interrupt for the specified function by
|
||||
* setting/clearing the corresponding bit in the INT Enable register in
|
||||
* function 0.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The specified function was enabled/disabled.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The state of the
|
||||
* related bit in the INT Enable register is
|
||||
* unchanged.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - The specified function cannot be
|
||||
* enabled/disabled, because it either
|
||||
* does not exist or it is not possible to
|
||||
* individually enable/disable functions.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and either of the
|
||||
* FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
|
||||
* is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioInterruptEnable(CsrSdioFunction *function);
|
||||
CsrResult CsrSdioInterruptDisable(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioInterruptAcknowledge
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Acknowledge that a signalled interrupt has been handled. Shall only
|
||||
* be called once, and exactly once for each signalled interrupt to the
|
||||
* corresponding function.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function to which the
|
||||
* event was signalled.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CsrSdioInterruptAcknowledge(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioInsertedAcknowledge, CsrSdioRemovedAcknowledge
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Acknowledge that a signalled inserted/removed event has been handled.
|
||||
* Shall only be called once, and exactly once for each signalled event to
|
||||
* the corresponding function.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function to which the
|
||||
* inserted was signalled.
|
||||
* result (CsrSdioInsertedAcknowledge only)
|
||||
* CSR_RESULT_SUCCESS - The Function Driver has accepted the
|
||||
* function, and the function is attached to
|
||||
* the Function Driver until the
|
||||
* CsrSdioRemovedCallback is called and
|
||||
* acknowledged.
|
||||
* CSR_RESULT_FAILURE - Unable to accept the function. The
|
||||
* function is not attached to the Function
|
||||
* Driver, and it may be passed to another
|
||||
* Function Driver which supports the
|
||||
* function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CsrSdioInsertedAcknowledge(CsrSdioFunction *function, CsrResult result);
|
||||
void CsrSdioRemovedAcknowledge(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioSuspendAcknowledge, CsrSdioResumeAcknowledge
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Acknowledge that a signalled suspend event has been handled. Shall only
|
||||
* be called once, and exactly once for each signalled event to the
|
||||
* corresponding function.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function to which the
|
||||
* event was signalled.
|
||||
* result
|
||||
* CSR_RESULT_SUCCESS - Successfully suspended/resumed.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CsrSdioSuspendAcknowledge(CsrSdioFunction *function, CsrResult result);
|
||||
void CsrSdioResumeAcknowledge(CsrSdioFunction *function, CsrResult result);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioBlockSizeSet
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set the block size to use for the function. The actual configured block
|
||||
* size shall be the minimum of:
|
||||
* 1) Maximum block size supported by the function.
|
||||
* 2) Maximum block size supported by the host controller.
|
||||
* 3) The block size specified by the blockSize argument.
|
||||
*
|
||||
* When this function returns, the actual configured block size is
|
||||
* available in the blockSize member of the function struct.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* blockSize - Block size to use for the function. Valid range is 1 to
|
||||
* 2048.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The block size register on the chip
|
||||
* was updated.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. The configured block
|
||||
* size is undefined.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER
|
||||
* bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned.
|
||||
* If the ERROR bit is set (but not FUNCTION_NUMBER),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
* NOTE: Setting the block size requires two individual operations. The
|
||||
* implementation shall ignore the OUT_OF_RANGE bit of the SDIO R5
|
||||
* response for the first operation, as the partially configured
|
||||
* block size may be out of range, even if the final block size
|
||||
* (after the second operation) is in the valid range.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioBlockSizeSet(CsrSdioFunction *function, CsrUint16 blockSize);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioMaxBusClockFrequencySet
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set the maximum clock frequency to use for the device associated with
|
||||
* the specified function. The actual configured clock frequency for the
|
||||
* device shall be the minimum of:
|
||||
* 1) Maximum clock frequency supported by the device.
|
||||
* 2) Maximum clock frequency supported by the host controller.
|
||||
* 3) Maximum clock frequency specified for any function on the same
|
||||
* device.
|
||||
*
|
||||
* If the clock frequency exceeds 25MHz, it is the responsibility of the
|
||||
* SDIO driver to enable high speed mode on the device, using the standard
|
||||
* defined procedure, before increasing the frequency beyond the limit.
|
||||
*
|
||||
* Note that the clock frequency configured affects all functions on the
|
||||
* same device.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* maxFrequency - The maximum clock frequency for the function in Hertz.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The maximum clock frequency was succesfully
|
||||
* set for the function.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER
|
||||
* bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned.
|
||||
* If the ERROR bit is set (but not FUNCTION_NUMBER),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, CsrUint32 maxFrequency);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioRead8, CsrSdioWrite8, CsrSdioRead8Async, CsrSdioWrite8Async
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Read/write an 8bit value from/to the specified register address.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* address - Register address within the function.
|
||||
* data - The data to read/write.
|
||||
* callback - The function to call on operation completion.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The data was successfully read/written.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. No data read/written.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and either of the
|
||||
* FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
|
||||
* is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
* NOTE: The CsrSdioRead8Async and CsrSdioWrite8Async functions return
|
||||
* immediately, and the supplied callback function is called when the
|
||||
* operation is complete. The result value is given as an argument to
|
||||
* the callback function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioRead8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data);
|
||||
CsrResult CsrSdioWrite8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data);
|
||||
void CsrSdioRead8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data, CsrSdioAsyncCallback callback);
|
||||
void CsrSdioWrite8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data, CsrSdioAsyncCallback callback);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioRead16, CsrSdioWrite16, CsrSdioRead16Async, CsrSdioWrite16Async
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Read/write a 16bit value from/to the specified register address.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* address - Register address within the function.
|
||||
* data - The data to read/write.
|
||||
* callback - The function to call on operation completion.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The data was successfully read/written.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. Data may have been
|
||||
* partially read/written.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and either of the
|
||||
* FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
|
||||
* is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
* NOTE: The CsrSdioRead16Async and CsrSdioWrite16Async functions return
|
||||
* immediately, and the supplied callback function is called when the
|
||||
* operation is complete. The result value is given as an argument to
|
||||
* the callback function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioRead16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data);
|
||||
CsrResult CsrSdioWrite16(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data);
|
||||
void CsrSdioRead16Async(CsrSdioFunction *function, CsrUint32 address, CsrUint16 *data, CsrSdioAsyncCallback callback);
|
||||
void CsrSdioWrite16Async(CsrSdioFunction *function, CsrUint32 address, CsrUint16 data, CsrSdioAsyncCallback callback);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioF0Read8, CsrSdioF0Write8, CsrSdioF0Read8Async,
|
||||
* CsrSdioF0Write8Async
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Read/write an 8bit value from/to the specified register address in
|
||||
* function 0.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* address - Register address within the function.
|
||||
* data - The data to read/write.
|
||||
* callback - The function to call on operation completion.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The data was successfully read/written.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. No data read/written.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and either of the
|
||||
* FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
|
||||
* is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
* NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return
|
||||
* immediately, and the supplied callback function is called when the
|
||||
* operation is complete. The result value is given as an argument to
|
||||
* the callback function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioF0Read8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data);
|
||||
CsrResult CsrSdioF0Write8(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data);
|
||||
void CsrSdioF0Read8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 *data, CsrSdioAsyncCallback callback);
|
||||
void CsrSdioF0Write8Async(CsrSdioFunction *function, CsrUint32 address, CsrUint8 data, CsrSdioAsyncCallback callback);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioRead, CsrSdioWrite, CsrSdioReadAsync, CsrSdioWriteAsync
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Read/write a specified number of bytes from/to the specified register
|
||||
* address.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
* address - Register address within the function.
|
||||
* data - The data to read/write.
|
||||
* length - Number of byte to read/write.
|
||||
* callback - The function to call on operation completion.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - The data was successfully read/written.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured. Data may have been
|
||||
* partially read/written.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device.
|
||||
*
|
||||
* NOTE: If the SDIO R5 response is available, and either of the
|
||||
* FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
|
||||
* is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
|
||||
* CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
|
||||
* COM_CRC_ERROR bits shall be ignored.
|
||||
*
|
||||
* If the CSPI response is available, and any of the
|
||||
* FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
|
||||
* CSR_SDIO_RESULT_INVALID_VALUE will be returned.
|
||||
*
|
||||
* NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return
|
||||
* immediately, and the supplied callback function is called when the
|
||||
* operation is complete. The result value is given as an argument to
|
||||
* the callback function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioRead(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length);
|
||||
CsrResult CsrSdioWrite(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length);
|
||||
void CsrSdioReadAsync(CsrSdioFunction *function, CsrUint32 address, void *data, CsrUint32 length, CsrSdioAsyncCallback callback);
|
||||
void CsrSdioWriteAsync(CsrSdioFunction *function, CsrUint32 address, const void *data, CsrUint32 length, CsrSdioAsyncCallback callback);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioPowerOn, CsrSdioPowerOff
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Power on/off the device.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function that resides on
|
||||
* the device to power on/off.
|
||||
*
|
||||
* RETURNS (only CsrSdioPowerOn)
|
||||
* CSR_RESULT_SUCCESS - Power was succesfully reapplied and the device
|
||||
* has been reinitialised.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured during reinitialisation.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device during
|
||||
* reinitialisation.
|
||||
* CSR_SDIO_RESULT_NOT_RESET - The power was not removed by the
|
||||
* CsrSdioPowerOff call. The state of the
|
||||
* device is unchanged.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioPowerOn(CsrSdioFunction *function);
|
||||
void CsrSdioPowerOff(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioHardReset
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Perform a hardware reset of the device.
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function that resides on
|
||||
* the device to hard reset.
|
||||
*
|
||||
* RETURNS
|
||||
* CSR_RESULT_SUCCESS - Reset was succesfully performed and the device
|
||||
* has been reinitialised.
|
||||
* CSR_RESULT_FAILURE - Unspecified/unknown error.
|
||||
* CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
|
||||
* CSR_SDIO_RESULT_CRC_ERROR - A CRC error occured during reinitialisation.
|
||||
* CSR_SDIO_RESULT_TIMEOUT - No response from the device during
|
||||
* reinitialisation.
|
||||
* CSR_SDIO_RESULT_NOT_RESET - The reset was not applied because it is not
|
||||
* supported. The state of the device is
|
||||
* unchanged.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
CsrResult CsrSdioHardReset(CsrSdioFunction *function);
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
* NAME
|
||||
* CsrSdioFunctionActive, CsrSdioFunctionIdle
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PARAMETERS
|
||||
* function - Pointer to struct representing the function.
|
||||
*
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CsrSdioFunctionActive(CsrSdioFunction *function);
|
||||
void CsrSdioFunctionIdle(CsrSdioFunction *function);
|
||||
|
||||
void CsrSdioCallbackInhibitEnter(CsrSdioFunction *function);
|
||||
void CsrSdioCallbackInhibitLeave(CsrSdioFunction *function);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Synergy compatible API -- SDIO utility library.
|
||||
*
|
||||
* Copyright (C) 2010 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef CSR_SDIO_LIB_H__
|
||||
#define CSR_SDIO_LIB_H__
|
||||
|
||||
#include <csr_sdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CsrResult CsrSdioFunctionReenable(CsrSdioFunction *function);
|
||||
|
||||
typedef int CsrStatus; /* platform specific */
|
||||
#define CSR_STATUS_FAILURE(status) ((status) < 0) /* platform specific */
|
||||
|
||||
CsrResult CsrSdioStatusToResult(CsrStatus status);
|
||||
CsrStatus CsrSdioResultToStatus(CsrResult result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef CSR_SDIO_LIB_H__ */
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Synergy compatible API -- helpers for Windows Driver Framework drivers.
|
||||
*
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef CSR_SDIO_WDF_H__
|
||||
#define CSR_SDIO_WDF_H__
|
||||
|
||||
#include <wdf.h>
|
||||
|
||||
NTSTATUS CsrSdioWdfDeviceInit(WDFDEVICE device);
|
||||
void CsrSdioWdfDeviceCleanup(WDFDEVICE device);
|
||||
|
||||
NTSTATUS CsrSdioWdfDeviceAdd(WDFDEVICE device);
|
||||
void CsrSdioWdfDeviceDel(WDFDEVICE device);
|
||||
|
||||
NTSTATUS CsrSdioWdfDeviceSuspend(WDFDEVICE device);
|
||||
NTSTATUS CsrSdioWdfDeviceResume(WDFDEVICE device);
|
||||
|
||||
#endif /* #ifndef CSR_SDIO_WDF_H__ */
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Synergy compatible API -- basic types.
|
||||
*
|
||||
* Copyright (C) 2010 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef CSR_TYPES_H__
|
||||
#define CSR_TYPES_H__
|
||||
|
||||
#include <oska/types.h>
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
|
||||
/* Data types */
|
||||
|
||||
typedef size_t CsrSize;
|
||||
|
||||
typedef uint8_t CsrUint8;
|
||||
typedef uint16_t CsrUint16;
|
||||
typedef uint32_t CsrUint32;
|
||||
|
||||
typedef int8_t CsrInt8;
|
||||
typedef int16_t CsrInt16;
|
||||
typedef int32_t CsrInt32;
|
||||
|
||||
typedef bool CsrBool;
|
||||
|
||||
typedef char CsrCharString;
|
||||
typedef unsigned char CsrUtf8String;
|
||||
typedef CsrUint16 CsrUtf16String; /* 16-bit UTF16 strings */
|
||||
typedef CsrUint32 CsrUint24;
|
||||
|
||||
/*
|
||||
* 64-bit integers
|
||||
*
|
||||
* Note: If a given compiler does not support 64-bit types, it is
|
||||
* OK to omit these definitions; 32-bit versions of the code using
|
||||
* these types may be available. Consult the relevant documentation
|
||||
* or the customer support group for information on this.
|
||||
*/
|
||||
#define CSR_HAVE_64_BIT_INTEGERS
|
||||
typedef uint64_t CsrUint64;
|
||||
typedef int64_t CsrInt64;
|
||||
|
||||
#endif
|
|
@ -1,404 +0,0 @@
|
|||
/*
|
||||
* SDIO Userspace Interface library.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef SDIOEMB_LIBSDIO_H
|
||||
#define SDIOEMB_LIBSDIO_H
|
||||
|
||||
/**
|
||||
* \defgroup libsdio Userspace SDIO library (libsdio)
|
||||
*
|
||||
* \brief \e libsdio is a Linux C library for accessing SDIO cards.
|
||||
*
|
||||
* Use of this library requires several \e sdioemb kernel modules to be
|
||||
* loaded:
|
||||
* - \c sdio.
|
||||
* - \c An SDIO slot driver (e.g., \c slot_shc for a standard PCI
|
||||
* SDIO Host Controller).
|
||||
* - \c sdio_uif which provides the required character devices
|
||||
* (/dev/sdio_uif0 for the card in SDIO slot 0 etc.).
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define LIBSDIOAPI __stdcall
|
||||
#else
|
||||
# define LIBSDIOAPI
|
||||
#endif
|
||||
|
||||
struct sdio_uif;
|
||||
|
||||
/**
|
||||
* Handle to an opened SDIO Userspace Interface device.
|
||||
*/
|
||||
typedef struct sdio_uif *sdio_uif_t;
|
||||
|
||||
enum sdio_status {
|
||||
SDIO_SUCCESS = 0,
|
||||
SDIO_EAGAIN = -1,
|
||||
SDIO_EINVAL = -2,
|
||||
SDIO_EIO = -3,
|
||||
SDIO_ENODEV = -4,
|
||||
SDIO_ENOMEM = -5,
|
||||
SDIO_ENOTSUPP = -6,
|
||||
SDIO_ENXIO = -7,
|
||||
SDIO_ETIMEDOUT = -8,
|
||||
};
|
||||
|
||||
/**
|
||||
* Card interrupt handler function.
|
||||
*
|
||||
* @param uif handle to the interrupting device.
|
||||
* @param arg data supplied by the caller of sdio_open().
|
||||
*/
|
||||
typedef void (LIBSDIOAPI *sdio_int_handler_t)(sdio_uif_t uif, void *arg);
|
||||
|
||||
/**
|
||||
* Asynchronous IO completion callback function.
|
||||
*
|
||||
* @param uif handle to the device that completed the IO operation.
|
||||
* @param arg data supplied by the caller of the asynchronous IO operation.
|
||||
* @param status status of the IO operation. 0 is success; -EIO,
|
||||
* -EINVAL, -ETIMEDOUT etc. on an error.
|
||||
*/
|
||||
typedef void (LIBSDIOAPI *sdio_io_callback_t)(sdio_uif_t uif, void *arg, int status);
|
||||
|
||||
/**
|
||||
* Open a SDIO Userspace Interface device and (optionally) register a
|
||||
* card interrupt handler and enable card interrupts.
|
||||
*
|
||||
* Card interrupts are masked before calling int_handler and are
|
||||
* unmasked when int_handler returns (unless sdio_interrupt_mask() is
|
||||
* called).
|
||||
*
|
||||
* @param dev_filename filename of the device to open.
|
||||
* @param int_handler card interrupt handler; or NULL if no
|
||||
* interrupt handler is required.
|
||||
* @param arg argument to be passed to the interrupt handler.
|
||||
*
|
||||
* @return handle to the opened device; or NULL on error with errno
|
||||
* set.
|
||||
*/
|
||||
sdio_uif_t LIBSDIOAPI sdio_open(const char *dev_filename,
|
||||
sdio_int_handler_t int_handler, void *arg);
|
||||
|
||||
/**
|
||||
* Mask the SDIO interrupt.
|
||||
*
|
||||
* Call this in an interrupt handler to allow the processing of
|
||||
* interrupts to be deferred until after the interrupt handler has
|
||||
* returned.
|
||||
*
|
||||
* @note \e Must only be called from within the interrupt handler
|
||||
* registered with sdio_open().
|
||||
*
|
||||
* @param uif device handle.
|
||||
*/
|
||||
void LIBSDIOAPI sdio_interrupt_mask(sdio_uif_t uif);
|
||||
|
||||
/**
|
||||
* Unmask the SDIO interrupt.
|
||||
*
|
||||
* Unmasks the SDIO interrupt if it had previously been masked with
|
||||
* sdio_interrupt_mask().
|
||||
*
|
||||
* @param uif device handle.
|
||||
*/
|
||||
void LIBSDIOAPI sdio_interrupt_unmask(sdio_uif_t uif);
|
||||
|
||||
/**
|
||||
* Close an opened SDIO Userspace Interface device, freeing all
|
||||
* associated resources.
|
||||
*
|
||||
* @param uif handle to the device.
|
||||
*/
|
||||
void LIBSDIOAPI sdio_close(sdio_uif_t uif);
|
||||
|
||||
/**
|
||||
* Return the number of functions the card has.
|
||||
*
|
||||
* @param uif device handle.
|
||||
*
|
||||
* @return number of card functions.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_num_functions(sdio_uif_t uif);
|
||||
|
||||
/**
|
||||
* Set an SDIO bus to 1 bit or 4 bit wide mode.
|
||||
*
|
||||
* The CCCR bus interface control register will be read and rewritten
|
||||
* with the new bus width.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param bus_width bus width (1 or 4).
|
||||
*
|
||||
* @return 0 on success; -ve on error with errno set.
|
||||
*
|
||||
* @note The card capabilities are \e not checked. The user should
|
||||
* ensure 4 bit mode is not enabled on a card that does not support
|
||||
* it.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_set_bus_width(sdio_uif_t uif, int bus_width);
|
||||
|
||||
/**
|
||||
* Limit the frequency of (or stop) the SD bus clock.
|
||||
*
|
||||
* The frequency cannot be set greater than that supported by the card
|
||||
* or the controller.
|
||||
*
|
||||
* @note Stopping the bus clock while other device drivers are
|
||||
* executing commands may result in those commands not completing
|
||||
* until the bus clock is restarted.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param max_freq maximum frequency (Hz) or 0 to stop the bus clock
|
||||
* until the start of the next command.
|
||||
*/
|
||||
void LIBSDIOAPI sdio_set_max_bus_freq(sdio_uif_t uif, int max_freq);
|
||||
|
||||
/**
|
||||
* Return the card's manufacturer (vendor) ID.
|
||||
*
|
||||
* @param uif device handle.
|
||||
*
|
||||
* @return manufacturer ID.
|
||||
*/
|
||||
uint16_t LIBSDIOAPI sdio_manf_id(sdio_uif_t uif);
|
||||
|
||||
/**
|
||||
* Return the card's card (device) ID.
|
||||
*
|
||||
* @param uif device handle.
|
||||
*
|
||||
* @return card ID.
|
||||
*/
|
||||
uint16_t LIBSDIOAPI sdio_card_id(sdio_uif_t uif);
|
||||
|
||||
/**
|
||||
* Return the standard interface code for a function.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function to query.
|
||||
*
|
||||
* @return the standard interface.
|
||||
*/
|
||||
uint8_t LIBSDIOAPI sdio_std_if(sdio_uif_t uif, int func);
|
||||
|
||||
/**
|
||||
* Return a function's maximum supported block size.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function to query.
|
||||
*
|
||||
* @return maximum block size.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_max_block_size(sdio_uif_t uif, int func);
|
||||
|
||||
/**
|
||||
* Return a function's current block size.
|
||||
*
|
||||
* @note This returns the driver's view of the block size and not the
|
||||
* value in the function's block size register.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function to query.
|
||||
*
|
||||
* @return the current block size.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_block_size(sdio_uif_t uif, int func);
|
||||
|
||||
/**
|
||||
* Set a function's block size.
|
||||
*
|
||||
* The function's block size registers will be written if necessary.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func function to modify.
|
||||
* @param blksz the new block size; or 0 for the default size.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_set_block_size(sdio_uif_t uif, int func, int blksz);
|
||||
|
||||
/**
|
||||
* Read an 8 bit register.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register address.
|
||||
* @param data the data read.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_read8(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data);
|
||||
|
||||
/**
|
||||
* Write an 8 bit register.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register address.
|
||||
* @param data the data to write.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_write8(sdio_uif_t uif, int func, uint32_t addr, uint8_t data);
|
||||
|
||||
/**
|
||||
* Read a buffer from a 8 bit wide register/FIFO.
|
||||
*
|
||||
* The buffer read uses a fixed (not incrementing) address.
|
||||
*
|
||||
* \a block_size \e must be set to the value writted into \a func's
|
||||
* I/O block size FBR register.
|
||||
*
|
||||
* If \a len % \a block_size == 0, a block mode transfer is used; a
|
||||
* byte mode transfer is used if \a len < \a block_size.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register/FIFO address.
|
||||
* @param data buffer to store the data read.
|
||||
* @param len length of data to read.
|
||||
* @param block_size block size to use for this transfer.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_read(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
|
||||
size_t len, int block_size);
|
||||
|
||||
/**
|
||||
* Write a buffer to an 8 bit wide register/FIFO.
|
||||
*
|
||||
* The buffer write uses a fixed (not incrementing) address.
|
||||
*
|
||||
* \a block_size \e must be set to the value writted into \a func's
|
||||
* I/O block size FBR register.
|
||||
*
|
||||
* If \a len % \a block_size == 0, a block mode transfer is used; a
|
||||
* byte mode transfer is used if \a len < \a block_size.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register/FIFO address.
|
||||
* @param data buffer of data to write.
|
||||
* @param len length of the data to write.
|
||||
* @param block_size block size to use for this transfer.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_write(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data,
|
||||
size_t len, int block_size);
|
||||
|
||||
/**
|
||||
* Read an 8 bit register, without waiting for completion.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register address.
|
||||
* @param data the data read.
|
||||
* @param callback function to be called when the read completes.
|
||||
* @param arg argument to be passed to callback.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_read8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
|
||||
sdio_io_callback_t callback, void *arg);
|
||||
|
||||
/**
|
||||
* Write an 8 bit register, without waiting for completion.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register address.
|
||||
* @param data the data to write.
|
||||
* @param callback function to be called when the write completes.
|
||||
* @param arg argument to be passed to callback.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_write8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t data,
|
||||
sdio_io_callback_t callback, void *arg);
|
||||
|
||||
/**
|
||||
* Read a buffer from a 8 bit wide register/FIFO, without waiting for
|
||||
* completion.
|
||||
*
|
||||
* The buffer read uses a fixed (not incrementing) address.
|
||||
*
|
||||
* \a block_size \e must be set to the value writted into \a func's
|
||||
* I/O block size FBR register.
|
||||
*
|
||||
* If \a len % \a block_size == 0, a block mode transfer is used; a
|
||||
* byte mode transfer is used if \a len < \a block_size.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register/FIFO address.
|
||||
* @param data buffer to store the data read.
|
||||
* @param len length of data to read.
|
||||
* @param block_size block size to use for this transfer.
|
||||
* @param callback function to be called when the read completes.
|
||||
* @param arg argument to be passed to callback.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_read_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
|
||||
size_t len, int block_size,
|
||||
sdio_io_callback_t callback, void *arg);
|
||||
|
||||
/**
|
||||
* Write a buffer to an 8 bit wide register/FIFO, without waiting for
|
||||
* completion.
|
||||
*
|
||||
* The buffer write uses a fixed (not incrementing) address.
|
||||
*
|
||||
* \a block_size \e must be set to the value writted into \a func's
|
||||
* I/O block size FBR register.
|
||||
*
|
||||
* If \a len % \a block_size == 0, a block mode transfer is used; a
|
||||
* byte mode transfer is used if \a len < \a block_size.
|
||||
*
|
||||
* @param uif device handle.
|
||||
* @param func card function.
|
||||
* @param addr register/FIFO address.
|
||||
* @param data buffer of data to write.
|
||||
* @param len length of the data to write.
|
||||
* @param block_size block size to use for this transfer.
|
||||
* @param callback function to be called when the write completes.
|
||||
* @param arg argument to be passed to callback.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_write_async(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data,
|
||||
size_t len, int block_size,
|
||||
sdio_io_callback_t callback, void *arg);
|
||||
/**
|
||||
* Force a card removal and reinsertion.
|
||||
*
|
||||
* This will power cycle the card if the slot hardware supports power
|
||||
* control.
|
||||
*
|
||||
* @note The device handle will no longer be valid.
|
||||
*
|
||||
* @param uif device handle.
|
||||
*
|
||||
* @return 0 on success; or -ve on error with errno set.
|
||||
*/
|
||||
int LIBSDIOAPI sdio_reinsert_card(sdio_uif_t uif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* #ifndef SDIOEMB_LIBSDIO_H */
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Linux helpers for slot drivers.
|
||||
*
|
||||
* Copyright (C) 2009 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef SDIOEMB_LINUX_H
|
||||
#define SDIOEMB_LINUX_H
|
||||
|
||||
#include <sdioemb/slot_api.h>
|
||||
|
||||
int sdioemb_linux_slot_register(struct sdioemb_slot *slot);
|
||||
|
||||
#endif /* #ifndef SDIOEMB_LINUX_H */
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Standard SDIO definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef SDIOEMB_SDIO_H
|
||||
#define SDIOEMB_SDIO_H
|
||||
|
||||
/* Maximum time for VDD to rise to VDD min. */
|
||||
#define SDIO_POWER_UP_TIME_MS 250
|
||||
|
||||
/* Minimum SD bus clock a card must support (Hz). */
|
||||
#define SDIO_CLOCK_FREQ_MIN 400000
|
||||
|
||||
/* Maximum clock frequency for normal mode (Hz).
|
||||
*
|
||||
* Although high speed mode should be suitable for all speeds not all
|
||||
* controller/card combinations are capable of meeting the higher
|
||||
* tolerances for (e.g.) clock rise/fall times. Therefore, default
|
||||
* mode is used where possible for improved compatibility. */
|
||||
#define SDIO_CLOCK_FREQ_NORMAL_SPD 25000000
|
||||
|
||||
/* Maximum clock frequency for high speed mode (Hz). */
|
||||
#define SDIO_CLOCK_FREQ_HIGH_SPD 50000000
|
||||
|
||||
#define SDIO_MAX_FUNCTIONS 8 /* incl. F0 */
|
||||
|
||||
/* Command argument format. */
|
||||
|
||||
#define SDIO_CMD52_ARG_WRITE 0x80000000
|
||||
#define SDIO_CMD52_ARG_FUNC(f) ((f) << 28)
|
||||
#define SDIO_CMD52_ARG_ADDR(a) ((a) << 9)
|
||||
#define SDIO_CMD52_ARG_DATA(d) ((d) << 0)
|
||||
|
||||
#define SDIO_CMD53_ARG_WRITE 0x80000000
|
||||
#define SDIO_CMD53_ARG_FUNC(f) ((f) << 28)
|
||||
#define SDIO_CMD53_ARG_BLK_MODE 0x08000000
|
||||
#define SDIO_CMD53_ARG_ADDR(a) ((a) << 9)
|
||||
#define SDIO_CMD53_ARG_CNT(c) ((c) << 0)
|
||||
|
||||
/* Response format. */
|
||||
|
||||
#define SDIO_R5_DATA(r) (((r) >> 0) & 0xff)
|
||||
#define SDIO_R5_OUT_OF_RANGE (1 << 8)
|
||||
#define SDIO_R5_FUNCTION_NUMBER (1 << 9)
|
||||
#define SDIO_R5_ERROR (1 << 11)
|
||||
|
||||
/* Register offsets and bits. */
|
||||
|
||||
#define SDIO_OCR_CARD_READY 0x80000000
|
||||
#define SDIO_OCR_NUM_FUNCS_MASK 0x70000000
|
||||
#define SDIO_OCR_NUM_FUNCS_OFFSET 28
|
||||
#define SDIO_OCR_VOLTAGE_3V3 0x00300000 /* 3.2-3.3V & 3.3-3.4V */
|
||||
|
||||
#define SDIO_CCCR_SDIO_REV 0x00
|
||||
#define SDIO_CCCR_SD_REV 0x01
|
||||
#define SDIO_CCCR_IO_EN 0x02
|
||||
#define SDIO_CCCR_IO_READY 0x03
|
||||
#define SDIO_CCCR_INT_EN 0x04
|
||||
# define SDIO_CCCR_INT_EN_MIE 0x01
|
||||
#define SDIO_CCCR_INT_PENDING 0x05
|
||||
#define SDIO_CCCR_IO_ABORT 0x06
|
||||
#define SDIO_CCCR_BUS_IFACE_CNTL 0x07
|
||||
# define SDIO_CCCR_BUS_IFACE_CNTL_CD_R_DISABLE 0x80
|
||||
# define SDIO_CCCR_BUS_IFACE_CNTL_ECSI 0x20
|
||||
# define SDIO_CCCR_BUS_IFACE_CNTL_4BIT_BUS 0x02
|
||||
#define SDIO_CCCR_CARD_CAPS 0x08
|
||||
# define SDIO_CCCR_CARD_CAPS_LSC 0x40
|
||||
# define SDIO_CCCR_CARD_CAPS_4BLS 0x80
|
||||
#define SDIO_CCCR_CIS_PTR 0x09
|
||||
#define SDIO_CCCR_BUS_SUSPEND 0x0c
|
||||
#define SDIO_CCCR_FUNC_SEL 0x0d
|
||||
#define SDIO_CCCR_EXEC_FLAGS 0x0e
|
||||
#define SDIO_CCCR_READY_FLAGS 0x0f
|
||||
#define SDIO_CCCR_F0_BLK_SIZE 0x10
|
||||
#define SDIO_CCCR_PWR_CNTL 0x12
|
||||
#define SDIO_CCCR_HIGH_SPEED 0x13
|
||||
# define SDIO_CCCR_HIGH_SPEED_SHS 0x01
|
||||
# define SDIO_CCCR_HIGH_SPEED_EHS 0x02
|
||||
|
||||
#define SDIO_FBR_REG(f, r) (0x100*(f) + (r))
|
||||
|
||||
#define SDIO_FBR_STD_IFACE(f) SDIO_FBR_REG(f, 0x00)
|
||||
#define SDIO_FBR_STD_IFACE_EXT(f) SDIO_FBR_REG(f, 0x01)
|
||||
#define SDIO_FBR_CIS_PTR(f) SDIO_FBR_REG(f, 0x09)
|
||||
#define SDIO_FBR_CSA_PTR(f) SDIO_FBR_REG(f, 0x0c)
|
||||
#define SDIO_FBR_CSA_DATA(f) SDIO_FBR_REG(f, 0x0f)
|
||||
#define SDIO_FBR_BLK_SIZE(f) SDIO_FBR_REG(f, 0x10)
|
||||
|
||||
#define SDIO_STD_IFACE_UART 0x01
|
||||
#define SDIO_STD_IFACE_BT_TYPE_A 0x02
|
||||
#define SDIO_STD_IFACE_BT_TYPE_B 0x03
|
||||
#define SDIO_STD_IFACE_GPS 0x04
|
||||
#define SDIO_STD_IFACE_CAMERA 0x05
|
||||
#define SDIO_STD_IFACE_PHS 0x06
|
||||
#define SDIO_STD_IFACE_WLAN 0x07
|
||||
#define SDIO_STD_IFACE_BT_TYPE_A_AMP 0x09
|
||||
|
||||
/*
|
||||
* Manufacturer and card IDs.
|
||||
*/
|
||||
#define SDIO_MANF_ID_CSR 0x032a
|
||||
|
||||
#define SDIO_CARD_ID_CSR_UNIFI_1 0x0001
|
||||
#define SDIO_CARD_ID_CSR_UNIFI_2 0x0002
|
||||
#define SDIO_CARD_ID_CSR_BC6 0x0004
|
||||
#define SDIO_CARD_ID_CSR_DASH_D00 0x0005
|
||||
#define SDIO_CARD_ID_CSR_BC7 0x0006
|
||||
#define SDIO_CARD_ID_CSR_CINDERELLA 0x0007
|
||||
#define SDIO_CARD_ID_CSR_UNIFI_3 0x0007
|
||||
#define SDIO_CARD_ID_CSR_UNIFI_4 0x0008
|
||||
#define SDIO_CARD_ID_CSR_DASH 0x0010
|
||||
|
||||
#endif /* #ifndef SDIOEMB_SDIO_H */
|
|
@ -1,408 +0,0 @@
|
|||
/*
|
||||
* SDIO device driver API.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SDIO_API_H
|
||||
#define _SDIO_API_H
|
||||
|
||||
/**
|
||||
* @defgroup fdriver SDIO function driver API
|
||||
*
|
||||
* @brief The SDIO function driver API is used to implement drivers
|
||||
* for SDIO card functions.
|
||||
*
|
||||
* Function drivers register with the SDIO driver core
|
||||
* (sdio_register_driver()), listing which functions it supports and
|
||||
* providing callback functions for card inserts, removes and
|
||||
* interrupts.
|
||||
*
|
||||
* @par \anchor card_io_ops Card I/O operations:
|
||||
*
|
||||
* - \link sdioemb_read8(struct sdioemb_dev *, uint32_t, uint8_t *) sdioemb_read8()\endlink
|
||||
* - \link sdioemb_read16(struct sdioemb_dev *, uint32_t, uint16_t *) sdioemb_read16()\endlink
|
||||
* - \link sdioemb_write8(struct sdioemb_dev *, uint32_t, uint8_t) sdioemb_write8()\endlink
|
||||
* - \link sdioemb_write16(struct sdioemb_dev *, uint32_t, uint16_t) sdioemb_write16()\endlink
|
||||
* - \link sdioemb_f0_read8(struct sdioemb_dev *, uint32_t, uint8_t *) sdioemb_f0_read8()\endlink
|
||||
* - \link sdioemb_f0_write8(struct sdioemb_dev *, uint32_t, uint8_t) sdioemb_f0_write8()\endlink
|
||||
* - \link sdioemb_read(struct sdioemb_dev *, uint32_t, void *, size_t) sdioemb_read()\endlink
|
||||
* - \link sdioemb_write(struct sdioemb_dev *, uint32_t, const void *, size_t) sdioemb_write()\endlink
|
||||
*/
|
||||
|
||||
struct sdioemb_func_driver;
|
||||
struct sdioemb_dev;
|
||||
struct sdioemb_dev_priv;
|
||||
|
||||
/**
|
||||
* An SDIO device.
|
||||
*
|
||||
* Each SDIO card will have an sdio_dev for each function.
|
||||
*
|
||||
* None of the fields (except for drv_data) should be written.
|
||||
*
|
||||
* @ingroup fdriver
|
||||
*/
|
||||
struct sdioemb_dev {
|
||||
struct sdioemb_func_driver *driver; /**< Function driver for this device. */
|
||||
uint16_t vendor_id; /**< Vendor ID of the card. */
|
||||
uint16_t device_id; /**< Device ID of the card. */
|
||||
int function; /**< Function number of this device. */
|
||||
uint8_t interface; /**< SDIO standard interface number. */
|
||||
uint16_t max_blocksize; /**< Maximum block size supported. */
|
||||
uint16_t blocksize; /**< Blocksize in use. */
|
||||
int slot_id; /**< ID of the slot this card is inserted into. */
|
||||
void * os_device; /**< Pointer to an OS-specific device structure. */
|
||||
struct sdioemb_dev_priv *priv; /**< Data private to the SDIO core. */
|
||||
void * drv_data; /**< Data private to the function driver. */
|
||||
};
|
||||
|
||||
#define SDIOEMB_ANY_ID 0xffff
|
||||
#define SDIOEMB_UIF_FUNC 0
|
||||
#define SDIOEMB_ANY_FUNC 0xff
|
||||
#define SDIOEMB_ANY_IFACE 0xff
|
||||
|
||||
/**
|
||||
* An entry for an SDIO device ID table.
|
||||
*
|
||||
* Functions are matched to drivers using any combination of vendor
|
||||
* ID, device ID, function number or standard interface.
|
||||
*
|
||||
* Matching on #function == SDIOEMB_UIF_FUNC is reserved for the SDIO
|
||||
* Userspace Interface driver. Card management drivers can match on
|
||||
* #function == 0, these will be probed before any function drivers.
|
||||
*
|
||||
* @ingroup fdriver
|
||||
*/
|
||||
struct sdioemb_id_table {
|
||||
uint16_t vendor_id; /**< Vendor ID to match or SDIOEMB_ANY_ID */
|
||||
uint16_t device_id; /**< Device ID to match or SDIOEMB_ANY_ID */
|
||||
int function; /**< Function number to match or SDIOEMB_ANY_FUNC */
|
||||
uint8_t interface; /**< SDIO standard interface to match or SDIOEMB_ANY_IFACE */
|
||||
};
|
||||
|
||||
/**
|
||||
* A driver for an SDIO function.
|
||||
*
|
||||
* @ingroup fdriver
|
||||
*/
|
||||
struct sdioemb_func_driver {
|
||||
/**
|
||||
* Driver name used in diagnostics.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* 0 terminated array of functions supported by this device.
|
||||
*
|
||||
* The driver may (for example) match on a number of vendor
|
||||
* ID/device ID/function number triplets or on an SDIO standard
|
||||
* interface.
|
||||
*/
|
||||
struct sdioemb_id_table *id_table;
|
||||
|
||||
/**
|
||||
* Called by the core when an inserted card has functions which
|
||||
* match those listed in id_table.
|
||||
*
|
||||
* The driver's implementation should (if required):
|
||||
*
|
||||
* - perform any additional probing
|
||||
* - do function specific initialization
|
||||
* - allocate and register any function/OS specific devices or interfaces.
|
||||
*
|
||||
* Called in: thread context.
|
||||
*
|
||||
* @param fdev the newly inserted device.
|
||||
*
|
||||
* @return 0 on success; -ve on error.
|
||||
*/
|
||||
int (*probe)(struct sdioemb_dev *fdev);
|
||||
|
||||
/**
|
||||
* Called by the core when a card is removed. This is only called
|
||||
* if the probe() call succeeded.
|
||||
*
|
||||
* The driver's implementation should (if required);
|
||||
*
|
||||
* - do any function specific shutdown.
|
||||
* - cleanup any data structures created/registers during probe().
|
||||
*
|
||||
* Called in: thread context.
|
||||
*
|
||||
* @param fdev the device being removed.
|
||||
*/
|
||||
void (*remove)(struct sdioemb_dev *fdev);
|
||||
|
||||
/**
|
||||
* Called by the core to signal an SDIO interrupt for this card
|
||||
* occurs, if interrupts have been enabled with
|
||||
* sdioemb_interrupt_enable().
|
||||
*
|
||||
* The driver's implementation should signal a thread (or similar)
|
||||
* to actually handle the interrupt as no card I/O may be
|
||||
* performed whilst in interrupt context. When the interrupt is
|
||||
* handled, the driver should call sdioemb_interrupt_acknowledge() to
|
||||
* enable further interrupts to be signalled.
|
||||
*
|
||||
* Called in: interrupt context.
|
||||
*
|
||||
* @param fdev the device which may have raised the interrupt.
|
||||
*/
|
||||
void (*card_int_handler)(struct sdioemb_dev *fdev);
|
||||
|
||||
/**
|
||||
* Called by the core to signal a suspend power management
|
||||
* event occured.
|
||||
*
|
||||
* The driver's implementation should (if required)
|
||||
* set the card to a low power mode and return as soon
|
||||
* as possible. After this function returns, the
|
||||
* driver should not start any SDIO commands.
|
||||
*
|
||||
* Called in: thread context.
|
||||
*
|
||||
* @param fdev the device handler.
|
||||
*/
|
||||
void (*suspend)(struct sdioemb_dev *fdev);
|
||||
|
||||
/**
|
||||
* Called by the core to signal a resume power management
|
||||
* event occured.
|
||||
*
|
||||
* The driver's implementation should (if required)
|
||||
* initialise the card to an operational mode and return
|
||||
* as soon as possible. If the card has been powered off
|
||||
* during suspend, the driver would have to initialise
|
||||
* the card from scratch (f/w download, h/w initialisation, etc.).
|
||||
*
|
||||
* Called in: thread context.
|
||||
*
|
||||
* @param fdev the device handler.
|
||||
*/
|
||||
void (*resume)(struct sdioemb_dev *fdev);
|
||||
};
|
||||
|
||||
int sdioemb_driver_register(struct sdioemb_func_driver *fdriver);
|
||||
void sdioemb_driver_unregister(struct sdioemb_func_driver *fdriver);
|
||||
|
||||
int sdioemb_driver_probe(struct sdioemb_func_driver *fdriver, struct sdioemb_dev *fdev);
|
||||
void sdioemb_driver_remove(struct sdioemb_func_driver *fdriver, struct sdioemb_dev *fdev);
|
||||
|
||||
/* For backward compatibility. */
|
||||
#define sdio_register_driver sdioemb_driver_register
|
||||
#define sdio_unregister_driver sdioemb_driver_unregister
|
||||
|
||||
int sdioemb_set_block_size(struct sdioemb_dev *fdev, uint16_t blksz);
|
||||
void sdioemb_set_max_bus_freq(struct sdioemb_dev *fdev, int max_freq);
|
||||
int sdioemb_set_bus_width(struct sdioemb_dev *fdev, int bus_width);
|
||||
|
||||
int sdioemb_enable_function(struct sdioemb_dev *fdev);
|
||||
int sdioemb_disable_function(struct sdioemb_dev *fdev);
|
||||
int sdioemb_reenable_csr_function(struct sdioemb_dev *dev);
|
||||
void sdioemb_idle_function(struct sdioemb_dev *fdev);
|
||||
|
||||
int sdioemb_read8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t *val);
|
||||
int sdioemb_read16(struct sdioemb_dev *fdev, uint32_t addr, uint16_t *val);
|
||||
int sdioemb_write8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t val);
|
||||
int sdioemb_write16(struct sdioemb_dev *fdev, uint32_t addr, uint16_t val);
|
||||
int sdioemb_f0_read8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t *val);
|
||||
int sdioemb_f0_write8(struct sdioemb_dev *fdev, uint32_t addr, uint8_t val);
|
||||
int sdioemb_read(struct sdioemb_dev *fdev, uint32_t addr, void *data, size_t len);
|
||||
int sdioemb_write(struct sdioemb_dev *fdev, uint32_t addr, const void *data, size_t len);
|
||||
|
||||
int sdioemb_hard_reset(struct sdioemb_dev *fdev);
|
||||
|
||||
void sdioemb_power_on(struct sdioemb_dev *fdev);
|
||||
void sdioemb_power_off(struct sdioemb_dev *fdev);
|
||||
|
||||
int sdioemb_interrupt_enable(struct sdioemb_dev *fdev);
|
||||
int sdioemb_interrupt_disable(struct sdioemb_dev *fdev);
|
||||
void sdioemb_interrupt_acknowledge(struct sdioemb_dev *fdev);
|
||||
|
||||
int sdioemb_cis_get_tuple(struct sdioemb_dev *fdev, uint8_t tuple,
|
||||
void *buf, size_t len);
|
||||
|
||||
void sdioemb_suspend_function(struct sdioemb_dev *fdev);
|
||||
void sdioemb_resume_function(struct sdioemb_dev *fdev);
|
||||
|
||||
/**
|
||||
* SDIO command status.
|
||||
*
|
||||
* @ingroup fdriver
|
||||
*/
|
||||
enum sdioemb_cmd_status {
|
||||
SDIOEMB_CMD_OK = 0x00, /**< Command successful. */
|
||||
|
||||
SDIOEMB_CMD_ERR_CMD = 0x01,
|
||||
SDIOEMB_CMD_ERR_DAT = 0x02,
|
||||
|
||||
SDIOEMB_CMD_ERR_CRC = 0x10,
|
||||
SDIOEMB_CMD_ERR_TIMEOUT = 0x20,
|
||||
SDIOEMB_CMD_ERR_OTHER = 0x40,
|
||||
|
||||
SDIOEMB_CMD_ERR_CMD_CRC = SDIOEMB_CMD_ERR_CMD | SDIOEMB_CMD_ERR_CRC, /**< Response CRC error. */
|
||||
SDIOEMB_CMD_ERR_CMD_TIMEOUT = SDIOEMB_CMD_ERR_CMD | SDIOEMB_CMD_ERR_TIMEOUT, /**< Response time out. */
|
||||
SDIOEMB_CMD_ERR_CMD_OTHER = SDIOEMB_CMD_ERR_CMD | SDIOEMB_CMD_ERR_OTHER, /**< Other response error. */
|
||||
SDIOEMB_CMD_ERR_DAT_CRC = SDIOEMB_CMD_ERR_DAT | SDIOEMB_CMD_ERR_CRC, /**< Data CRC error. */
|
||||
SDIOEMB_CMD_ERR_DAT_TIMEOUT = SDIOEMB_CMD_ERR_DAT | SDIOEMB_CMD_ERR_TIMEOUT, /**< Data receive time out. */
|
||||
SDIOEMB_CMD_ERR_DAT_OTHER = SDIOEMB_CMD_ERR_DAT | SDIOEMB_CMD_ERR_OTHER, /**< Other data error. */
|
||||
|
||||
SDIOEMB_CMD_ERR_NO_CARD = 0x04, /**< No card present. */
|
||||
|
||||
SDIOEMB_CMD_IN_PROGRESS = 0xff, /**< Command still in progress. */
|
||||
};
|
||||
|
||||
/**
|
||||
* A response to an SDIO command.
|
||||
*
|
||||
* For R1, R4, R5, and R6 responses only the middle 32 bits of the
|
||||
* response are stored, the leading octet (start and direction bits
|
||||
* and command index) and trailing octet (CRC and stop bit) are
|
||||
* discarded.
|
||||
*
|
||||
* @bug R2 and R3 responses are not used by SDIO and are not
|
||||
* supported.
|
||||
*
|
||||
* @ingroup fdriver
|
||||
*/
|
||||
union sdioemb_response {
|
||||
uint32_t r1;
|
||||
uint32_t r4;
|
||||
uint32_t r5;
|
||||
uint32_t r6;
|
||||
};
|
||||
|
||||
/**
|
||||
* SDIO command parameters and response.
|
||||
*/
|
||||
struct sdioemb_cmd_resp {
|
||||
uint8_t cmd; /**< Command index (0 to 63). */
|
||||
uint32_t arg; /**< Command argument. */
|
||||
union sdioemb_response response; /**< Response to the command. Valid
|
||||
iff the command has completed and
|
||||
(sdio_cmd::status & SDIOEMB_CMD_ERR_CMD) == 0.*/
|
||||
};
|
||||
|
||||
/**
|
||||
* CSPI command parameters and response.
|
||||
*/
|
||||
struct cspi_cmd_resp {
|
||||
unsigned cmd : 8; /**< Command octet (type, and function). */
|
||||
unsigned addr: 24; /**< 24 bit address. */
|
||||
uint16_t val; /**< Word to write or read from the card (for non-burst commands). */
|
||||
uint8_t response; /**< Response octet. Valid iff the command has completed and
|
||||
(sdio_cmd::status & SDIOEMB_CMD_ERR_CMD) == 0. */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An SDIO command, its status and response.
|
||||
*
|
||||
* sdio_cmd is used to submit SDIO commands to a device and return its
|
||||
* status and any response or data.
|
||||
*
|
||||
* @ingroup fdriver
|
||||
*/
|
||||
struct sdioemb_cmd {
|
||||
/**
|
||||
* The SDIO device which submitted the command. Set by the
|
||||
* core.
|
||||
*/
|
||||
struct sdioemb_dev *owner;
|
||||
|
||||
/**
|
||||
* Called by the core when the command has been completed.
|
||||
*
|
||||
* Called in: interrupt context.
|
||||
*
|
||||
* @param cmd the completed command.
|
||||
*/
|
||||
void (*callback)(struct sdioemb_cmd *cmd);
|
||||
|
||||
/**
|
||||
* Set of flags specifying the response type, data transfer
|
||||
* direction and other parameters.
|
||||
*
|
||||
* For SDIO commands set at least one of the response types:
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_NONE
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R1
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R1B
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R2
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R3
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R4
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R5
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R5B
|
||||
* - #SDIOEMB_CMD_FLAG_RESP_R6
|
||||
*
|
||||
* and any of the additional flags:
|
||||
* - #SDIOEMB_CMD_FLAG_READ
|
||||
*
|
||||
* For CSPI commands set:
|
||||
* - #SDIOEMB_CMD_FLAG_CSPI
|
||||
*/
|
||||
unsigned flags;
|
||||
|
||||
/**
|
||||
* SDIO command parameters and response.
|
||||
*
|
||||
* Valid only if #SDIOEMB_CMD_FLAG_CSPI is \e not set in #flags.
|
||||
*/
|
||||
struct sdioemb_cmd_resp sdio;
|
||||
|
||||
/**
|
||||
* CSPI command parameters and response.
|
||||
*
|
||||
* Valid only if #SDIOEMB_CMD_FLAG_CSPI is set in #flags.
|
||||
*/
|
||||
struct cspi_cmd_resp cspi;
|
||||
|
||||
/**
|
||||
* Buffer of data to read or write.
|
||||
*
|
||||
* Must be set to NULL if the command is not a data transfer.
|
||||
*/
|
||||
uint8_t *data;
|
||||
|
||||
/**
|
||||
* Length of #data in octets.
|
||||
*
|
||||
* len must be either: less than the device's sdio_dev::blocksize;
|
||||
* or a multiple of the device's sdio_dev::blocksize.
|
||||
*/
|
||||
size_t len;
|
||||
|
||||
/**
|
||||
* Status of the command after it has completed.
|
||||
*/
|
||||
enum sdioemb_cmd_status status;
|
||||
|
||||
/**
|
||||
* Data private to caller of sdioemb_start_cmd().
|
||||
*/
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/** @addtogroup fdriver
|
||||
*@{*/
|
||||
#define SDIOEMB_CMD_FLAG_RESP_NONE 0x00 /**< No response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R1 0x01 /**< R1 response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R1B 0x02 /**< R1b response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R2 0x03 /**< R2 response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R3 0x04 /**< R3 response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R4 0x05 /**< R4 response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R5 0x06 /**< R5 response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R5B 0x07 /**< R5b response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_R6 0x08 /**< R6 response. */
|
||||
#define SDIOEMB_CMD_FLAG_RESP_MASK 0xff /**< Mask for response type. */
|
||||
#define SDIOEMB_CMD_FLAG_RAW 0x0100 /**< @internal Bypass the command queues. */
|
||||
#define SDIOEMB_CMD_FLAG_READ 0x0200 /**< Data transfer is a read, not a write. */
|
||||
#define SDIOEMB_CMD_FLAG_CSPI 0x0400 /**< CSPI transfer, not SDIO or SDIO-SPI. */
|
||||
#define SDIOEMB_CMD_FLAG_ABORT 0x0800 /**< Data transfer abort command. */
|
||||
/*@}*/
|
||||
|
||||
int sdioemb_start_cmd(struct sdioemb_dev *fdev, struct sdioemb_cmd *cmd);
|
||||
|
||||
#endif /* #ifndef _SDIO_API_H */
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
* SDIO Bluetooth Type-A interface definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef SDIOEMB_SDIO_BT_A_H
|
||||
#define SDIOEMB_SDIO_BT_A_H
|
||||
|
||||
#include <sdioemb/sdio_csr.h>
|
||||
#include <csr_sdio.h>
|
||||
|
||||
/*
|
||||
* Standard SDIO function registers for a Bluetooth Type-A interface.
|
||||
*/
|
||||
#define SDIO_BT_A_RD 0x00
|
||||
#define SDIO_BT_A_TD 0x00
|
||||
|
||||
#define SDIO_BT_A_RX_PKT_CTRL 0x10
|
||||
# define PC_RRT 0x01
|
||||
|
||||
#define SDIO_BT_A_TX_PKT_CTRL 0x11
|
||||
# define PC_WRT 0x01
|
||||
|
||||
#define SDIO_BT_A_RETRY_CTRL 0x12
|
||||
# define RTC_STAT 0x01
|
||||
# define RTC_SET 0x01
|
||||
|
||||
#define SDIO_BT_A_INTRD 0x13
|
||||
# define INTRD 0x01
|
||||
# define CL_INTRD 0x01
|
||||
|
||||
#define SDIO_BT_A_INT_EN 0x14
|
||||
# define EN_INTRD 0x01
|
||||
|
||||
#define SDIO_BT_A_BT_MODE 0x20
|
||||
# define MD_STAT 0x01
|
||||
|
||||
/*
|
||||
* Length of the Type-A header.
|
||||
*
|
||||
* Packet length (3 octets) plus Service ID (1 octet).
|
||||
*/
|
||||
#define SDIO_BT_A_HEADER_LEN 4
|
||||
|
||||
/*
|
||||
* Maximum length of a Type-A transport packet.
|
||||
*
|
||||
* Type-A header length and maximum length of a HCI packet (65535
|
||||
* octets).
|
||||
*/
|
||||
#define SDIO_BT_A_PACKET_LEN_MAX 65543
|
||||
|
||||
enum sdioemb_bt_a_service_id {
|
||||
SDIO_BT_A_SID_CMD = 0x01,
|
||||
SDIO_BT_A_SID_ACL = 0x02,
|
||||
SDIO_BT_A_SID_SCO = 0x03,
|
||||
SDIO_BT_A_SID_EVT = 0x04,
|
||||
SDIO_BT_A_SID_VENDOR = 0xfe,
|
||||
};
|
||||
|
||||
static __inline int sdioemb_bt_a_packet_len(const char *p)
|
||||
{
|
||||
return (p[0] & 0xff) | ((p[1] & 0xff) << 8) | ((p[2] & 0xff) << 16);
|
||||
}
|
||||
|
||||
static __inline int sdioemb_bt_a_service_id(const char *p)
|
||||
{
|
||||
return p[3];
|
||||
}
|
||||
|
||||
/*
|
||||
* Minimum amount to read (including the Type-A header). This allows
|
||||
* short packets (e.g., flow control packets) to be read with a single
|
||||
* command.
|
||||
*/
|
||||
#define SDIO_BT_A_MIN_READ 32
|
||||
|
||||
#define SDIO_BT_A_NAME_LEN 16
|
||||
|
||||
struct sdioemb_bt_a_dev {
|
||||
CsrSdioFunction *func;
|
||||
char name[SDIO_BT_A_NAME_LEN];
|
||||
void *drv_data;
|
||||
|
||||
/**
|
||||
* Get a buffer to receive a packet into.
|
||||
*
|
||||
* @param bt the BT device.
|
||||
* @param header a buffer of length #SDIO_BT_A_MIN_READ containing
|
||||
* (part of) the packet the buffer is for. It will contain
|
||||
* the Type-A header and as much of the payload that will
|
||||
* fit.
|
||||
* @param buffer_min_len the minimum length of buffer required to
|
||||
* receive the whole packet. This includes space for padding
|
||||
* the read to a whole number of blocks (if more than 512
|
||||
* octets is still to be read).
|
||||
* @param buffer returns the buffer. The packet (including the
|
||||
* Type-A header will be placed at the beginning of this
|
||||
* buffer.
|
||||
* @param buffer_handle returns a buffer handle passed to the
|
||||
* subsequent call of the receive() callback.
|
||||
*
|
||||
* @return 0 if a buffer was provided.
|
||||
* @return -ENOMEM if no buffer could be provided.
|
||||
*/
|
||||
int (*get_rx_buffer)(struct sdioemb_bt_a_dev *bt, const uint8_t *header,
|
||||
size_t buffer_min_len, uint8_t **buffer, void **buffer_handle);
|
||||
void (*receive)(struct sdioemb_bt_a_dev *bt, void *buffer_handle, int status);
|
||||
void (*sleep_state_changed)(struct sdioemb_bt_a_dev *bt);
|
||||
|
||||
enum sdio_sleep_state sleep_state;
|
||||
|
||||
uint8_t max_tx_retries;
|
||||
uint8_t max_rx_retries;
|
||||
unsigned needs_read_ack:1;
|
||||
unsigned wait_for_firmware:1;
|
||||
|
||||
unsigned rx_off:1;
|
||||
|
||||
/**
|
||||
* A buffer to read the packet header into before the real buffer
|
||||
* is requested with the get_rx_buffer() callback.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
uint8_t *header;
|
||||
};
|
||||
|
||||
int sdioemb_bt_a_setup(struct sdioemb_bt_a_dev *bt, CsrSdioFunction *func);
|
||||
void sdioemb_bt_a_cleanup(struct sdioemb_bt_a_dev *bt);
|
||||
int sdioemb_bt_a_send(struct sdioemb_bt_a_dev *bt, const uint8_t *packet, size_t len);
|
||||
void sdioemb_bt_a_handle_interrupt(struct sdioemb_bt_a_dev *bt);
|
||||
void sdioemb_bt_a_set_sleep_state(struct sdioemb_bt_a_dev *bt, enum sdio_sleep_state state);
|
||||
int sdioemb_bt_a_check_for_reset(struct sdioemb_bt_a_dev *bt);
|
||||
void sdioemb_bt_a_start(struct sdioemb_bt_a_dev *bt);
|
||||
void sdioemb_bt_a_stop(struct sdioemb_bt_a_dev *bt);
|
||||
void sdioemb_bt_a_rx_on(struct sdioemb_bt_a_dev *bt);
|
||||
void sdioemb_bt_a_rx_off(struct sdioemb_bt_a_dev *bt);
|
||||
|
||||
#endif /* #ifndef SDIOEMB_SDIO_BT_A_H */
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* SDIO CIS definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SDIO_CIS_H
|
||||
#define _SDIO_CIS_H
|
||||
|
||||
#define CISTPL_NULL 0x00
|
||||
#define CISTPL_CHECKSUM 0x10
|
||||
#define CISTPL_VERS_1 0x15
|
||||
#define CISTPL_ALTSTR 0x16
|
||||
#define CISTPL_MANFID 0x20
|
||||
# define CISTPL_MANFID_SIZE 0x04
|
||||
#define CISTPL_FUNCID 0x21
|
||||
#define CISTPL_FUNCE 0x22
|
||||
#define CISTPL_SDIO_STD 0x91
|
||||
#define CISTPL_SDIO_EXT 0x92
|
||||
#define CISTPL_END 0xff
|
||||
#define CISTPL_FUNCE 0x22
|
||||
# define CISTPL_FUNCE_00_SIZE 0x04
|
||||
# define CISTPL_FUNCE_01_SIZE 0x2a
|
||||
|
||||
#endif /* #ifndef _SDIO_CIS_H */
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* CSR specific SDIO registers.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef SDIOEMB_SDIO_CSR_H
|
||||
#define SDIOEMB_SDIO_CSR_H
|
||||
|
||||
/**
|
||||
* @defgroup registers CSR specific SDIO registers
|
||||
*
|
||||
* Registers at 0xF0 - 0xFF in the CCCR are reserved for vendor
|
||||
* specific registers. The registers documented here are specific to
|
||||
* following CSR chips:
|
||||
*
|
||||
* - BlueCore (6 and later)
|
||||
* - UltraCore
|
||||
*@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interrupt status/host wakeup register.
|
||||
*
|
||||
* This controls a function's deep sleep state.
|
||||
*
|
||||
* @see enum sdio_sleep_state
|
||||
*/
|
||||
#define SDIO_CSR_SLEEP_STATE 0xf0
|
||||
# define SDIO_CSR_SLEEP_STATE_FUNC(f) ((f) << 4)
|
||||
# define SDIO_CSR_SLEEP_STATE_RDY_INT_EN 0x02
|
||||
# define SDIO_CSR_SLEEP_STATE_WAKE_REQ 0x01
|
||||
|
||||
/**
|
||||
* Host interrupt clear register.
|
||||
*
|
||||
* Writing a 1 to bit 0 clears an SDIO interrupt raised by a generic
|
||||
* function.
|
||||
*/
|
||||
#define SDIO_CSR_HOST_INT 0xf1
|
||||
# define SDIO_CSR_HOST_INT_CL 0x01
|
||||
|
||||
/**
|
||||
* From host scratch register 0.
|
||||
*
|
||||
* A read/write register that can be used for signalling between the
|
||||
* host and the chip.
|
||||
*
|
||||
* The usage of this register depends on the version of the chip or
|
||||
* firmware.
|
||||
*/
|
||||
#define SDIO_CSR_FROM_HOST_SCRATCH0 0xf2
|
||||
|
||||
/**
|
||||
* From host scratch register 1.
|
||||
*
|
||||
* @see SDIO_CSR_FROM_HOST_SCRATCH0
|
||||
*/
|
||||
#define SDIO_CSR_FROM_HOST_SCRATCH1 0xf3
|
||||
|
||||
/**
|
||||
* To host scratch register 0.
|
||||
*
|
||||
* A read only register that may be used for signalling between the
|
||||
* chip and the host.
|
||||
*
|
||||
* The usage of this register depends on the version of the chip or
|
||||
* firmware.
|
||||
*/
|
||||
#define SDIO_CSR_TO_HOST_SCRATCH0 0xf4
|
||||
|
||||
/**
|
||||
* To host scratch register 1.
|
||||
*
|
||||
* @see SDIO_CSR_TO_HOST_SCRATCH0
|
||||
*/
|
||||
#define SDIO_CSR_TO_HOST_SCRATCH1 0xf5
|
||||
|
||||
/**
|
||||
* Extended I/O enable.
|
||||
*
|
||||
* Similar to the standard CCCR I/O Enable register, this is used to
|
||||
* detect if an internal reset of a function has occured and
|
||||
* (optionally) reenable it.
|
||||
*
|
||||
* An internal reset is detected by CCCR I/O Enable bit being set and
|
||||
* the corresponding EXT_IO_EN bit being clear.
|
||||
*/
|
||||
#define SDIO_CSR_EXT_IO_EN 0xf6
|
||||
|
||||
/**
|
||||
* Deep sleep states as set via the sleep state register.
|
||||
*
|
||||
* These states are used to control when the chip may go into a deep
|
||||
* sleep (a low power mode).
|
||||
*
|
||||
* Since a chip in deep sleep may not respond to SDIO commands, the
|
||||
* host should ensure that the chip is not in deep sleep before
|
||||
* attempting SDIO commands to functions 1 to 7.
|
||||
*
|
||||
* The available states are:
|
||||
*
|
||||
* AWAKE - chip must not enter deep sleep and should exit deep sleep
|
||||
* if it's currently sleeping.
|
||||
*
|
||||
* TORPID - chip may enter deep sleep.
|
||||
*
|
||||
* DROWSY - a transition state between TORPID and AWAKE. This is
|
||||
* AWAKE plus the chip asserts an interrupt when the chip is awake.
|
||||
*
|
||||
* @see SDIO_CSR_SLEEP_STATE
|
||||
*/
|
||||
enum sdio_sleep_state {
|
||||
SLEEP_STATE_AWAKE = SDIO_CSR_SLEEP_STATE_WAKE_REQ,
|
||||
SLEEP_STATE_DROWSY = SDIO_CSR_SLEEP_STATE_WAKE_REQ | SDIO_CSR_SLEEP_STATE_RDY_INT_EN,
|
||||
SLEEP_STATE_TORPID = 0x00,
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*
|
||||
* Generic function registers (with byte addresses).
|
||||
*/
|
||||
|
||||
/*
|
||||
* SDIO_MODE is chip dependant, see the sdio_mode table in sdio_cspi.c
|
||||
* to add support for new chips.
|
||||
*/
|
||||
#define SDIO_MODE /* chip dependant */
|
||||
# define SDIO_MODE_CSPI_EN 0x40
|
||||
|
||||
#endif /* SDIOEMB_SDIO_CSR_H */
|
|
@ -1,313 +0,0 @@
|
|||
/*
|
||||
* Slot driver API.
|
||||
*
|
||||
* Copyright (C) 2007-2009 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SLOT_API_H
|
||||
#define _SLOT_API_H
|
||||
|
||||
#include <sdioemb/sdio_api.h>
|
||||
|
||||
struct sdioemb_slot;
|
||||
|
||||
/**
|
||||
* @defgroup sdriver SDIO slot driver API
|
||||
*
|
||||
* @brief The SDIO slot driver API provides an interface for the SDIO
|
||||
* layer to driver an SDIO slot (socket).
|
||||
*
|
||||
* Slot drivers register with the SDIO layer (sdioemb_slot_register()),
|
||||
* providing functions to starting commands, enabling/disable card
|
||||
* interrupts, card detection and bus power control.
|
||||
*
|
||||
* Functions are provided to notify the SDIO layer when a command has
|
||||
* completed (sdioemb_cmd_complete()) and when an SDIO card interrupt has
|
||||
* occurred (sdioemb_interrupt()).
|
||||
*/
|
||||
|
||||
#define SDIOEMB_BUS_FREQ_OFF 0
|
||||
#define SDIOEMB_BUS_FREQ_DEFAULT -1
|
||||
#define SDIOEMB_BUS_FREQ_IDLE -2
|
||||
|
||||
/**
|
||||
* Valid SDIO bus voltage levels.
|
||||
*
|
||||
* @ingroup sdriver
|
||||
*/
|
||||
enum sdioemb_power {
|
||||
SDIOEMB_POWER_OFF = 0, /**< Power switched off. */
|
||||
SDIOEMB_POWER_3V3 = 33, /**< Voltage set to 3.3V. */
|
||||
};
|
||||
|
||||
/**
|
||||
* SDIO slot capabilities.
|
||||
*
|
||||
* @ingroup sdriver
|
||||
*/
|
||||
struct slot_caps {
|
||||
int max_bus_freq; /**< Maximum bus frequency (Hz). */
|
||||
int max_bus_width; /**< Maximum bus width supported (1 or 4 data lines). */
|
||||
uint8_t cspi_mode; /**< CSPI_MODE register value (for CSPI capable slots). */
|
||||
};
|
||||
|
||||
/**
|
||||
* Controller hardware type.
|
||||
*
|
||||
* @ingroup sdriver
|
||||
*/
|
||||
enum slot_controller_type {
|
||||
SDIOEMB_SLOT_TYPE_SD = 0, /**< SD/SDIO controller. */
|
||||
SDIOEMB_SLOT_TYPE_SPI, /**< SPI controller. */
|
||||
SDIOEMB_SLOT_TYPE_SPI_CSPI, /**< SPI controller capable of CSPI. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Return values from the add_function() notifier.
|
||||
*
|
||||
* @ingroup sdriver
|
||||
*/
|
||||
enum sdioemb_add_func_status {
|
||||
/**
|
||||
* The core will call sdioemb_add_function().
|
||||
*/
|
||||
SDIOEMB_ADD_FUNC_NOW = 0,
|
||||
/**
|
||||
* The slot driver will call sdioemb_add_function() or the
|
||||
* function driver will call sdioemb_driver_probe() directly.
|
||||
*/
|
||||
SDIOEMB_ADD_FUNC_DEFERRED = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Slot/card event notifiers.
|
||||
*
|
||||
* A slot driver may be notified when certain slot or card events
|
||||
* occur.
|
||||
*
|
||||
* @ingroup sdriver
|
||||
*/
|
||||
struct sdioemb_slot_notifiers {
|
||||
/**
|
||||
* This is called when a card function has been enumerated
|
||||
* and initialized but before can be bound to a function driver.
|
||||
*
|
||||
* A slot driver may use this to create an OS-specific object for
|
||||
* the function. The slot driver must either (a) return
|
||||
* SDIOEMB_ADD_FUNC_NOW; (b) return SDIOEMB_ADD_FUNC_DEFERRED and
|
||||
* call sdioemb_add_function() later on; (c) return
|
||||
* SDIOEMB_ADD_FUNC_DEFERRED and pass the fdev to the function
|
||||
* driver for it to call sdioemb_driver_probe() directly; or (d)
|
||||
* return an error.
|
||||
*
|
||||
* The slot driver may need to get a reference to the fdev with
|
||||
* sdioemb_get_function() if the lifetime of the OS-specific
|
||||
* object extends beyond the subsequent return of the
|
||||
* del_function() callback.
|
||||
*
|
||||
* If this is non-NULL the slot driver must also provide
|
||||
* del_function().
|
||||
*
|
||||
* @param slot the SDIO slot producing the notification.
|
||||
* @param fdev the SDIO function being added.
|
||||
*
|
||||
* @return SDIOEMB_ADD_FUNC_NOW if the function is ready for use.
|
||||
* @return SDIOEMB_ADD_FUNC_DEFERRED if sdioemb_add_function() or
|
||||
* sdioemb_driver_probe() will be called later.
|
||||
* @return -ve on a error.
|
||||
*/
|
||||
int (*add_function)(struct sdioemb_slot *slot, struct sdioemb_dev *fdev);
|
||||
|
||||
/**
|
||||
* This is called when a card function is being removed and after
|
||||
* any function driver has been unbound.
|
||||
*
|
||||
* A slot driver may use this to delete any OS-specific object
|
||||
* created by the add_function() notifier.
|
||||
*
|
||||
* @param slot the SDIO slot producing the notification.
|
||||
* @param fdev the SDIO function being deleted.
|
||||
*/
|
||||
void (*del_function)(struct sdioemb_slot *slot, struct sdioemb_dev *fdev);
|
||||
};
|
||||
|
||||
struct sdioemb_slot_priv;
|
||||
|
||||
/**
|
||||
* An SDIO slot driver.
|
||||
*
|
||||
* Allocate and free with sdioemb_slot_alloc() and sdioemb_slot_free().
|
||||
*
|
||||
* @ingroup sdriver
|
||||
*/
|
||||
struct sdioemb_slot {
|
||||
/**
|
||||
* Name of the slot used in diagnostic messages.
|
||||
*
|
||||
* This would typically include the name of the SDIO controller
|
||||
* and the slot number if the controller has multiple slots.
|
||||
*
|
||||
* This will be set by sdioemb_slot_register() if it is left as an
|
||||
* empty string.
|
||||
*/
|
||||
char name[64];
|
||||
|
||||
/**
|
||||
* Controller hardware type.
|
||||
*/
|
||||
enum slot_controller_type type;
|
||||
|
||||
/**
|
||||
* Set the SD bus clock frequency.
|
||||
*
|
||||
* The driver's implementation should set the SD bus clock to not
|
||||
* more than \a clk Hz (unless \a clk is equal to
|
||||
* #SDIOEMB_BUS_FREQ_OFF or #SDIOEMB_BUS_FREQ_IDLE).
|
||||
*
|
||||
* If \a clk == SDIOEMB_BUS_FREQ_OFF the clock should be stopped.
|
||||
*
|
||||
* \a clk == SDIOEMB_BUS_FREQ_IDLE indicates that the bus is idle
|
||||
* (currently unused) and the host controller may slow (or stop)
|
||||
* the SD bus clock to save power on the card. During this idle
|
||||
* state the host controller must be capable of receiving SDIO
|
||||
* interrupts (for certain host controllers this may require
|
||||
* leaving the clock running).
|
||||
*
|
||||
* If \a clk is greater than #SDIO_CLOCK_FREQ_NORMAL_SPD (25 MHz)
|
||||
* subsequent commands should be done with the controller in high
|
||||
* speed mode.
|
||||
*
|
||||
* Called from: interrupt context.
|
||||
*
|
||||
* @param slot the slot to configure.
|
||||
* @param clk new SD bus clock frequency in Hz, SDIOEMB_BUS_FREQ_OFF
|
||||
* or SDIOEMB_BUS_FREQ_IDLE.
|
||||
*
|
||||
* @return The bus frequency actually configured in Hz.
|
||||
*/
|
||||
int (*set_bus_freq)(struct sdioemb_slot *slot, int clk);
|
||||
|
||||
/**
|
||||
* Set the SD bus width.
|
||||
*
|
||||
* The driver's implementation should set the width of the SD bus
|
||||
* for all subsequent data transfers to the specified value.
|
||||
*
|
||||
* This may be NULL if the driver sets the bus width when starting
|
||||
* a command, or the driver is for an SDIO-SPI or CSPI controller.
|
||||
*
|
||||
* Called from: thread context.
|
||||
*
|
||||
* @param slot the slot to configure.
|
||||
* @param bus_width new SD bus width (either 1 or 4).
|
||||
*
|
||||
* @return 0 on success.
|
||||
* @return -ve if a low-level error occured when setting the bus width.
|
||||
*/
|
||||
int (*set_bus_width)(struct sdioemb_slot *slot, int bus_width);
|
||||
|
||||
/**
|
||||
* Start an SDIO command.
|
||||
*
|
||||
* The driver's implementation should:
|
||||
*
|
||||
* - set the controller's bus width to #bus_width,
|
||||
* - program the controller to start the command.
|
||||
*
|
||||
* Called from: interrupt context.
|
||||
*
|
||||
* @param slot slot to perform the command.
|
||||
* @param cmd SDIO command to start.
|
||||
*/
|
||||
int (*start_cmd)(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd);
|
||||
|
||||
/**
|
||||
* Detect if a card is inserted into the slot.
|
||||
*
|
||||
* Called from: thread context.
|
||||
*
|
||||
* @param slot slot to check.
|
||||
*
|
||||
* @return non-zero if a card is inserted; 0 otherwise.
|
||||
*/
|
||||
int (*card_present)(struct sdioemb_slot *slot);
|
||||
|
||||
/**
|
||||
* Switch on/off the SDIO bus power and set the SDIO bus voltage.
|
||||
*
|
||||
* Called from: thread context.
|
||||
*
|
||||
* @param slot the slot.
|
||||
* @param power the requested voltage.
|
||||
*
|
||||
* @return 0 on success; -ve on error: -EINVAL - requested voltage
|
||||
* is not supported.
|
||||
*/
|
||||
int (*card_power)(struct sdioemb_slot *slot, enum sdioemb_power power);
|
||||
|
||||
/**
|
||||
* Enable (unmask) the SDIO card interrupt on the controller.
|
||||
*
|
||||
* Called from: interrupt context.
|
||||
*
|
||||
* @param slot the slot to enable the interrupt on..
|
||||
*/
|
||||
void (*enable_card_int)(struct sdioemb_slot *slot);
|
||||
|
||||
/**
|
||||
* Disable (mask) the SDIO card interrupt on the controller.
|
||||
*
|
||||
* Called from: thread context.
|
||||
*
|
||||
* @param slot the slot to disable the interrupt on.
|
||||
*/
|
||||
void (*disable_card_int)(struct sdioemb_slot *slot);
|
||||
|
||||
/**
|
||||
* Perform a hard reset of the card.
|
||||
*
|
||||
* Hard resets can be achieved in two ways:
|
||||
*
|
||||
* -# Power cycle (if the slot has power control).
|
||||
* -# Platform-specific assertion of a card/chip reset line.
|
||||
*
|
||||
* If hard resets are not supported, either return 0 or set
|
||||
* hard_reset to NULL.
|
||||
*
|
||||
* @param slot the slot for the card to reset.
|
||||
*
|
||||
* @return 0 if a hard reset was performed.
|
||||
* @return 1 if hard resets are not supported.
|
||||
*/
|
||||
int (*hard_reset)(struct sdioemb_slot *slot);
|
||||
|
||||
struct slot_caps caps; /**< Slot capabilities. */
|
||||
int clock_freq; /**< SD bus frequency requested by the SDIO layer. */
|
||||
int bus_width; /**< Bus width requested by the SDIO layer. */
|
||||
struct sdioemb_slot_notifiers notifs; /**< Slot event notifiers. */
|
||||
int cspi_reg_pad; /**< Padding for CSPI register reads. */
|
||||
int cspi_burst_pad; /**< Padding for CSPI burst reads. */
|
||||
struct sdioemb_slot_priv *priv; /**< Data private to the SDIO layer. */
|
||||
void * drv_data; /**< Data private to the slot driver. */
|
||||
};
|
||||
|
||||
struct sdioemb_slot *sdioemb_slot_alloc(size_t drv_data_size);
|
||||
void sdioemb_slot_free(struct sdioemb_slot *slot);
|
||||
int sdioemb_slot_register(struct sdioemb_slot *slot);
|
||||
void sdioemb_slot_unregister(struct sdioemb_slot *slot);
|
||||
int sdioemb_card_inserted(struct sdioemb_slot *slot);
|
||||
void sdioemb_card_removed(struct sdioemb_slot *slot);
|
||||
void sdioemb_interrupt(struct sdioemb_slot *slot);
|
||||
void sdioemb_cmd_complete(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd);
|
||||
|
||||
void sdioemb_suspend(struct sdioemb_slot *slot);
|
||||
void sdioemb_resume(struct sdioemb_slot *slot);
|
||||
|
||||
void sdioemb_add_function(struct sdioemb_dev *fdev);
|
||||
void sdioemb_del_function(struct sdioemb_dev *fdev);
|
||||
void sdioemb_get_function(struct sdioemb_dev *fdev);
|
||||
void sdioemb_put_function(struct sdioemb_dev *fdev);
|
||||
|
||||
#endif /* #ifndef _SLOT_API_H */
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* i.MX27 SDHC definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SLOT_IMX27_H
|
||||
#define _SLOT_IMX27_H
|
||||
|
||||
/*
|
||||
* i.MX27 SDHC registers.
|
||||
*/
|
||||
|
||||
#define SDHC_STR_STP_CLK 0x00
|
||||
# define STR_STP_CLK_MMCSD_RESET 0x0008
|
||||
# define STR_STP_CLK_START_CLK 0x0002
|
||||
# define STR_STP_CLK_STOP_CLK 0x0001
|
||||
|
||||
#define SDHC_STATUS 0x04
|
||||
# define STATUS_CARD_PRESENCE 0x8000
|
||||
# define STATUS_SDIO_INT_ACTIVE 0x4000
|
||||
# define STATUS_END_CMD_RESP 0x2000
|
||||
# define STATUS_WRITE_OP_DONE 0x1000
|
||||
# define STATUS_READ_OP_DONE 0x0800
|
||||
# define STATUS_CARD_BUS_CLK_RUN 0x0100
|
||||
# define STATUS_APPL_BUFF_FF 0x0080
|
||||
# define STATUS_APPL_BUFF_FE 0x0040
|
||||
# define STATUS_RESP_CRC_ERR 0x0020
|
||||
# define STATUS_CRC_READ_ERR 0x0008
|
||||
# define STATUS_CRC_WRITE_ERR 0x0004
|
||||
# define STATUS_TIME_OUT_RESP 0x0002
|
||||
# define STATUS_TIME_OUT_READ 0x0001
|
||||
# define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP)
|
||||
# define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ)
|
||||
# define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK)
|
||||
|
||||
#define SDHC_CLK_RATE 0x08
|
||||
|
||||
#define SDHC_CMD_DAT_CTRL 0x0c /* CMD_DAT_CONT */
|
||||
# define CMD_DAT_CTRL_CMD_RESUME 0x8000
|
||||
# define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000
|
||||
# define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800
|
||||
# define CMD_DAT_CTRL_START_READ_WAIT 0x0400
|
||||
# define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200
|
||||
# define CMD_DAT_CTRL_INIT 0x0080
|
||||
# define CMD_DAT_CTRL_WRITE 0x0010
|
||||
# define CMD_DAT_CTRL_DATA_ENABLE 0x0008
|
||||
# define CMD_DAT_CTRL_RESP_NONE 0x0000
|
||||
# define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001
|
||||
# define CMD_DAT_CTRL_RESP_R2 0x0002
|
||||
# define CMD_DAT_CTRL_RESP_R3_R4 0x0003
|
||||
|
||||
#define SDHC_RES_TO 0x10
|
||||
|
||||
#define SDHC_READ_TO 0x14
|
||||
# define READ_TO_RECOMMENDED 0x2db4
|
||||
|
||||
#define SDHC_BLK_LEN 0x18
|
||||
|
||||
#define SDHC_NOB 0x1c
|
||||
|
||||
#define SDHC_REV_NO 0x20
|
||||
|
||||
#define SDHC_INT_CTRL 0x24 /* INT_CNTR */
|
||||
# define INT_CTRL_CARD_INSERTION_EN 0x8000
|
||||
# define INT_CTRL_SDIO_REMOVAL_EN 0x4000
|
||||
# define INT_CTRL_SDIO_IRQ_EN 0x2000
|
||||
# define INT_CTRL_DAT0_EN 0x1000
|
||||
# define INT_CTRL_BUF_READ_EN 0x0010
|
||||
# define INT_CTRL_BUF_WRITE_EN 0x0008
|
||||
# define INT_CTRL_END_CMD_RES 0x0004
|
||||
# define INT_CTRL_WRITE_OP_DONE 0x0002
|
||||
# define INT_CTRL_READ_OP_DONE 0x0001
|
||||
# define INT_CTRL_INT_EN_MASK 0xe01f
|
||||
|
||||
#define SDHC_CMD 0x28
|
||||
|
||||
#define SDHC_ARG 0x2c
|
||||
|
||||
#define SDHC_RES_FIFO 0x34
|
||||
|
||||
#define SDHC_BUFFER_ACCESS 0x38
|
||||
|
||||
#endif /* #ifndef _SLOT_IMX27_H */
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* i.MX31 SDHC definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SLOT_IMX31_H
|
||||
#define _SLOT_IMX31_H
|
||||
|
||||
/*
|
||||
* i.MX31 SDHC registers.
|
||||
*/
|
||||
|
||||
#define SDHC_STR_STP_CLK 0x00
|
||||
# define STR_STP_CLK_MMCSD_RESET 0x0008
|
||||
# define STR_STP_CLK_START_CLK 0x0002
|
||||
# define STR_STP_CLK_STOP_CLK 0x0001
|
||||
|
||||
#define SDHC_STATUS 0x04
|
||||
# define STATUS_CARD_PRESENCE 0x8000
|
||||
# define STATUS_SDIO_INT_ACTIVE 0x4000
|
||||
# define STATUS_END_CMD_RESP 0x2000
|
||||
# define STATUS_WRITE_OP_DONE 0x1000
|
||||
# define STATUS_READ_OP_DONE 0x0800
|
||||
# define STATUS_CARD_BUS_CLK_RUN 0x0100
|
||||
# define STATUS_APPL_BUFF_FF 0x0080
|
||||
# define STATUS_APPL_BUFF_FE 0x0040
|
||||
# define STATUS_RESP_CRC_ERR 0x0020
|
||||
# define STATUS_CRC_READ_ERR 0x0008
|
||||
# define STATUS_CRC_WRITE_ERR 0x0004
|
||||
# define STATUS_TIME_OUT_RESP 0x0002
|
||||
# define STATUS_TIME_OUT_READ 0x0001
|
||||
# define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP)
|
||||
# define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ)
|
||||
# define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK)
|
||||
|
||||
#define SDHC_CLK_RATE 0x08
|
||||
|
||||
#define SDHC_CMD_DAT_CTRL 0x0c /* CMD_DAT_CONT */
|
||||
# define CMD_DAT_CTRL_CMD_RESUME 0x8000
|
||||
# define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000
|
||||
# define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800
|
||||
# define CMD_DAT_CTRL_START_READ_WAIT 0x0400
|
||||
# define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200
|
||||
# define CMD_DAT_CTRL_INIT 0x0080
|
||||
# define CMD_DAT_CTRL_WRITE 0x0010
|
||||
# define CMD_DAT_CTRL_DATA_ENABLE 0x0008
|
||||
# define CMD_DAT_CTRL_RESP_NONE 0x0000
|
||||
# define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001
|
||||
# define CMD_DAT_CTRL_RESP_R2 0x0002
|
||||
# define CMD_DAT_CTRL_RESP_R3_R4 0x0003
|
||||
|
||||
#define SDHC_RES_TO 0x10
|
||||
|
||||
#define SDHC_READ_TO 0x14
|
||||
# define READ_TO_RECOMMENDED 0x2db4
|
||||
|
||||
#define SDHC_BLK_LEN 0x18
|
||||
|
||||
#define SDHC_NOB 0x1c
|
||||
|
||||
#define SDHC_REV_NO 0x20
|
||||
|
||||
#define SDHC_INT_CTRL 0x24 /* INT_CNTR */
|
||||
# define INT_CTRL_CARD_INSERTION_EN 0x8000
|
||||
# define INT_CTRL_SDIO_REMOVAL_EN 0x4000
|
||||
# define INT_CTRL_SDIO_IRQ_EN 0x2000
|
||||
# define INT_CTRL_DAT0_EN 0x1000
|
||||
# define INT_CTRL_BUF_READ_EN 0x0010
|
||||
# define INT_CTRL_BUF_WRITE_EN 0x0008
|
||||
# define INT_CTRL_END_CMD_RES 0x0004
|
||||
# define INT_CTRL_WRITE_OP_DONE 0x0002
|
||||
# define INT_CTRL_READ_OP_DONE 0x0001
|
||||
# define INT_CTRL_INT_EN_MASK 0xe01f
|
||||
|
||||
#define SDHC_CMD 0x28
|
||||
|
||||
#define SDHC_ARG 0x2c
|
||||
|
||||
#define SDHC_RES_FIFO 0x34
|
||||
|
||||
#define SDHC_BUFFER_ACCESS 0x38
|
||||
|
||||
#endif /* #ifndef _SLOT_IMX31_H */
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* PXA27x MMC/SD controller definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SLOT_PXA27X_H
|
||||
#define _SLOT_PXA27X_H
|
||||
|
||||
#define PXA27X_MMC_MMCLK_BASE_FREQ 19500000
|
||||
#define PXA27X_MMC_FIFO_SIZE 32
|
||||
|
||||
#define STOP_CLOCK (1 << 0)
|
||||
#define START_CLOCK (2 << 0)
|
||||
|
||||
#define STAT_END_CMD_RES (1 << 13)
|
||||
#define STAT_PRG_DONE (1 << 12)
|
||||
#define STAT_DATA_TRAN_DONE (1 << 11)
|
||||
#define STAT_CLK_EN (1 << 8)
|
||||
#define STAT_RECV_FIFO_FULL (1 << 7)
|
||||
#define STAT_XMIT_FIFO_EMPTY (1 << 6)
|
||||
#define STAT_RES_CRC_ERR (1 << 5)
|
||||
#define STAT_SPI_READ_ERROR_TOKEN (1 << 4)
|
||||
#define STAT_CRC_READ_ERROR (1 << 3)
|
||||
#define STAT_CRC_WRITE_ERROR (1 << 2)
|
||||
#define STAT_TIME_OUT_RESPONSE (1 << 1)
|
||||
#define STAT_READ_TIME_OUT (1 << 0)
|
||||
|
||||
#define SPI_CS_ADDRESS (1 << 3)
|
||||
#define SPI_CS_EN (1 << 2)
|
||||
#define CRC_ON (1 << 1)
|
||||
#define SPI_EN (1 << 0)
|
||||
|
||||
#define CMDAT_SDIO_INT_EN (1 << 11)
|
||||
#define CMDAT_STOP_TRAN (1 << 10)
|
||||
#define CMDAT_SD_4DAT (1 << 8)
|
||||
#define CMDAT_DMAEN (1 << 7)
|
||||
#define CMDAT_INIT (1 << 6)
|
||||
#define CMDAT_BUSY (1 << 5)
|
||||
#define CMDAT_STREAM (1 << 4) /* 1 = stream */
|
||||
#define CMDAT_WRITE (1 << 3) /* 1 = write */
|
||||
#define CMDAT_DATAEN (1 << 2)
|
||||
#define CMDAT_RESP_NONE (0 << 0)
|
||||
#define CMDAT_RESP_SHORT (1 << 0)
|
||||
#define CMDAT_RESP_R2 (2 << 0)
|
||||
#define CMDAT_RESP_R3 (3 << 0)
|
||||
|
||||
#define RDTO_MAX 0xffff
|
||||
|
||||
#define BUF_PART_FULL (1 << 0)
|
||||
|
||||
#define SDIO_SUSPEND_ACK (1 << 12)
|
||||
#define SDIO_INT (1 << 11)
|
||||
#define RD_STALLED (1 << 10)
|
||||
#define RES_ERR (1 << 9)
|
||||
#define DAT_ERR (1 << 8)
|
||||
#define TINT (1 << 7)
|
||||
#define TXFIFO_WR_REQ (1 << 6)
|
||||
#define RXFIFO_RD_REQ (1 << 5)
|
||||
#define CLK_IS_OFF (1 << 4)
|
||||
#define STOP_CMD (1 << 3)
|
||||
#define END_CMD_RES (1 << 2)
|
||||
#define PRG_DONE (1 << 1)
|
||||
#define DATA_TRAN_DONE (1 << 0)
|
||||
|
||||
#define MMC_I_MASK_ALL 0x00001fff
|
||||
|
||||
#endif /* #ifndef _SLOT_PXA27X_H */
|
|
@ -1,223 +0,0 @@
|
|||
/*
|
||||
* Standard Host Controller definitions.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SLOT_SHC_H
|
||||
#define _SLOT_SHC_H
|
||||
|
||||
#include <oska/io.h>
|
||||
|
||||
/* SHC registers */
|
||||
#define SHC_SYSTEM_ADDRESS 0x00
|
||||
|
||||
#define SHC_BLOCK_SIZE 0x04
|
||||
# define SHC_BLOCK_SIZE_DMA_BOUNDARY_4K (0x0 << 12)
|
||||
# define SHC_BLOCK_SIZE_DMA_BOUNDARY_512K (0x7 << 12)
|
||||
|
||||
#define SHC_BLOCK_COUNT 0x06
|
||||
#define SHC_ARG 0x08
|
||||
|
||||
#define SHC_TRANSFER_MODE 0x0c
|
||||
# define SHC_TRANSFER_MODE_DMA_EN 0x0001
|
||||
# define SHC_TRANSFER_MODE_BLK_CNT_EN 0x0002
|
||||
# define SHC_TRANSFER_MODE_AUTO_CMD12_EN 0x0004
|
||||
# define SHC_TRANSFER_MODE_DATA_READ 0x0010
|
||||
# define SHC_TRANSFER_MODE_MULTI_BLK 0x0020
|
||||
|
||||
#define SHC_CMD 0x0e
|
||||
# define SHC_CMD_RESP_NONE 0x0000
|
||||
# define SHC_CMD_RESP_136 0x0001
|
||||
# define SHC_CMD_RESP_48 0x0002
|
||||
# define SHC_CMD_RESP_48B 0x0003
|
||||
# define SHC_CMD_RESP_CRC_CHK 0x0008
|
||||
# define SHC_CMD_RESP_IDX_CHK 0x0010
|
||||
# define SHC_CMD_DATA_PRESENT 0x0020
|
||||
# define SHC_CMD_TYPE_ABORT (0x3 << 6)
|
||||
# define SHC_CMD_IDX(c) ((c) << 8)
|
||||
|
||||
#define SHC_RESPONSE_0_31 0x10
|
||||
|
||||
#define SHC_BUFFER_DATA_PORT 0x20
|
||||
|
||||
#define SHC_PRESENT_STATE 0x24
|
||||
# define SHC_PRESENT_STATE_CMD_INHIBIT 0x00000001
|
||||
# define SHC_PRESENT_STATE_DAT_INHIBIT 0x00000002
|
||||
# define SHC_PRESENT_STATE_CARD_PRESENT 0x00010000
|
||||
|
||||
#define SHC_HOST_CTRL 0x28
|
||||
# define SHC_HOST_CTRL_LED_ON 0x01
|
||||
# define SHC_HOST_CTRL_4BIT 0x02
|
||||
# define SHC_HOST_CTRL_HIGH_SPD_EN 0x04
|
||||
|
||||
|
||||
#define SHC_PWR_CTRL 0x29
|
||||
# define SHC_PWR_CTRL_3V3 0x0e
|
||||
# define SHC_PWR_CTRL_ON 0x01
|
||||
|
||||
#define SHC_BLOCK_GAP_CTRL 0x2a
|
||||
#define SHC_WAKEUP_CTRL 0x2b
|
||||
|
||||
#define SHC_CLOCK_CTRL 0x2c
|
||||
# define SHC_CLOCK_CTRL_INT_CLK_EN 0x01
|
||||
# define SHC_CLOCK_CTRL_INT_CLK_STABLE 0x02
|
||||
# define SHC_CLOCK_CTRL_SD_CLK_EN 0x04
|
||||
# define SHC_CLOCK_CTRL_DIV(d) (((d) >> 1) << 8) /* divisor must be power of 2 */
|
||||
|
||||
#define SHC_TIMEOUT_CTRL 0x2e
|
||||
# define SHC_TIMEOUT_CTRL_MAX 0x0e
|
||||
|
||||
#define SHC_SOFTWARE_RST 0x2f
|
||||
# define SHC_SOFTWARE_RST_ALL 0x01
|
||||
# define SHC_SOFTWARE_RST_CMD 0x02
|
||||
# define SHC_SOFTWARE_RST_DAT 0x04
|
||||
|
||||
#define SHC_INT_STATUS 0x30
|
||||
#define SHC_INT_STATUS_EN 0x34
|
||||
#define SHC_INT_SIGNAL_EN 0x38
|
||||
# define SHC_INT_CMD_COMPLETE 0x00000001
|
||||
# define SHC_INT_TRANSFER_COMPLETE 0x00000002
|
||||
# define SHC_INT_BLOCK_GAP 0x00000004
|
||||
# define SHC_INT_DMA 0x00000008
|
||||
# define SHC_INT_WR_BUF_RDY 0x00000010
|
||||
# define SHC_INT_RD_BUF_RDY 0x00000020
|
||||
# define SHC_INT_CARD_INSERTED 0x00000040
|
||||
# define SHC_INT_CARD_REMOVED 0x00000080
|
||||
# define SHC_INT_CARD_INT 0x00000100
|
||||
# define SHC_INT_ERR_ANY 0x00008000
|
||||
# define SHC_INT_ERR_CMD_TIMEOUT 0x00010000
|
||||
# define SHC_INT_ERR_CMD_CRC 0x00020000
|
||||
# define SHC_INT_ERR_CMD_ENDBIT 0x00040000
|
||||
# define SHC_INT_ERR_CMD_INDEX 0x00080000
|
||||
# define SHC_INT_ERR_CMD_ALL 0x000f0000
|
||||
# define SHC_INT_ERR_DAT_TIMEOUT 0x00100000
|
||||
# define SHC_INT_ERR_DAT_CRC 0x00200000
|
||||
# define SHC_INT_ERR_DAT_ENDBIT 0x00400000
|
||||
# define SHC_INT_ERR_DAT_ALL 0x00700000
|
||||
# define SHC_INT_ERR_CURRENT_LIMIT 0x00800000
|
||||
# define SHC_INT_ERR_AUTO_CMD12 0x01000000
|
||||
# define SHC_INT_ERR_ALL 0x01ff0000
|
||||
# define SHC_INT_ALL 0x01ff81ff
|
||||
|
||||
#define SHC_AUTO_CMD12_STATUS 0x3c
|
||||
|
||||
#define SHC_CAPS 0x40
|
||||
# define SHC_CAPS_TO_BASE_CLK_FREQ(c) (((c) & 0x00003f00) >> 8)
|
||||
# define SHC_CAPS_PWR_3V3 (1 << 24)
|
||||
|
||||
#define SHC_MAX_CURRENT_CAPS 0x4c
|
||||
|
||||
/* PCI configuration registers. */
|
||||
#define PCI_SHC_SLOT_INFO 0x40
|
||||
|
||||
/* Maximum time to wait for a software reset. */
|
||||
#define SHC_RESET_TIMEOUT_MS 100 /* ms */
|
||||
|
||||
/* Maximum time to wait for internal clock to stabilize */
|
||||
#define SHC_INT_CLK_STABLE_TIMEOUT_MS 100
|
||||
|
||||
/*
|
||||
* No supported voltages in the capabilities register.
|
||||
*
|
||||
* Workaround: Assume 3.3V is supported.
|
||||
*/
|
||||
#define SLOT_SHC_QUIRK_NO_VOLTAGE_CAPS (1 << 0)
|
||||
|
||||
/*
|
||||
* Commands with an R5B (busy) response do not complete.
|
||||
*
|
||||
* Workaround: Use R5 instead. This will only work if the busy signal
|
||||
* is cleared sufficiently quickly before the next command is started.
|
||||
*/
|
||||
#define SLOT_SHC_QUIRK_R5B_BROKEN (1 << 1)
|
||||
|
||||
/*
|
||||
* High speed mode doesn't work.
|
||||
*
|
||||
* Workaround: limit maximum bus frequency to 25 MHz.
|
||||
*/
|
||||
#define SLOT_SHC_QUIRK_HIGH_SPD_BROKEN (1 << 2)
|
||||
|
||||
/*
|
||||
* Data timeout (TIMEOUT_CTRL) uses SDCLK and not TMCLK.
|
||||
*
|
||||
* Workaround: set TIMEOUT_CTRL using SDCLK.
|
||||
*/
|
||||
#define SLOT_SHC_QUIRK_DATA_TIMEOUT_USES_SDCLK (1 << 3)
|
||||
|
||||
/*
|
||||
* Controller can only start DMA on dword (32 bit) aligned addresses.
|
||||
*
|
||||
* Workaround: PIO is used on data transfers with a non-dword aligned
|
||||
* address.
|
||||
*/
|
||||
#define SHC_QUIRK_DMA_NEEDS_DWORD_ALIGNED_ADDR (1 << 4)
|
||||
|
||||
/*
|
||||
* Controller is unreliable following multiple transfers
|
||||
*
|
||||
* Workaround: The controller is reset following every command, not just
|
||||
* erroneous ones
|
||||
*/
|
||||
#define SHC_QUIRK_RESET_EVERY_CMD_COMPLETE (1 << 5)
|
||||
|
||||
/*
|
||||
* JMicron JMB381 to JMB385 controllers require some non-standard PCI
|
||||
* config space writes.
|
||||
*/
|
||||
#define SHC_QUIRK_JMICRON_JMB38X (1 << 6)
|
||||
|
||||
/*
|
||||
* Controller can only do DMA if the length is a whole number of
|
||||
* dwords.
|
||||
*
|
||||
* Controller with this quirk probably also need
|
||||
* SHC_QUIRK_DMA_NEEDS_DWORD_ALIGNED_ADDR.
|
||||
*
|
||||
* Workaround: PIO is used on data transfers that don't end on an
|
||||
* aligned address.
|
||||
*/
|
||||
#define SHC_QUIRK_DMA_NEEDS_DWORD_ALIGNED_LEN (1 << 7)
|
||||
|
||||
struct sdioemb_shc {
|
||||
struct sdioemb_slot *slot;
|
||||
void (*enable_int)(struct sdioemb_slot *slot, uint32_t ints);
|
||||
void (*disable_int)(struct sdioemb_slot *slot, uint32_t ints);
|
||||
void (*cmd_complete)(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd);
|
||||
uint32_t quirks;
|
||||
os_io_mem_t addr;
|
||||
|
||||
os_spinlock_t lock;
|
||||
os_timer_t lockup_timer;
|
||||
uint32_t base_clk;
|
||||
struct sdioemb_cmd *current_cmd;
|
||||
uint8_t *data;
|
||||
size_t remaining;
|
||||
size_t block_size;
|
||||
};
|
||||
|
||||
void sdioemb_shc_init(struct sdioemb_shc *shc);
|
||||
void sdioemb_shc_clean_up(struct sdioemb_shc *shc);
|
||||
|
||||
int sdioemb_shc_start(struct sdioemb_shc *shc);
|
||||
void sdioemb_shc_stop(struct sdioemb_shc *shc);
|
||||
|
||||
bool sdioemb_shc_isr(struct sdioemb_shc *shc, uint32_t *int_stat);
|
||||
void sdioemb_shc_dsr(struct sdioemb_shc *shc, uint32_t int_stat);
|
||||
|
||||
int sdioemb_shc_set_bus_freq(struct sdioemb_shc *shc, int clk);
|
||||
int sdioemb_shc_set_bus_width(struct sdioemb_shc *shc, int bus_width);
|
||||
int sdioemb_shc_start_cmd(struct sdioemb_shc *shc, struct sdioemb_cmd *cmd,
|
||||
bool use_dma, uint64_t dma_addr);
|
||||
int sdioemb_shc_card_present(struct sdioemb_shc *shc);
|
||||
int sdioemb_shc_card_power(struct sdioemb_shc *shc, enum sdioemb_power power);
|
||||
void sdioemb_shc_enable_card_int(struct sdioemb_shc *shc);
|
||||
void sdioemb_shc_disable_card_int(struct sdioemb_shc *shc);
|
||||
int sdioemb_shc_hard_reset(struct sdioemb_shc *shc);
|
||||
|
||||
void sdioemb_shc_show_quirks(struct sdioemb_shc *shc);
|
||||
|
||||
#endif /* #ifndef _SLOT_SHC_H */
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* USB Standard Host Controller definitions.
|
||||
*
|
||||
* Copyright (C) 2010 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef _SLOT_USHC_H
|
||||
#define _SLOT_USHC_H
|
||||
|
||||
#include <oska/io.h>
|
||||
|
||||
enum ushc_request
|
||||
{
|
||||
USHC_GET_CAPS = 0x00,
|
||||
USHC_HOST_CTRL = 0x01,
|
||||
USHC_PWR_CTRL = 0x02,
|
||||
USHC_CLK_FREQ = 0x03,
|
||||
USHC_EXEC_CMD = 0x04,
|
||||
USHC_READ_RESP = 0x05,
|
||||
USHC_RESET = 0x06
|
||||
};
|
||||
|
||||
enum ushc_request_recipient
|
||||
{
|
||||
USHC_RECIPIENT_DEVICE = 0x00,
|
||||
USHC_RECIPIENT_INTERFACE = 0x01,
|
||||
USHC_RECIPIENT_ENDPOINT = 0x02,
|
||||
USHC_RECIPIENT_OTHER = 0x03
|
||||
};
|
||||
|
||||
enum ushc_request_direction
|
||||
{
|
||||
USHC_HOST_TO_DEVICE = 0x00,
|
||||
USHC_DEVICE_TO_HOST = 0x01
|
||||
};
|
||||
|
||||
struct sdioemb_ushc
|
||||
{
|
||||
struct sdioemb_slot *slot;
|
||||
|
||||
void (*enable_int)(struct sdioemb_slot *slot, uint32_t ints);
|
||||
void (*disable_int)(struct sdioemb_slot *slot, uint32_t ints);
|
||||
void (*cmd_complete)(struct sdioemb_slot *slot, struct sdioemb_cmd *cmd);
|
||||
int (*set_host_ctrl)(struct sdioemb_slot *slot, uint16_t controler_state);
|
||||
int (*submit_vendor_request)(struct sdioemb_slot *slot,
|
||||
enum ushc_request request,
|
||||
enum ushc_request_direction direction,
|
||||
enum ushc_request_recipient recipient,
|
||||
uint16_t value,
|
||||
uint16_t index,
|
||||
void* io_buffer,
|
||||
uint32_t io_buffer_length);
|
||||
int (*submit_cbw_request)(struct sdioemb_slot *slot, uint8_t cmd_index, uint16_t block_size, uint32_t cmd_arg);
|
||||
int (*submit_data_request)(struct sdioemb_slot *slot,
|
||||
enum ushc_request_direction direction,
|
||||
void* request_buffer,
|
||||
uint32_t request_buffer_length);
|
||||
int (*submit_csw_request)(struct sdioemb_slot *slot);
|
||||
|
||||
os_spinlock_t lock;
|
||||
|
||||
uint32_t base_clock;
|
||||
uint32_t controler_capabilities;
|
||||
uint16_t controler_state;
|
||||
struct sdioemb_cmd* current_cmd;
|
||||
|
||||
#define DISCONNECTED 0
|
||||
#define INT_EN 1
|
||||
#define IGNORE_NEXT_INT 2
|
||||
#define STOP 4
|
||||
uint32_t flags;
|
||||
|
||||
#define USHC_INT_STATUS_SDIO_INT (1 << 1)
|
||||
#define USHC_INT_STATUS_CARD_PRESENT (1 << 0)
|
||||
uint8_t interrupt_status;
|
||||
|
||||
size_t block_size;
|
||||
};
|
||||
|
||||
#define USHC_GET_CAPS_VERSION_MASK 0xff
|
||||
#define USHC_GET_CAPS_3V3 (1 << 8)
|
||||
#define USHC_GET_CAPS_3V0 (1 << 9)
|
||||
#define USHC_GET_CAPS_1V8 (1 << 10)
|
||||
#define USHC_GET_CAPS_HIGH_SPD (1 << 16)
|
||||
|
||||
#define USHC_PWR_CTRL_OFF 0x00
|
||||
#define USHC_PWR_CTRL_3V3 0x01
|
||||
#define USHC_PWR_CTRL_3V0 0x02
|
||||
#define USHC_PWR_CTRL_1V8 0x03
|
||||
|
||||
#define USHC_HOST_CTRL_4BIT (1 << 1)
|
||||
#define USHC_HOST_CTRL_HIGH_SPD (1 << 0)
|
||||
|
||||
#define USHC_READ_RESP_BUSY (1 << 4)
|
||||
#define USHC_READ_RESP_ERR_TIMEOUT (1 << 3)
|
||||
#define USHC_READ_RESP_ERR_CRC (1 << 2)
|
||||
#define USHC_READ_RESP_ERR_DAT (1 << 1)
|
||||
#define USHC_READ_RESP_ERR_CMD (1 << 0)
|
||||
#define USHC_READ_RESP_ERR_MASK 0x0f
|
||||
|
||||
void sdioemb_ushc_init(struct sdioemb_ushc* ushc);
|
||||
void sdioemb_ushc_clean_up(struct sdioemb_ushc* ushc);
|
||||
|
||||
int sdioemb_ushc_start(struct sdioemb_ushc* ushc);
|
||||
void sdioemb_ushc_stop(struct sdioemb_ushc* ushc);
|
||||
|
||||
bool sdioemb_ushc_isr(struct sdioemb_ushc* ushc, uint8_t int_stat);
|
||||
|
||||
int sdioemb_ushc_set_bus_freq(struct sdioemb_ushc* ushc, int clk);
|
||||
int sdioemb_ushc_set_bus_width(struct sdioemb_ushc* ushc, int bus_width);
|
||||
int sdioemb_ushc_start_cmd(struct sdioemb_ushc* ushc, struct sdioemb_cmd *cmd);
|
||||
int sdioemb_ushc_card_present(struct sdioemb_ushc* ushc);
|
||||
int sdioemb_ushc_card_power(struct sdioemb_ushc* ushc, enum sdioemb_power power);
|
||||
void sdioemb_ushc_enable_card_int(struct sdioemb_ushc* ushc);
|
||||
void sdioemb_ushc_disable_card_int(struct sdioemb_ushc* ushc);
|
||||
int sdioemb_ushc_hard_reset(struct sdioemb_ushc* ushc);
|
||||
|
||||
void sdioemb_ushc_command_complete(struct sdioemb_ushc* ushc, uint8_t status, uint32_t respones);
|
||||
|
||||
int ushc_hw_get_caps(struct sdioemb_ushc* ushc);
|
||||
static int ushc_hw_set_host_ctrl(struct sdioemb_ushc* ushc, uint16_t mask, uint16_t val);
|
||||
static int ushc_hw_submit_vendor_request(struct sdioemb_ushc* ushc,
|
||||
enum ushc_request request,
|
||||
enum ushc_request_recipient recipient,
|
||||
enum ushc_request_direction direction,
|
||||
uint16_t value,
|
||||
uint16_t index,
|
||||
void* io_buffer,
|
||||
uint32_t io_buffer_length);
|
||||
|
||||
#endif
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Sdioemb trace messages.
|
||||
*
|
||||
* Copyright (C) 2009 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
|
||||
#ifndef SDIOEMB_TRACE_H
|
||||
#define SDIOEMB_TRACE_H
|
||||
|
||||
#if defined(__linux__)
|
||||
# define OS_TRACE_PREFIX "sdioemb: "
|
||||
#endif
|
||||
|
||||
#include <oska/trace.h>
|
||||
|
||||
#endif /* #ifndef SDIOEMB_TRACE_H */
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Userspace interface to the SDIO Userspace Interface driver.
|
||||
*
|
||||
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
|
||||
*
|
||||
* Refer to LICENSE.txt included with this source code for details on
|
||||
* the license terms.
|
||||
*/
|
||||
#ifndef LINUX_SDIOEMB_UIF_H
|
||||
#define LINUX_SDIOEMB_UIF_H
|
||||
|
||||
enum sdioemb_uif_cmd_type {
|
||||
SDIOEMB_UIF_CMD52_READ, SDIOEMB_UIF_CMD52_WRITE,
|
||||
SDIOEMB_UIF_CMD53_READ, SDIOEMB_UIF_CMD53_WRITE,
|
||||
};
|
||||
|
||||
struct sdioemb_uif_cmd {
|
||||
enum sdioemb_uif_cmd_type type;
|
||||
int function;
|
||||
uint32_t address;
|
||||
uint8_t * data;
|
||||
size_t len;
|
||||
int block_size;
|
||||
};
|
||||
|
||||
#define SDIOEMB_UIF_IOC_MAGIC 's'
|
||||
|
||||
#define SDIOEMB_UIF_IOCQNUMFUNCS _IO(SDIOEMB_UIF_IOC_MAGIC, 0)
|
||||
#define SDIOEMB_UIF_IOCCMD _IOWR(SDIOEMB_UIF_IOC_MAGIC, 1, struct sdioemb_uif_cmd)
|
||||
#define SDIOEMB_UIF_IOCWAITFORINT _IO(SDIOEMB_UIF_IOC_MAGIC, 2)
|
||||
#define SDIOEMB_UIF_IOCTBUSWIDTH _IO(SDIOEMB_UIF_IOC_MAGIC, 3)
|
||||
#define SDIOEMB_UIF_IOCREINSERT _IO(SDIOEMB_UIF_IOC_MAGIC, 4)
|
||||
#define SDIOEMB_UIF_IOCTBUSFREQ _IO(SDIOEMB_UIF_IOC_MAGIC, 5)
|
||||
#define SDIOEMB_UIF_IOCQMANFID _IO(SDIOEMB_UIF_IOC_MAGIC, 6)
|
||||
#define SDIOEMB_UIF_IOCQCARDID _IO(SDIOEMB_UIF_IOC_MAGIC, 7)
|
||||
#define SDIOEMB_UIF_IOCQSTDIF _IO(SDIOEMB_UIF_IOC_MAGIC, 8)
|
||||
#define SDIOEMB_UIF_IOCQMAXBLKSZ _IO(SDIOEMB_UIF_IOC_MAGIC, 9)
|
||||
#define SDIOEMB_UIF_IOCQBLKSZ _IO(SDIOEMB_UIF_IOC_MAGIC, 10)
|
||||
#define SDIOEMB_UIF_IOCTBLKSZ _IO(SDIOEMB_UIF_IOC_MAGIC, 11)
|
||||
|
||||
#endif /* #ifndef LINUX_SDIOEMB_UIF_H */
|
|
@ -1,11 +0,0 @@
|
|||
/* Autogenerated by the sdioemb release procedure. */
|
||||
#ifndef SDIOEMB_VERSION_H
|
||||
#define SDIOEMB_VERSION_H
|
||||
|
||||
#define SDIOEMB_RELEASE 31
|
||||
|
||||
#ifndef SDIOEMB_RELEASE_EXTRA
|
||||
#define SDIOEMB_RELEASE_EXTRA ""
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef SDIOEMB_VERSION_H */
|
Loading…
Reference in New Issue