1 /*
2 * platform interfaces for XRadio drivers
3 *
4 * Copyright (c) 2013, XRadio
5 * Author: XRadio
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 #include <linux/version.h>
12 #include <linux/module.h>
13 #include <linux/err.h>
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/interrupt.h>
17 #include <linux/gpio.h>
18 #include <linux/ioport.h>
19 #include <linux/regulator/consumer.h>
20 //#include <asm/mach-types.h>
21 //#include <mach/sys_config.h>
22 #include "xradio.h"
23 #include "platform.h"
24 #include "sbus.h"
25 #include <linux/gpio.h>
26 #include <linux/types.h>
27 //#include <linux/power/scenelock.h>
28 //#include <linux/power/aw_pm.h>
29 #include <linux/pm_wakeirq.h>
30
31 #ifndef CONFIG_DRIVERS_HDF_XR829
32 MODULE_AUTHOR("XRadioTech");
33 MODULE_DESCRIPTION("XRadioTech WLAN driver");
34 MODULE_LICENSE("GPL");
35 MODULE_ALIAS("xradio_wlan");
36 #endif
37
38 extern void sunxi_wlan_set_power(bool on);
39 extern int sunxi_wlan_get_bus_index(void);
40 extern int sunxi_wlan_get_oob_irq(int *, int *);
41 extern void sunxi_bluetooth_set_power(bool on_off);
42
43 static int wlan_bus_id;
44 static u32 gpio_irq_handle;
45 static int irq_flags, wakeup_enable;
46
xradio_get_syscfg(void)47 int xradio_get_syscfg(void)
48 {
49 int wlan_bus_index = 0;
50 wlan_bus_index = sunxi_wlan_get_bus_index();
51 if (wlan_bus_index < 0)
52 return wlan_bus_index;
53 else
54 wlan_bus_id = wlan_bus_index;
55 gpio_irq_handle = sunxi_wlan_get_oob_irq(&irq_flags, &wakeup_enable);
56 return wlan_bus_index;
57 }
58 /*********************Interfaces called by xradio core. *********************/
xradio_plat_init(void)59 int xradio_plat_init(void)
60 {
61 return 0;
62 }
63
xradio_plat_deinit(void)64 void xradio_plat_deinit(void)
65 {
66 ;
67 }
68
xradio_wlan_power(int on)69 int xradio_wlan_power(int on)
70 {
71 int ret = 0;
72 if (on) {
73 ret = xradio_get_syscfg();
74 if (ret < 0)
75 return ret;
76 }
77 sunxi_wlan_set_power(on);
78 mdelay(100);
79 return ret;
80 }
81
xradio_bt_power(int on_off)82 void xradio_bt_power(int on_off)
83 {
84 sunxi_bluetooth_set_power(on_off);
85 mdelay(100);
86 }
87
xradio_sdio_detect(int enable)88 void xradio_sdio_detect(int enable)
89 {
90 MCI_RESCAN_CARD(wlan_bus_id);
91 xradio_dbg(XRADIO_DBG_ALWY, "%s SDIO card %d\n",
92 enable?"Detect":"Remove", wlan_bus_id);
93 mdelay(10);
94 }
95
xradio_gpio_irq_handler(int irq,void * sbus_priv)96 static irqreturn_t xradio_gpio_irq_handler(int irq, void *sbus_priv)
97 {
98 struct sbus_priv *self = (struct sbus_priv *)sbus_priv;
99 unsigned long flags;
100
101 SYS_BUG(!self);
102 spin_lock_irqsave(&self->lock, flags);
103 if (self->irq_handler)
104 self->irq_handler(self->irq_priv);
105 spin_unlock_irqrestore(&self->lock, flags);
106 return IRQ_HANDLED;
107 }
108
xradio_request_gpio_irq(struct device * dev,void * sbus_priv)109 int xradio_request_gpio_irq(struct device *dev, void *sbus_priv)
110 {
111 int ret = -1;
112
113 ret = devm_request_irq(dev, gpio_irq_handle,
114 (irq_handler_t)xradio_gpio_irq_handler,
115 irq_flags, "xradio_irq", sbus_priv);
116 if (ret < 0) {
117 gpio_irq_handle = 0;
118 xradio_dbg(XRADIO_DBG_ERROR, "%s: request_irq FAIL!ret=%d\n",
119 __func__, ret);
120 }
121
122 if (wakeup_enable) {
123 ret = device_init_wakeup(dev, true);
124 if (ret < 0) {
125 xradio_dbg(XRADIO_DBG_ERROR, "device init wakeup failed!\n");
126 return ret;
127 }
128
129 ret = dev_pm_set_wake_irq(dev, gpio_irq_handle);
130 if (ret < 0) {
131 xradio_dbg(XRADIO_DBG_ERROR, "can't enable wakeup src!\n");
132 return ret;
133 }
134 }
135
136 return ret;
137 }
138
xradio_free_gpio_irq(struct device * dev,void * sbus_priv)139 void xradio_free_gpio_irq(struct device *dev, void *sbus_priv)
140 {
141 struct sbus_priv *self = (struct sbus_priv *)sbus_priv;
142 if (wakeup_enable) {
143 device_init_wakeup(dev, false);
144 dev_pm_clear_wake_irq(dev);
145 }
146 devm_free_irq(dev, gpio_irq_handle, self);
147 gpio_irq_handle = 0;
148 }
149