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