1 #define SII_HAL_LINUX_ISR_C
3 #include "sii_hal_priv.h"
4 #include "si_drvisrconfig.h"
5 #include <linux/kernel.h>
6 #include <linux/kthread.h>
7 #include <linux/sched.h>
8 #include <linux/wait.h>
9 #include <linux/completion.h>
10 #include <linux/interrupt.h>
11 #include <linux/delay.h>
12 #include <mach/irqs.h>
13 #include "mach/eint.h"
14 #include "mach/irqs.h"
15 #include <mach/mt_gpio.h>
16 #include <cust_gpio_usage.h>
17 #include <cust_eint.h>
18 #if !defined GPIO_MHL_EINT_PIN
19 /* #error GPIO_MHL_EINT_PIN not defined */
21 #if !defined CUST_EINT_MHL_NUM
22 /* /#error CUST_EINT_MHL_NUM not defined */
26 static irqreturn_t
HalThreadedIrqHandler(int irq
, void *data
)
28 pMhlDeviceContext pMhlDevContext
= (pMhlDeviceContext
) data
;
29 if (HalAcquireIsrLock() == HAL_RET_SUCCESS
) {
30 if (pMhlDevContext
->CheckDevice
&& !pMhlDevContext
->CheckDevice(0)) {
31 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
, "mhl device errror\n");
35 if (pMhlDevContext
->irqHandler
) {
36 (pMhlDevContext
->irqHandler
) ();
40 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
, "------------- irq missing! -------------\n");
46 static struct task_struct
*mhl_irq_task
;
48 static wait_queue_head_t mhl_irq_wq
;
50 #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
51 extern int smartbook_kthread(void *data
);
52 extern wait_queue_head_t smartbook_wq
;
53 static struct task_struct
*smartbook_task
; /* add by kirby */
56 static atomic_t mhl_irq_event
= ATOMIC_INIT(0);
60 static void mhl8338_irq_handler(void)
62 atomic_set(&mhl_irq_event
, 1);
63 wake_up_interruptible(&mhl_irq_wq
);
64 /* mt65xx_eint_unmask(CUST_EINT_HDMI_HPD_NUM); */
68 static int mhl_irq_kthread(void *data
)
70 struct sched_param param
= {.sched_priority
= RTPM_PRIO_SCRN_UPDATE
};
71 sched_setscheduler(current
, SCHED_RR
, ¶m
);
74 set_current_state(TASK_INTERRUPTIBLE
);
75 wait_event_interruptible(mhl_irq_wq
, atomic_read(&mhl_irq_event
));
76 set_current_state(TASK_RUNNING
);
77 printk("mhl_irq_kthread, mhl irq received\n");
78 /* hdmi_update_impl(); */
80 atomic_set(&mhl_irq_event
, 0);
82 if (kthread_should_stop())
84 #ifdef CUST_EINT_MHL_NUM
85 mt_eint_unmask(CUST_EINT_MHL_NUM
);
92 halReturn_t
HalInstallIrqHandler(fwIrqHandler_t irqHandler
)
97 init_waitqueue_head(&mhl_irq_wq
);
99 mhl_irq_task
= kthread_create(mhl_irq_kthread
, NULL
, "mhl_irq_kthread");
100 wake_up_process(mhl_irq_task
);
102 #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
104 init_waitqueue_head(&smartbook_wq
);
105 smartbook_task
= kthread_create(smartbook_kthread
, NULL
, "smartbook_kthread");
106 wake_up_process(smartbook_task
);
109 if (irqHandler
== NULL
) {
110 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
111 "HalInstallIrqHandler: irqHandler cannot be NULL!\n");
112 return HAL_RET_PARAMETER_ERROR
;
114 halRet
= I2cAccessCheck();
115 if (halRet
!= HAL_RET_SUCCESS
) {
119 if (gMhlDevice
.pI2cClient
->irq
== 0) {
120 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
121 "HalInstallIrqHandler: No IRQ assigned to I2C device!\n");
122 return HAL_RET_FAILURE
;
128 mt_set_gpio_mode(GPIO_MHL_EINT_PIN
, GPIO_MODE_01
);
129 mt_set_gpio_dir(GPIO_MHL_EINT_PIN
, GPIO_DIR_IN
);
130 mt_set_gpio_pull_select(GPIO_MHL_EINT_PIN
, GPIO_PULL_UP
);
131 mt_set_gpio_pull_enable(GPIO_MHL_EINT_PIN
, true);
134 #ifdef CUST_EINT_MHL_NUM
135 /* /mt_eint_set_sens(CUST_EINT_MHL_NUM, MT_LEVEL_SENSITIVE); */
136 /* /mt_eint_set_hw_debounce(CUST_EINT_MHL_NUM, CUST_EINT_MHL_DEBOUNCE_CN); */
137 mt_eint_registration(CUST_EINT_MHL_NUM
, CUST_EINT_MHL_TYPE
, &mhl8338_irq_handler
, 0);
138 mt_eint_unmask(CUST_EINT_MHL_NUM
);
140 printk("%s,%d Error: CUST_EINT_MHL_NUM is not defined\n", __func__
, __LINE__
);
143 gMhlDevice
.irqHandler
= irqHandler
;
144 retStatus
= request_threaded_irq(gMhlDevice
.pI2cClient
->irq
, NULL
,
145 HalThreadedIrqHandler
,
146 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
,
147 gMhlI2cIdTable
[0].name
, &gMhlDevice
);
148 if (retStatus
!= 0) {
149 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
150 "HalInstallIrqHandler: request_threaded_irq failed, status: %d\n",
152 gMhlDevice
.irqHandler
= NULL
;
153 return HAL_RET_FAILURE
;
156 return HAL_RET_SUCCESS
;
159 halReturn_t
HalRemoveIrqHandler(void)
162 halRet
= I2cAccessCheck();
163 if (halRet
!= HAL_RET_SUCCESS
) {
166 if (gMhlDevice
.irqHandler
== NULL
) {
167 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
168 "HalRemoveIrqHandler: no irqHandler installed!\n");
169 return HAL_RET_FAILURE
;
171 free_irq(gMhlDevice
.pI2cClient
->irq
, &gMhlDevice
);
172 gMhlDevice
.irqHandler
= NULL
;
173 return HAL_RET_SUCCESS
;
176 void HalEnableIrq(uint8_t bEnable
)
180 enable_irq(gMhlDevice
.pI2cClient
->irq
);
182 disable_irq(gMhlDevice
.pI2cClient
->irq
);
187 static irqreturn_t
HalSilMonRequestIrqHandler(int irq
, void *data
)
189 pMhlDeviceContext pMhlDevContext
= (pMhlDeviceContext
) data
;
192 spin_lock_irqsave(&pMhlDevContext
->SilMonRequestIRQ_Lock
, flags
);
193 if (HalGpioGetPin(GPIO_REQ_IN
, &gpio_value
) < 0) {
194 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
195 "HalSilMonRequestIrqHandler GPIO(%d) get error\n", gpio_value
);
196 spin_unlock_irqrestore(&pMhlDevContext
->SilMonRequestIRQ_Lock
, flags
);
199 if ((gMhlDevice
.SilMonControlReleased
&& gpio_value
)
200 || (!gMhlDevice
.SilMonControlReleased
&& !gpio_value
)) {
201 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
202 "HalSilMonRequestIrqHandler, wrong IRQ coming, please check you board\n");
203 spin_unlock_irqrestore(&pMhlDevContext
->SilMonRequestIRQ_Lock
, flags
);
207 /* HalGpioSetPin(GPIO_GNT,1); */
209 enable_irq(pMhlDevContext
->pI2cClient
->irq
);
211 enable_irq(pMhlDevContext
->SilExtDeviceIRQ
);
213 gMhlDevice
.SilMonControlReleased
= true;
215 disable_irq(pMhlDevContext
->pI2cClient
->irq
);
217 disable_irq(pMhlDevContext
->SilExtDeviceIRQ
);
220 /* HalGpioSetPin(GPIO_GNT,0); */
221 gMhlDevice
.SilMonControlReleased
= false;
223 spin_unlock_irqrestore(&pMhlDevContext
->SilMonRequestIRQ_Lock
, flags
);
227 halReturn_t
HalInstallSilMonRequestIrqHandler(void)
231 halRet
= I2cAccessCheck();
232 if (halRet
!= HAL_RET_SUCCESS
) {
235 halRet
= HalGetGpioIrqNumber(GPIO_REQ_IN
, &gMhlDevice
.SilMonRequestIRQ
);
236 if (halRet
!= HAL_RET_SUCCESS
) {
239 spin_lock_init(&gMhlDevice
.SilMonRequestIRQ_Lock
);
240 gMhlDevice
.SilMonControlReleased
= true;
241 retStatus
= request_threaded_irq(gMhlDevice
.SilMonRequestIRQ
, NULL
,
242 HalSilMonRequestIrqHandler
,
243 IRQF_TRIGGER_FALLING
| IRQF_TRIGGER_RISING
| IRQF_ONESHOT
,
244 gMhlI2cIdTable
[0].name
, &gMhlDevice
);
245 if (retStatus
!= 0) {
246 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
247 "HalInstallIrqHandler: request_threaded_irq failed, status: %d\n",
249 return HAL_RET_FAILURE
;
251 return HAL_RET_SUCCESS
;
254 halReturn_t
HalRemoveSilMonRequestIrqHandler(void)
257 halRet
= I2cAccessCheck();
258 if (halRet
!= HAL_RET_SUCCESS
) {
261 free_irq(gMhlDevice
.SilMonRequestIRQ
, &gMhlDevice
);
262 return HAL_RET_SUCCESS
;
266 static irqreturn_t
HalSilExtDeviceIrqHandler(int irq
, void *data
)
268 pMhlDeviceContext pMhlDevContext
= (pMhlDeviceContext
) data
;
269 if (HalAcquireIsrLock() == HAL_RET_SUCCESS
) {
270 if (pMhlDevContext
->CheckDevice
&& !pMhlDevContext
->CheckDevice(1)) {
274 if (pMhlDevContext
->ExtDeviceirqHandler
) {
275 (pMhlDevContext
->ExtDeviceirqHandler
) ();
279 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
280 "------------- ExtDevice irq missing! -------------\n");
286 halReturn_t
HalInstallSilExtDeviceIrqHandler(fwIrqHandler_t irqHandler
)
290 halRet
= I2cAccessCheck();
291 if (halRet
!= HAL_RET_SUCCESS
) {
294 halRet
= HalGetGpioIrqNumber(GPIO_V_INT
, &gMhlDevice
.SilExtDeviceIRQ
);
295 if (halRet
!= HAL_RET_SUCCESS
) {
298 gMhlDevice
.ExtDeviceirqHandler
= irqHandler
;
299 retStatus
= request_threaded_irq(gMhlDevice
.SilExtDeviceIRQ
, NULL
,
300 HalSilExtDeviceIrqHandler
,
301 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
,
302 gMhlI2cIdTable
[0].name
, &gMhlDevice
);
303 if (retStatus
!= 0) {
304 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
305 "HalInstallIrqHandler: request_threaded_irq failed, status: %d\n",
307 gMhlDevice
.ExtDeviceirqHandler
= NULL
;
308 return HAL_RET_FAILURE
;
310 return HAL_RET_SUCCESS
;
313 halReturn_t
HalRemoveSilExtDeviceIrqHandler(void)
316 halRet
= I2cAccessCheck();
317 if (halRet
!= HAL_RET_SUCCESS
) {
320 if (gMhlDevice
.ExtDeviceirqHandler
== NULL
) {
321 SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE
,
322 "HalRemoveSilExtDeviceIrqHandler: no irqHandler installed!\n");
323 return HAL_RET_FAILURE
;
325 free_irq(gMhlDevice
.SilExtDeviceIRQ
, &gMhlDevice
);
326 return HAL_RET_SUCCESS
;
330 halReturn_t
HalInstallCheckDeviceCB(fnCheckDevice fn
)
332 gMhlDevice
.CheckDevice
= fn
;
333 return HAL_RET_SUCCESS
;