1 /*
2 * Sbus interfaces for XRadio drivers
3 *
4 * Copyright (c) 2013
5 * Xradio Technology Co., Ltd. <www.xradiotech.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12
13 #ifndef __SBUS_H
14 #define __SBUS_H
15
16 #include <linux/version.h>
17 #include <linux/module.h>
18 /*
19 * sbus priv forward definition.
20 * Implemented and instantiated in particular modules.
21 */
22
23 struct xradio_common;
24 /*sdio bus private struct*/
25 #define SDIO_UNLOAD 0
26 #define SDIO_LOAD 1
27
28 #ifdef CONFIG_XRADIO_NON_POWER_OF_TWO_BLOCKSIZES
29
30 #define SDIO_BLOCK_SIZE (264) /*264 = 528/2*/
31 #if (SDIO_BLOCK_SIZE & 0x3)
32 #error "SDIO_BLOCK_SIZE is not aligned of 4 byte"
33 #endif
34
35 #else
36
37 #define SDIO_BLOCK_SIZE (256)
38 #if ((SDIO_BLOCK_SIZE-1) & SDIO_BLOCK_SIZE)
39 #error "SDIO_BLOCK_SIZE is not power of 2"
40 #endif
41
42 #endif
43
44
45 typedef void (*sbus_irq_handler)(void *priv);
46 struct sbus_priv {
47 struct sdio_func *func;
48 spinlock_t lock;
49 sbus_irq_handler irq_handler;
50 void *irq_priv;
51 wait_queue_head_t init_wq;
52 int load_state;
53 u32 *val32_r;
54 u32 *val32_w;
55 };
56
57 struct sbus_ops {
58 int (*sbus_data_read)(struct sbus_priv *self, unsigned int addr,
59 void *dst, int count);
60 int (*sbus_data_write)(struct sbus_priv *self, unsigned int addr,
61 const void *src, int count);
62 void (*lock)(struct sbus_priv *self);
63 void (*unlock)(struct sbus_priv *self);
64 size_t (*align_size)(struct sbus_priv *self, size_t size);
65 int (*set_block_size)(struct sbus_priv *self, size_t size);
66 size_t (*get_block_size)(struct sbus_priv *self);
67 int (*irq_subscribe)(struct sbus_priv *self,
68 sbus_irq_handler handler, void *priv);
69 int (*irq_unsubscribe)(struct sbus_priv *self);
70 int (*power_mgmt)(struct sbus_priv *self, bool suspend);
71 int (*reset)(struct sbus_priv *self);
72 };
73
74 #ifdef CONFIG_XRADIO_NON_POWER_OF_TWO_BLOCKSIZES
xr_sdio_blksize_align(unsigned size)75 static inline unsigned xr_sdio_blksize_align(unsigned size)
76 {
77 unsigned align_size = size%SDIO_BLOCK_SIZE;
78 return align_size ? (size + SDIO_BLOCK_SIZE - align_size) : size;
79 }
80 #else
xr_sdio_blksize_align(unsigned size)81 static inline unsigned xr_sdio_blksize_align(unsigned size)
82 {
83 return (size + (SDIO_BLOCK_SIZE - 1)) &
84 (~(SDIO_BLOCK_SIZE - 1));
85 }
86 #endif
87
xr_sdio_align_broken_byte512(unsigned size)88 static inline unsigned xr_sdio_align_broken_byte512(unsigned size)
89 {
90 unsigned align_size = (size + 0x3) & 0x3;
91 return (align_size < 512 ?
92 align_size : xr_sdio_blksize_align(align_size));
93 }
94
95 /*sbus init functions*/
96 struct device *sbus_sdio_init(struct sbus_ops **sdio_ops,
97 struct sbus_priv **sdio_priv);
98 void sbus_sdio_deinit(void);
99
100 #endif /* __SBUS_H */
101