• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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