summaryrefslogtreecommitdiffstats
path: root/drivers/staging/csr/sdioemb/sdio_api.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/csr/sdioemb/sdio_api.h')
-rw-r--r--drivers/staging/csr/sdioemb/sdio_api.h408
1 files changed, 408 insertions, 0 deletions
diff --git a/drivers/staging/csr/sdioemb/sdio_api.h b/drivers/staging/csr/sdioemb/sdio_api.h
new file mode 100644
index 000000000000..cd8aded7229f
--- /dev/null
+++ b/drivers/staging/csr/sdioemb/sdio_api.h
@@ -0,0 +1,408 @@
+/*
+ * 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 */