1 /* Copyright Statement:
\r
3 * This software/firmware and related documentation ("MediaTek Software") are
\r
4 * protected under relevant copyright laws. The information contained herein is
\r
5 * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
\r
6 * the prior written permission of MediaTek inc. and/or its licensors, any
\r
7 * reproduction, modification, use or disclosure of MediaTek Software, and
\r
8 * information contained herein, in whole or in part, shall be strictly
\r
11 * MediaTek Inc. (C) 2010. All rights reserved.
\r
13 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
\r
14 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
\r
15 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
\r
16 * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
\r
17 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
\r
18 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
\r
19 * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
\r
20 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
\r
21 * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
\r
22 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
\r
23 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
\r
24 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
\r
25 * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
\r
26 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
\r
27 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
\r
28 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
\r
29 * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
\r
30 * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
\r
31 * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
\r
33 * The following software/firmware and/or related documentation ("MediaTek
\r
34 * Software") have been modified by MediaTek Inc. All revisions are subject to
\r
35 * any receiver's applicable license agreements with MediaTek Inc.
\r
38 #include <linux/module.h>
\r
39 #include <linux/delay.h>
\r
40 #include <linux/irq.h>
\r
41 #include <linux/interrupt.h>
\r
42 #include <linux/gpio.h>
\r
43 #include <mach/gpio.h>
\r
44 #include <mach/iomux.h>
\r
45 //#include <plat/gpio-cfg.h>
\r
47 #include "bt_hwctl.h"
\r
49 extern int mt6622_suspend_flag;
\r
51 /****************************************************************************
\r
52 * C O N S T A N T S *
\r
53 *****************************************************************************/
\r
54 #define MODULE_TAG "[MT6622] "
\r
56 static int irq_num = -1;
\r
58 #ifdef CONFIG_ARCH_RK29
\r
59 #define rk_mux_api_set(name,mode) rk29_mux_api_set(name,mode)
\r
60 #elif defined (CONFIG_ARCH_RK30)
\r
61 #define rk_mux_api_set(name,mode) rk30_mux_api_set(name,mode)
\r
63 #define rk_mux_api_set(name,mode) rk30_mux_api_set(name,mode)
\r
67 // to avoid irq enable and disable not match
\r
68 static unsigned int irq_mask;
\r
69 //static spinlock_t bt_irq_lock;
\r
71 /****************************************************************************
\r
72 * I R Q F U N C T I O N S *
\r
73 *****************************************************************************/
\r
74 static int mt_bt_request_irq(void)
\r
77 int trigger = IRQF_TRIGGER_RISING;
\r
78 struct mt6622_platform_data *pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();
\r
81 if(pdata->irq_gpio.enable == GPIO_LOW)
\r
82 trigger = IRQF_TRIGGER_FALLING;
\r
84 iRet = request_irq(irq_num, mt_bt_eirq_handler,
\r
85 trigger, "BT_INT_B", NULL);
\r
87 printk(KERN_ALERT MODULE_TAG "request_irq IRQ%d fails, errno %d\n", irq_num, iRet);
\r
90 printk(KERN_INFO MODULE_TAG "request_irq IRQ%d success\n", irq_num);
\r
91 mt_bt_disable_irq();
\r
92 /* enable irq when driver init complete, at hci_uart_open */
\r
98 static void mt_bt_free_irq(void)
\r
101 free_irq(irq_num, NULL);
\r
106 int mt6622_suspend(struct platform_device *pdev, pm_message_t state)
\r
108 if(irq_num != -1) {
\r
109 printk(KERN_INFO MODULE_TAG "mt6622_suspend\n");
\r
110 mt6622_suspend_flag = 1;
\r
111 enable_irq_wake(irq_num);
\r
116 int mt6622_resume(struct platform_device *pdev)
\r
118 if(irq_num != -1) {
\r
119 printk(KERN_INFO MODULE_TAG "mt6622_resume\n");
\r
120 disable_irq_wake(irq_num);
\r
125 void mt_bt_enable_irq(void)
\r
129 enable_irq(irq_num);
\r
132 EXPORT_SYMBOL(mt_bt_enable_irq);
\r
134 void mt_bt_disable_irq(void)
\r
138 disable_irq_nosync(irq_num);
\r
141 EXPORT_SYMBOL(mt_bt_disable_irq);
\r
143 /****************************************************************************
\r
144 * P O W E R C O N T R O L *
\r
145 *****************************************************************************/
\r
147 int mt_bt_power_init(void)
\r
149 struct mt6622_platform_data *pdata;
\r
151 printk(KERN_INFO MODULE_TAG "mt_bt_power_init\n");
\r
153 pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();
\r
157 // PWR_EN and RESET
\r
158 /* PWR_EN set to gpio output low */
\r
159 if(pdata->power_gpio.io != INVALID_GPIO)
\r
160 gpio_direction_output(pdata->power_gpio.io, 0);
\r
161 /* RESET set to gpio output low */
\r
162 if(pdata->reset_gpio.io != INVALID_GPIO)
\r
163 gpio_direction_output(pdata->reset_gpio.io, 0);
\r
166 /* PWR_EN pull up */
\r
167 //if(pdata->power_gpio.io != INVALID_GPIO)
\r
168 // gpio_direction_output(pdata->power_gpio.io, 0);
\r
170 /* RESET pull up */
\r
171 if(pdata->reset_gpio.io != INVALID_GPIO)
\r
172 gpio_direction_output(pdata->reset_gpio.io, 1);
\r
175 //pdata->power_gpio.io = INVALID_GPIO;
\r
176 pdata->reset_gpio.io = INVALID_GPIO;
\r
181 EXPORT_SYMBOL(mt_bt_power_init);
\r
183 int mt_bt_power_on(void)
\r
186 struct mt6622_platform_data *pdata;
\r
188 printk(KERN_INFO MODULE_TAG "mt_bt_power_on ++\n");
\r
190 pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();
\r
195 // PCMIN, PCMOUT, PCMCLK, PCMSYNC
\r
198 //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(0));
\r
199 //--s3c_gpio_setpull(GPIO_BT_EINT_PIN, S3C_GPIO_PULL_DOWN);
\r
200 if(pdata->irq_gpio.io != INVALID_GPIO)
\r
201 gpio_direction_input(pdata->irq_gpio.io);
\r
202 //gpio_pull_updown(pdata->irq_gpio->io, GPIOPullDown);
\r
203 /* set to EINT mode */
\r
204 //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(0xF));
\r
205 /* get irq number */
\r
206 if(pdata->irq_gpio.io != INVALID_GPIO)
\r
207 irq_num = gpio_to_irq(pdata->irq_gpio.io);
\r
208 //mt_set_gpio_mode(GPIO_BT_EINT_PIN, GPIO_BT_EINT_PIN_M_GPIO);
\r
209 //mt_set_gpio_pull_enable(GPIO_BT_EINT_PIN, 1);
\r
210 //mt_set_gpio_pull_select(GPIO_BT_EINT_PIN, GPIO_PULL_DOWN);
\r
211 //mt_set_gpio_mode(GPIO_BT_EINT_PIN, GPIO_BT_EINT_PIN_M_EINT);
\r
214 //mt_set_gpio_mode(GPIO_BT_CLK_PIN , GPIO_BT_CLK_PIN_M_CLK);
\r
215 //mt_set_clock_output(GPIO_BT_CLK_PIN_CLK, CLK_SRC_F32K, 1);
\r
217 if(gpio_is_valid(pdata->rts_gpio.io)) {
\r
218 printk(KERN_INFO MODULE_TAG "mt_bt_power_on rts iomux\n");
\r
219 rk_mux_api_set(pdata->rts_gpio.iomux.name, pdata->rts_gpio.iomux.fgpio);
\r
220 gpio_direction_output(pdata->rts_gpio.io, 0);
\r
223 // PWR_EN and RESET
\r
224 /* PWR_EN set to gpio output low */
\r
225 if(pdata->power_gpio.io != INVALID_GPIO)
\r
226 gpio_direction_output(pdata->power_gpio.io, 0);
\r
227 /* RESET set to gpio output low */
\r
228 if(pdata->reset_gpio.io != INVALID_GPIO)
\r
229 gpio_direction_output(pdata->reset_gpio.io, 0);
\r
232 /* PWR_EN pull up */
\r
233 if(pdata->power_gpio.io != INVALID_GPIO)
\r
234 gpio_direction_output(pdata->power_gpio.io, 1);
\r
236 /* RESET pull up */
\r
237 if(pdata->reset_gpio.io != INVALID_GPIO)
\r
238 gpio_direction_output(pdata->reset_gpio.io, 1);
\r
241 if(gpio_is_valid(pdata->rts_gpio.io)) {
\r
242 rk_mux_api_set(pdata->rts_gpio.iomux.name, pdata->rts_gpio.iomux.fmux);
\r
245 error = mt_bt_request_irq();
\r
247 if(pdata->power_gpio.io != INVALID_GPIO)
\r
248 gpio_direction_output(pdata->power_gpio.io, 0);
\r
249 if(pdata->reset_gpio.io != INVALID_GPIO)
\r
250 gpio_direction_output(pdata->reset_gpio.io, 0);
\r
251 //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(1));
\r
252 if(pdata->irq_gpio.io != INVALID_GPIO)
\r
253 gpio_direction_output(pdata->irq_gpio.io, 0);
\r
258 printk(KERN_INFO MODULE_TAG "mt_bt_power_on --\n");
\r
263 EXPORT_SYMBOL(mt_bt_power_on);
\r
266 void mt_bt_power_off(void)
\r
268 struct mt6622_platform_data *pdata;
\r
269 pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();
\r
271 printk(KERN_INFO MODULE_TAG "mt_bt_power_off ++\n");
\r
274 // PWR_EN and RESET
\r
275 if(pdata->power_gpio.io != INVALID_GPIO)
\r
276 gpio_direction_output(pdata->power_gpio.io, 0);
\r
277 if(pdata->reset_gpio.io != INVALID_GPIO)
\r
278 gpio_direction_output(pdata->reset_gpio.io, 0);
\r
281 //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(1));
\r
282 if(pdata->irq_gpio.io != INVALID_GPIO)
\r
283 gpio_direction_output(pdata->irq_gpio.io, 0);
\r
288 printk(KERN_INFO MODULE_TAG "mt_bt_power_off --\n");
\r
291 EXPORT_SYMBOL(mt_bt_power_off);
\r