s3c-keypad-qisda.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427
  1. /* Qisda Tony 090324, add keypad [
  2. * drivers/input/keyboard/s3c-keypad-qisda.c
  3. * KeyPad Interface on S3C in Qisda eBook
  4. *
  5. * This file is subject to the terms and conditions of the GNU General Public
  6. * License. See the file COPYING in the main directory of this archive
  7. * for more details.
  8. */
  9. #include <linux/module.h>
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/input.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/miscdevice.h>
  16. #include <linux/irq.h>
  17. #include <asm/arch/regs-irq.h>
  18. #include <asm/hardware.h>
  19. #include <asm/io.h>
  20. #include <asm/delay.h>
  21. #include <asm/irq.h>
  22. #include <asm/arch/regs-gpio.h>
  23. /*Qisda , wenny cheng , 20091224 , board id info {*/
  24. #include <../include/asm-arm/plat-s3c24xx/common-smdk.h>
  25. /*Qisda , wenny cheng , 20091224 , board id info }*/
  26. /* Qisda, ShiYong Lin, 2009/08/18, Detect insertion source {*/
  27. #include <asm/arch/regs-udc-hs.h>
  28. #include <asm/arch/regs-s3c2416-clock.h>
  29. /* } Qisda, ShiYong Lin, 2009/08/18, Detect insertion source */
  30. #define DPRINTK(x...) printk("S3C-Keypad-qisda " x)
  31. //#define DPRINTK(x...) /* !!!! */
  32. #define DEVICE_NAME "s3c-keypad-qisda"
  33. #define TRUE 1
  34. #define FALSE 0
  35. //#define IN_2416_EMU_BOARD
  36. /* Qisda, ShiYong Lin, 2009/07/18, Set Power key as EINT for sys shutdown{*/
  37. //#define POWER_KEY_FOR_SYS_SHUTDOWN
  38. /* Qisda, ShiYong Lin, 2009/07/18, Set Power key as EINT for sys shutdown}*/
  39. #define QISDA_TILT_0 0
  40. #define QISDA_TILT_90 1
  41. #define QISDA_TILT_180 3
  42. #define QISDA_TILT_270 2
  43. /*Qisda , wenny cheng , 20091224 , board id info {*/
  44. //static int hw_version_for_keypad = 0;
  45. extern int board_id;
  46. /*Qisda , wenny cheng , 20091224 , board id info }*/
  47. extern int average_adc_value_keep1; /*joey add to keep ADC will always return lower one 2009/12/28*/
  48. extern int average_adc_value_keep2; /*joey add to keep ADC will always return lower one 2009/12/28*/
  49. // Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event {
  50. int sleeping_cha_event = 0;
  51. // Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event }
  52. /*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
  53. #define OP_MODE_DELAY_REQUEST KEY_F9
  54. /*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
  55. #if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
  56. #define MAX_KEYPAD_QISDA 23 /*shiyong joey for asus 2009/12/15*/
  57. static int keypad_keycode_qisda[] = {
  58. KEY_PAGEDOWN, KEY_PAGEUP, KEY_VOLUMEDOWN, KEY_VOLUMEUP,
  59. KEY_F1, KEY_F2, KEY_F3, KEY_INSERT, KEY_ESC,
  60. /* Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP {*/
  61. KEY_CHA_STA_WALL_CHARGER, KEY_CHA_STA_UNPLUG,
  62. KEY_CHA_STA_USB, KEY_BATTERY_FAIL,
  63. KEY_SLEEP, KEY_TIMER_TICK,
  64. KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_SOUND,
  65. KEY_SD_INSERT, KEY_BATTERY /*shiyong joey for asus 2009/12/15*/
  66. };
  67. #endif
  68. #ifdef CONFIG_QISDA_QD060B00
  69. #define QISDA_E600
  70. //#define QISDA_L600
  71. //#define QISDA_BQ060B00_DVT
  72. #define MAX_KEYPAD_QISDA 29
  73. static int keypad_keycode_qisda[] = {
  74. KEY_MENU, KEY_SEARCH, KEY_PAGEDOWN, KEY_PAGEUP,
  75. KEY_BACK, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_WAKEUP,
  76. KEY_REFRESH, KEY_ENTER, KEY_UP, KEY_DOWN,
  77. KEY_LEFT, KEY_RIGHT,
  78. KEY_F1, KEY_F2, KEY_F3, KEY_F4,
  79. KEY_F5, KEY_F6,
  80. /* Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP {*/
  81. KEY_CLOSE, KEY_CHA_STA_WALL_CHARGER, KEY_CHA_STA_UNPLUG,
  82. KEY_CHA_STA_USB, KEY_BATTERY_FAIL,
  83. KEY_SLEEP, KEY_TIMER_TICK, KEY_BATTERY,
  84. /* } Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP */
  85. /*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
  86. KEY_F9
  87. /*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
  88. };
  89. #endif
  90. #ifdef CONFIG_QISDA_QD090B00
  91. #define MAX_KEYPAD_QISDA 27
  92. static int keypad_keycode_qisda[] = {
  93. KEY_MENU, KEY_SEARCH, KEY_PAGEDOWN, KEY_PAGEUP,
  94. KEY_BACK, KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_WAKEUP,
  95. KEY_REFRESH, KEY_ENTER, KEY_UP, KEY_DOWN,
  96. KEY_F1, KEY_F2, KEY_F3, KEY_F4,
  97. KEY_F5, KEY_F6,
  98. /* Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP {*/
  99. KEY_CLOSE, KEY_CHA_STA_WALL_CHARGER, KEY_CHA_STA_UNPLUG,
  100. KEY_CHA_STA_USB, KEY_BATTERY_FAIL,
  101. KEY_SLEEP, KEY_TIMER_TICK, KEY_BATTERY,
  102. /* } Qisda, ShiYong Lin, 2009/09/08, Implement for message for AP */
  103. /*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
  104. KEY_F9
  105. /*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
  106. };
  107. #endif
  108. struct s3c_keypad_qisda {
  109. struct input_dev *dev;
  110. int keycodes[MAX_KEYPAD_QISDA];
  111. int pressed[MAX_KEYPAD_QISDA];
  112. };
  113. //static struct work_struct wqReadData;
  114. static struct timer_list keypad_timer_qisda;
  115. static int is_timer_on_qisda = FALSE;
  116. static int keypad_set_irq = FALSE;
  117. /* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
  118. static struct timer_list charger_source_timer;
  119. /* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
  120. /*joey add timer to avoid bouncing with usb in/out 20100127*/
  121. static struct timer_list battery_status_timer;
  122. /* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
  123. static struct timer_list power_fail_timer;
  124. static struct work_struct power_fail_workq;
  125. u32 is_pwr_fail_timer_on = 0;
  126. /* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
  127. int charging_source = 3;
  128. struct input_dev *Message_dev = NULL;
  129. //static unsigned prevmask = 1;
  130. static void keypad_port_initialize(void)
  131. {
  132. #ifdef CONFIG_QISDA_AS090B00
  133. //Set gpio as input and pull-up enable
  134. s3c2410_gpio_cfgpin(S3C2410_GPD10, S3C2410_GPD10_INP); //T_SENSOR2
  135. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_INP); //T_SENSOR1
  136. s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); // power
  137. s3c2410_gpio_pullup(S3C2410_GPF0, 2);
  138. s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_INP); // Menu
  139. s3c2410_gpio_pullup(S3C2410_GPD14, 2);
  140. s3c2410_gpio_cfgpin(S3C2410_GPD15, S3C2410_GPD15_INP); // Return
  141. s3c2410_gpio_pullup(S3C2410_GPD15, 2);
  142. s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_INP); // Function
  143. s3c2410_gpio_pullup(S3C2410_GPG6, 2);
  144. s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // VOL+
  145. s3c2410_gpio_pullup(S3C2410_GPH4, 2);
  146. s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_INP); // VOL-
  147. s3c2410_gpio_pullup(S3C2410_GPH5, 2);
  148. s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_INP); // page up
  149. s3c2410_gpio_pullup(S3C2410_GPF7, 2);
  150. s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_INP); // Page down
  151. s3c2410_gpio_pullup(S3C2410_GPG7, 2);
  152. #endif
  153. #ifdef CONFIG_QISDA_QD090B00
  154. /*Qisda , wenny cheng , 20091224 , board id info {*/
  155. // hw_version_for_keypad = readl(S3C2416_GPKDAT) & (0x3<<3);
  156. printk("\nhw_version_for_keypad: %d\n", board_id);
  157. //if(hw_version_for_keypad){
  158. if(board_id != QD090B00_S02){
  159. s3c2410_gpio_cfgpin(S3C2410_GPC3, S3C2410_GPC3_OUTP); // Tilt_EN
  160. s3c2410_gpio_setpin(S3C2410_GPC3, 1);
  161. s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_EINT10); // Search
  162. s3c2410_gpio_pullup(S3C2410_GPG2, 2);
  163. s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11); // Return
  164. s3c2410_gpio_pullup(S3C2410_GPG3, 2);
  165. }
  166. else{
  167. //old
  168. s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_INP); // Search
  169. s3c2410_gpio_pullup(S3C2410_GPD14, 2);
  170. s3c2410_gpio_cfgpin(S3C2410_GPD15, S3C2410_GPD15_INP); // Return
  171. s3c2410_gpio_pullup(S3C2410_GPD15, 2);
  172. }
  173. /*Qisda , wenny cheng , 20091224 , board id info }*/
  174. //Set gpio as input and pull-up enable
  175. s3c2410_gpio_cfgpin(S3C2410_GPD10, S3C2410_GPD10_INP); //T_SENSOR2
  176. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_INP); //T_SENSOR1
  177. s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); // power
  178. s3c2410_gpio_pullup(S3C2410_GPF0, 2);
  179. s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_INP); // page down
  180. s3c2410_gpio_pullup(S3C2410_GPF7, 2);
  181. s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_INP); // Refresh
  182. s3c2410_gpio_pullup(S3C2410_GPG4, 2);
  183. s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_INP); // Menu
  184. s3c2410_gpio_pullup(S3C2410_GPG6, 2);
  185. s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_INP); // Page up
  186. s3c2410_gpio_pullup(S3C2410_GPG7, 2);
  187. s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // VOL+
  188. s3c2410_gpio_pullup(S3C2410_GPH4, 2);
  189. s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_INP); // VOL-
  190. s3c2410_gpio_pullup(S3C2410_GPH5, 2);
  191. #endif
  192. #ifdef CONFIG_QISDA_QD060B00
  193. s3c2410_gpio_cfgpin(S3C2410_GPC3, S3C2410_GPC3_OUTP); // Tilt_EN
  194. s3c2410_gpio_setpin(S3C2410_GPC3, 1);
  195. #ifdef CONFIG_QISDA_BK060B00
  196. s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_INP); //T_SENSOR2
  197. s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_INP); //T_SENSOR1
  198. s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_INP); // Menu / Plato: Menu
  199. s3c2410_gpio_pullup(S3C2410_GPG6, 2);
  200. s3c2410_gpio_cfgpin(S3C2410_GPG0, S3C2410_GPG0_INP); // VOL-/LEFT
  201. s3c2410_gpio_pullup(S3C2410_GPG0, 2);
  202. s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_INP); // VOL+/RIGHT
  203. s3c2410_gpio_pullup(S3C2410_GPG2, 2);
  204. s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_OUTP); // USB_SEL: DEVICE ONLY
  205. s3c2410_gpio_setpin(S3C2410_GPH5, 0);
  206. #else
  207. s3c2410_gpio_cfgpin(S3C2410_GPD10, S3C2410_GPD10_INP); //T_SENSOR2
  208. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_INP); //T_SENSOR1
  209. //Set gpio as input and pull-up enable
  210. // Qisda Jonas disable for keypad rework 20100104
  211. s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_INP); // Menu / Plato: Menu
  212. s3c2410_gpio_pullup(S3C2410_GPD14, 2);
  213. // Qisda Jonas disable for keypad rework
  214. s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); // power
  215. s3c2410_gpio_pullup(S3C2410_GPF0, 2);
  216. s3c2410_gpio_cfgpin(S3C2410_GPH5, S3C2410_GPH5_INP); // Search / UP / Plato: Vol up
  217. s3c2410_gpio_pullup(S3C2410_GPH5, 2);
  218. // Qisda Jonas modify for keypad rework 20100104
  219. s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11); // Menu key
  220. s3c2410_gpio_pullup(S3C2410_GPG3, 2);
  221. s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_EINT12); // Page up, Plato: Back
  222. s3c2410_gpio_pullup(S3C2410_GPG4, 2);
  223. // Qisda Jonas modify for keypad rework
  224. #endif
  225. s3c2410_gpio_cfgpin(S3C2410_GPD15, S3C2410_GPD15_INP); // Page down / Back / Plato: Back
  226. s3c2410_gpio_pullup(S3C2410_GPD15, 2);
  227. s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_EINT7); // Back / Right / Plato: Page down
  228. s3c2410_gpio_pullup(S3C2410_GPF7, 2);
  229. s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_EINT14); // VOL / Down / Plato: Search
  230. s3c2410_gpio_pullup(S3C2410_GPG6, 2);
  231. s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2410_GPG7_EINT15); // Refresh / Left / Plato: Page up
  232. s3c2410_gpio_pullup(S3C2410_GPG7, 2);
  233. #ifdef QISDA_L600
  234. s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // OK
  235. s3c2410_gpio_pullup(S3C2410_GPH4, 2);
  236. #endif
  237. #ifdef CONFIG_QISDA_BQ060B00_DVT
  238. s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_INP); // Plato: Vol down
  239. s3c2410_gpio_pullup(S3C2410_GPH4, 2);
  240. #endif
  241. #endif
  242. // CHG_STA, GPF6, Both edge triggered /*shiyong joey for asus 2009/12/15*/
  243. s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_EINT6);
  244. s3c2410_gpio_pullup(S3C2410_GPF6, 0); /*joey modify 2->0 20100127*/
  245. writel((readl(S3C2410_EXTINT0) & ~(1<<27)), S3C2410_EXTINT0);
  246. writel(((readl(S3C2410_EXTINT0) & ~(7<<24))|(4<<24)), S3C2410_EXTINT0); /*joey modify (6<<24) to (4<<24)) 20100127*/ /*1:high 4:rise 6:both*/
  247. // VBUS_IN_STA, GPG1, Both edge triggered /*shiyong joey for asus 2009/12/15*/
  248. s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9);
  249. s3c2410_gpio_pullup(S3C2410_GPG1, 0);
  250. writel((readl(S3C2410_EXTINT1) & ~(1<<7)), S3C2410_EXTINT1); /* EINT9 filter enable */
  251. writel(((readl(S3C2410_EXTINT1) & ~(7<<4))|(6<<4)), S3C2410_EXTINT1);
  252. // Power_Fail, GPG5, Both edge triggered /*shiyong joey for asus 2009/12/15*/
  253. s3c2410_gpio_cfgpin(S3C2410_GPG5, S3C2410_GPG5_EINT13);
  254. s3c2410_gpio_pullup(S3C2410_GPG5, 2);
  255. writel((readl(S3C2410_EXTINT1) & ~(1<<23)), S3C2410_EXTINT1);
  256. writel(((readl(S3C2410_EXTINT1) & ~(7<<20))|(6<<20)), S3C2410_EXTINT1);
  257. }
  258. struct s3c_keypad_qisda *pdata;
  259. /*
  260. static s3c_keypad_qisda_workqueue(struct work_struct *work)
  261. {
  262. struct input_dev *dev = pdata->dev;
  263. DPRINTK("s3c_keypad_qisda_workqueue 1\n");
  264. input_report_key(dev,pdata->keycodes[0],1);
  265. input_sync(dev);
  266. msleep(200);
  267. input_report_key(dev,pdata->keycodes[0],0);
  268. input_sync(dev);
  269. }
  270. */
  271. /* Qisda, ShiYong Lin, 2009/09/10, Detect insertion source {*/
  272. /*Leo*/
  273. int IsWallCharger(void)
  274. {
  275. u32 i=0;
  276. u32 read_pin=99, test_pin = 99;
  277. udelay(1000);
  278. if((readl(S3C2410_GPGDAT)&0x2)==0x2){
  279. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  280. s3c2410_gpio_setpin(S3C2443_GPH14, 1); /* usb power enbale */
  281. // s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPD13_OUTP);
  282. // s3c2410_gpio_setpin(S3C2410_GPD13,1); /* usb power enbale */
  283. /* if reset by sleep wakeup, control the retention I/O cell */
  284. if (__raw_readl(S3C_RSTSTAT) & 0x8)
  285. __raw_writel(__raw_readl(S3C_RSTCON)|(1<<16), S3C_RSTCON);
  286. __raw_writel(__raw_readl(S3C2410_MISCCR)&~(1<<12), S3C2410_MISCCR);
  287. __raw_writel(__raw_readl(S3C_PWRCFG)|(1<<4), S3C_PWRCFG);
  288. __raw_writel((0<<2)|(1<<0), S3C_URSTCON);
  289. udelay(1000);
  290. __raw_writel((1<<2)|(0<<0), S3C_URSTCON);
  291. __raw_writel((0<<2)|(0<<0), S3C_URSTCON);
  292. __raw_writel((0<<3)|(0<<2)|(1<<1)|(0<<0), S3C_PHYCTRL);
  293. __raw_writel((1<<31)|(0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0), S3C_PHYPWR);
  294. __raw_writel((0<<31)|(1<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
  295. __raw_writel((1<<31)|(1<<4)|(1<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
  296. }
  297. for(i=0;i<10;i++) {
  298. read_pin = __raw_readl(S3C_UDC_SYS_STATUS_REG)&0x60;
  299. udelay(1000);
  300. }
  301. //Benq,Andy modify for wall charger recognize bugfix
  302. //if( (read_pin != 0x60) ){
  303. if( (read_pin != 0x60) && (read_pin != 0x0)){ //Benq, Andy add (read_pin != 0x0)
  304. printk("usb\n");
  305. #if defined(CONFIG_QISDA_E600_EVT2)|| defined(CONFIG_QISDA_QD060N00_DVT1_1)
  306. if((readl(S3C2410_GPGDAT) &(1<<1))==0)
  307. {
  308. if((readl(S3C2410_GPHDAT) &&(1<<11))==0)
  309. {
  310. printk("3G Module off\n");
  311. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  312. s3c2410_gpio_setpin(S3C2443_GPH14, 0);
  313. }
  314. __raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
  315. }
  316. #endif
  317. #if defined(CONFIG_QISDA_AS090B00_EVT1)||defined(CONFIG_QISDA_AS090B00_EVT1_1)||defined(CONFIG_QISDA_QD090B00_EVT1)
  318. if((readl(S3C2410_GPGDAT) &(1<<1))==0)
  319. {
  320. if((readl(S3C2410_GPHDAT) &(1<<11))==0)
  321. {
  322. // printk("3G Module off\n");
  323. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  324. s3c2410_gpio_setpin(S3C2443_GPH14, 0);
  325. }
  326. __raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
  327. }
  328. #endif
  329. #ifdef CONFIG_PM_PLATFORM_POWER_SAVING
  330. //{Benq,Andy add for USB power disable
  331. printk("\nUSB_UDC_DEVICE_POWER_DOWN\n");
  332. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  333. s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb all power disable (USB_EN20)*/
  334. //}Benq,Andy add for USB power disable
  335. #endif
  336. return 0;
  337. }
  338. else
  339. {
  340. printk("wall charger\n");
  341. #if defined(CONFIG_QISDA_E600_EVT2)||defined(CONFIG_QISDA_QD060N00_DVT1_1)
  342. if((readl(S3C2410_GPGDAT) &(1<<1))==0)
  343. {
  344. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  345. s3c2410_gpio_setpin(S3C2443_GPH14, 0);
  346. __raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
  347. }
  348. #endif
  349. #if defined(CONFIG_QISDA_AS090B00_EVT1)||defined(CONFIG_QISDA_AS090B00_EVT1_1)||defined(CONFIG_QISDA_QD090B00_EVT1)
  350. if((readl(S3C2410_GPGDAT) &(1<<1))==0)
  351. {
  352. if((readl(S3C2410_GPHDAT) &(1<<11))==0)
  353. {
  354. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  355. s3c2410_gpio_setpin(S3C2443_GPH14, 0);
  356. }
  357. __raw_writel((0<<31)|(0<<2)|(1<<1)|(1<<0), S3C_UCLKCON);
  358. }
  359. #endif
  360. #ifdef CONFIG_PM_PLATFORM_POWER_SAVING
  361. //{Benq,Andy add for USB power disable
  362. printk("\nUSB_UDC_DEVICE_POWER_DOWN\n");
  363. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  364. s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb all power disable (USB_EN20)*/
  365. //}Benq,Andy add for USB power disable
  366. #endif
  367. return 1;
  368. }
  369. }
  370. /*Leo*/
  371. /* } Qisda, ShiYong Lin, 2009/09/10, Detect insertion source */
  372. static void s3c_keypad_deal(struct input_dev *dev, u32 read_pin, int key)
  373. {
  374. if(read_pin){ //should be released
  375. if(pdata->pressed[key]){
  376. input_report_key(dev, pdata->keycodes[key], 0);
  377. input_sync(dev);
  378. pdata->pressed[key] = 0;
  379. printk(" release: %d\n", pdata->keycodes[key]);
  380. }
  381. }
  382. else{ //should be pressed
  383. if(!pdata->pressed[key]){
  384. input_report_key(dev, pdata->keycodes[key], 1);
  385. input_sync(dev);
  386. pdata->pressed[key] = 1;
  387. printk(" press: %d\n", pdata->keycodes[key]);
  388. }
  389. }
  390. }
  391. static irqreturn_t s3c_pwrbtn_close_irq(int irq, void *id)
  392. {
  393. /* Qisda, ShiYong Lin, 2009/08/27, Implementing power btn behavior {*/
  394. struct input_dev *dev = id;
  395. u32 read_pin;
  396. read_pin = readl(S3C2410_GPFDAT) & (1<<0);
  397. #if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
  398. s3c_keypad_deal(dev, read_pin, 8);
  399. #elif defined(CONFIG_QISDA_QD090B00) || defined(CONFIG_QISDA_QD060N00_DVT1_1)
  400. s3c_keypad_deal(dev, read_pin, 7);
  401. #else
  402. s3c_keypad_deal(dev, read_pin, 7);
  403. #endif
  404. #ifdef POWER_KEY_FOR_SYS_SHUTDOWN
  405. //close system by letting P_KEEP low
  406. #ifdef CONFIG_QISDA_BK060B00
  407. s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_OUTP);
  408. s3c2410_gpio_setpin(S3C2410_GPD14, 0);
  409. #else
  410. s3c2410_gpio_setpin(S3C2410_GPG0, 0);
  411. s3c2410_gpio_cfgpin(S3C2410_GPG0, S3C2410_GPG0_OUTP);
  412. #endif
  413. #endif
  414. /* } Qisda, ShiYong Lin, 2009/08/27, Implementing power btn behavior */
  415. return IRQ_HANDLED;
  416. }
  417. static void battery_status_handler(unsigned long data)
  418. {
  419. //struct input_dev *dev = id;
  420. u32 read_pin;
  421. u32 i, j;
  422. printk("battery_status_handler\n");
  423. read_pin = readl(S3C2410_GPGDAT) & (1<<1); /*joey add condition with usb/charger 20100128*/
  424. if(read_pin!=0)
  425. {
  426. read_pin = readl(S3C2410_GPFDAT) & (0x01<<6);
  427. #ifdef CONFIG_QISDA_QD090B00
  428. if(read_pin)
  429. {
  430. //s3c_keypad_deal(dev, 0 , 25);
  431. input_report_key(Message_dev,KEY_BATTERY,1);
  432. input_sync(Message_dev);
  433. printk("s3c_battery_status_irq, keypad_message_to_ap\n");
  434. }
  435. else
  436. {
  437. //s3c_keypad_deal(dev, 1 , 25);
  438. input_report_key(Message_dev,KEY_BATTERY,0);
  439. input_sync(Message_dev);
  440. }
  441. #else
  442. if(read_pin)
  443. {
  444. //s3c_keypad_deal(dev, 0 , 27);
  445. input_report_key(Message_dev,KEY_BATTERY,1);
  446. input_sync(Message_dev);
  447. printk("s3c_battery_status_irq, keypad_message_to_ap\n");
  448. }
  449. else
  450. {
  451. //s3c_keypad_deal(dev, 1 , 27);
  452. input_report_key(Message_dev,KEY_BATTERY,0);
  453. input_sync(Message_dev);
  454. }
  455. #endif
  456. }
  457. enable_irq(IRQ_EINT6); /*joey add timer to avoid bouncing with usb in/out 20100127*/
  458. }
  459. static irqreturn_t s3c_battery_status_irq(int irq, void *id) /*joey add timer to avoid bouncing with usb in/out 20100127*/
  460. {
  461. printk("s3c_battery_status_irq, detecting\n");
  462. disable_irq(IRQ_EINT6);
  463. battery_status_timer.expires = jiffies + (HZ);
  464. add_timer(&battery_status_timer);
  465. return IRQ_HANDLED;
  466. }
  467. /* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
  468. static irqreturn_t s3c_cha_sta_irq(int irq, void *id)
  469. {
  470. /* Qisda , howard hsu, 2010/01/16 , op_mode-delay key event {*/
  471. op_mode_delay_message_to_ap(0);//0:usb,1:sd
  472. /* } Qisda , howard hsu, 2010/01/16 , op_mode-delay key event */
  473. // Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event {
  474. sleeping_cha_event = 1;
  475. // Qisda, 2010/02/18, TN Wei, sleep mode wakes up for usb event }
  476. printk("s3c_cha_sta_irq\n");
  477. disable_irq(IRQ_EINT9);
  478. charger_source_timer.expires = jiffies + (HZ);
  479. add_timer(&charger_source_timer);
  480. return IRQ_HANDLED;
  481. }
  482. /* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
  483. /* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
  484. static irqreturn_t s3c_pwr_fail_irq(int irq, void *id)
  485. {
  486. printk("s3c_pwr_fail_irq, detecting\n");
  487. disable_irq(IRQ_EINT13);
  488. power_fail_timer.expires = jiffies + (HZ*3);
  489. if(is_pwr_fail_timer_on == 0){
  490. // printk("add_timer, detected\n");
  491. add_timer(&power_fail_timer);
  492. is_pwr_fail_timer_on = 1;
  493. }
  494. else{
  495. // printk("mod_timer, detected\n");
  496. mod_timer(&power_fail_timer, keypad_timer_qisda.expires);
  497. }
  498. return IRQ_HANDLED;
  499. }
  500. /* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
  501. /* Qisda, ShiYong Lin, 2009/07/22, Implement function for RTC tick service {*/
  502. void rtc_tick_keypad_message_to_ap (void)
  503. {
  504. input_report_key(Message_dev,KEY_TIMER_TICK,1);
  505. input_sync(Message_dev);
  506. input_report_key(Message_dev,KEY_TIMER_TICK,0);
  507. input_sync(Message_dev);
  508. printk("rtc_tick_keypad_message_to_ap, keypad_message_to_ap\n");
  509. }
  510. /*} Qisda, ShiYong Lin, 2009/07/22, Implement function for RTC tick service */
  511. /* Qisda, Leo SJ Yang, 2009/10/26*/
  512. /*send key code F6 1 when USB plugin*/
  513. /*send key code F6 0 when USB unplug*/
  514. /*send key code F6 0 when safely remove usb{*/
  515. void USB_SaftRemove_keypad_message_to_ap(uint uiSleep)
  516. {
  517. if(uiSleep==1)
  518. {
  519. input_report_key(Message_dev,KEY_F6,1);
  520. input_sync(Message_dev);
  521. printk("Key-USB_PlugIn\n");
  522. }
  523. else
  524. {
  525. input_report_key(Message_dev,KEY_F6,0);
  526. input_sync(Message_dev);
  527. printk("Key-USB_PlugOut\n");
  528. //printk("USB_SaftRemove_keypad_message_to_ap, USB_SaftRemove_keypad_message_to_ap press\n");
  529. }
  530. }
  531. /*} Qisda, Leo SJ Yang, 2009/10/26*/
  532. /*Qisda , howard hsu, 20100116 , op_mode-delay key event {*/
  533. /* OP_MODE_DELAY_REQUEST is KEY_F9 */
  534. /* Qisda , howard hsu, 20100208 , add type, 0 for usb, 1 for sd */
  535. void op_mode_delay_message_to_ap(uint type)
  536. {
  537. static uint last_type=0;
  538. if (type == last_type)
  539. {
  540. if(pdata!=NULL)
  541. {
  542. change_bit(OP_MODE_DELAY_REQUEST,pdata->dev->key);
  543. }
  544. }
  545. last_type = type;
  546. input_report_key(Message_dev,OP_MODE_DELAY_REQUEST,type);
  547. input_sync(Message_dev);
  548. }
  549. /*} Qisda , howard hsu, 20100116 , op_mode-delay key event*/
  550. /* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
  551. // disable it first, wait integration test
  552. #ifdef CONFIG_SD_SW_DEBOUNCE
  553. void SD_Detect_keypad_message_to_ap(uint sd_on)
  554. {
  555. static uint last_sd_on=0;
  556. if (last_sd_on == sd_on)
  557. {
  558. printk("\nCC--Repeat SDKey(%d)\n",sd_on);
  559. if(pdata!=NULL)
  560. {
  561. change_bit(KEY_F5,pdata->dev->key);
  562. }
  563. }
  564. last_sd_on = sd_on;
  565. input_report_key(Message_dev,KEY_F5,sd_on);
  566. input_sync(Message_dev);
  567. printk("\nCC--SendSD Key(%d)\n",sd_on);
  568. }
  569. #endif /* CONFIG_SD_SW_DEBOUNCE */
  570. /* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
  571. /* Qisda, ShiYong Lin, 2009/09/08, Implement sleep message to AP {*/
  572. void s3c_keypad_pm_sleep_message_to_ap (uint uiSleep)
  573. {
  574. if(uiSleep){
  575. input_report_key(Message_dev,KEY_SLEEP,1);
  576. input_sync(Message_dev);
  577. }
  578. else{
  579. input_report_key(Message_dev,KEY_SLEEP,0);
  580. input_sync(Message_dev);
  581. }
  582. }
  583. /* } Qisda, ShiYong Lin, 2009/09/08, Implement sleep message to AP */
  584. static void s3c_keypad_set_irq(struct input_dev *dev)
  585. {
  586. set_irq_type(IRQ_EINT0, 0x3);
  587. request_irq(IRQ_EINT0, s3c_pwrbtn_close_irq,
  588. SA_INTERRUPT, DEVICE_NAME, dev);
  589. set_irq_type(IRQ_EINT6, 0x3); /*shiyong joey for asus 2009/12/15*/
  590. request_irq(IRQ_EINT6, s3c_battery_status_irq,
  591. SA_INTERRUPT, "s3c2410-battery status", dev);
  592. set_irq_type(IRQ_EINT9, 0x3);
  593. request_irq(IRQ_EINT9, s3c_cha_sta_irq,
  594. SA_INTERRUPT, "s3c2410-charging status", dev);
  595. /* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
  596. if((readl(S3C2410_GPGDAT) & (1<<5)) == 0){
  597. set_irq_type(IRQ_EINT13, IRQT_HIGH);
  598. }
  599. else{
  600. set_irq_type(IRQ_EINT13, IRQT_LOW);
  601. }
  602. /* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
  603. request_irq(IRQ_EINT13, s3c_pwr_fail_irq,
  604. SA_INTERRUPT, "s3c2410-power fail status", dev);
  605. }
  606. /* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
  607. static void charger_source_handler(unsigned long data)
  608. {
  609. u32 read_pin = 99;
  610. printk("charger_source_handler_qisda\n");
  611. read_pin = readl(S3C2410_GPGDAT) & (1<<1);
  612. printk("GPG1 = %d\n", read_pin);
  613. if(read_pin != 0){
  614. //s3c2410_gpio_pullup(S3C2410_GPF6, 0); /*joey add to put floating GPF6 with usb 20100201*/
  615. average_adc_value_keep1=9999; /*joey add to keep ADC will always return lower one 2009/12/28*/
  616. average_adc_value_keep2=9999; /*joey add to keep ADC will always return lower one 2009/12/28*/
  617. input_report_key(Message_dev, KEY_CHA_STA_UNPLUG, 0);
  618. input_sync(Message_dev);
  619. printk("usb or wallchager\n");
  620. if(IsWallCharger()==0){
  621. charging_source = 0;
  622. input_report_key(Message_dev, KEY_CHA_STA_USB, 1);
  623. input_sync(Message_dev);
  624. printk("USB, EN2 = 0, EN1 = 1\n");
  625. //EN2
  626. s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
  627. s3c2410_gpio_setpin(S3C2410_GPB0, 0);
  628. //EN1
  629. s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
  630. s3c2410_gpio_setpin(S3C2410_GPB4, 1);
  631. }
  632. else
  633. {
  634. charging_source = 1;
  635. input_report_key(Message_dev, KEY_CHA_STA_WALL_CHARGER, 1);
  636. input_sync(Message_dev);
  637. printk("Charger, EN2 = 1, EN1 = 0\n");
  638. //EN2
  639. s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
  640. s3c2410_gpio_setpin(S3C2410_GPB0, 1);
  641. //EN1
  642. s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
  643. s3c2410_gpio_setpin(S3C2410_GPB4, 0);
  644. }
  645. }
  646. else{
  647. //s3c2410_gpio_pullup(S3C2410_GPF6, 1); /*joey add to pull low GPF6 without usb 20100201*/
  648. printk("nothing\n");
  649. input_report_key(Message_dev, KEY_CHA_STA_UNPLUG, 1);
  650. input_sync(Message_dev);
  651. if(charging_source==0){
  652. input_report_key(Message_dev, KEY_CHA_STA_USB, 0);
  653. input_sync(Message_dev);
  654. }
  655. else{
  656. input_report_key(Message_dev, KEY_CHA_STA_WALL_CHARGER, 0);
  657. input_sync(Message_dev);
  658. }
  659. charging_source = 2;
  660. printk("EN2 = 0, EN1 = 1\n");
  661. //EN2
  662. s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
  663. s3c2410_gpio_setpin(S3C2410_GPB0, 0);
  664. //EN1
  665. s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP);
  666. s3c2410_gpio_setpin(S3C2410_GPB4, 1);
  667. #ifdef CONFIG_PM_PLATFORM_POWER_SAVING
  668. //{Benq,Andy add for disable USB power
  669. printk("\nUSB_UDC_DEVICE_POWER_DOWN\n");
  670. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  671. s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb all power disable (USB33 & USB12)*/
  672. //}Benq,Andy add for disable USB power
  673. #endif
  674. }
  675. enable_irq(IRQ_EINT9);
  676. }
  677. /* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
  678. /* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
  679. static void power_fail_handler(unsigned long data)
  680. {
  681. // printk("power_fail_handler\n");
  682. schedule_work(&power_fail_workq);
  683. }
  684. static void power_fail_workqueue(struct work_struct *work)
  685. {
  686. u32 test_pin, i;
  687. u32 read_pin = readl(S3C2410_GPGDAT) & (1<<5);
  688. msleep(1);
  689. // printk("power_fail_workqueue, read_pin = %d\n",read_pin);
  690. for(i = 0; i <100; i++){
  691. test_pin = readl(S3C2410_GPGDAT) & (1<<5);
  692. msleep(1);
  693. if(read_pin != test_pin){
  694. printk("read_pin != test_pin\n");
  695. is_pwr_fail_timer_on = 0;
  696. enable_irq(IRQ_EINT13);
  697. return;
  698. }
  699. msleep(1);
  700. }
  701. // printk("power_fail_workqueue test_pin = %d\n", read_pin);
  702. if(read_pin == 0){
  703. // printk("send KEY_BATTERY_FAIL trigger, 0\n");
  704. set_irq_type(IRQ_EINT13, IRQT_HIGH);
  705. #if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
  706. s3c_keypad_deal(Message_dev, 0, 12);
  707. #elif defined(CONFIG_QISDA_QD090B00)
  708. s3c_keypad_deal(Message_dev, 0, 22);
  709. #elif CONFIG_QISDA_QD060N00_DVT1_1
  710. s3c_keypad_deal(Message_dev, 0, 24);
  711. #else
  712. s3c_keypad_deal(Message_dev, 0, 12);
  713. #endif
  714. }
  715. else{
  716. // printk("send KEY_BATTERY_FAIL trigger, 1\n");
  717. set_irq_type(IRQ_EINT13, IRQT_LOW);
  718. #if defined(CONFIG_QISDA_AS090B00_EVT1) || defined(CONFIG_QISDA_AS090B00_EVT1_1)
  719. s3c_keypad_deal(Message_dev, 1, 12);
  720. #elif defined(CONFIG_QISDA_QD090B00)
  721. s3c_keypad_deal(Message_dev, 1, 22);
  722. #elif CONFIG_QISDA_QD060N00_DVT1_1
  723. s3c_keypad_deal(Message_dev, 1, 24);
  724. #else
  725. s3c_keypad_deal(Message_dev, 1, 12);
  726. #endif
  727. }
  728. is_pwr_fail_timer_on = 0;
  729. enable_irq(IRQ_EINT13);
  730. return;
  731. }
  732. /* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
  733. static void keypad_timer_handler_qisda(unsigned long data)
  734. {
  735. u32 read_pin;
  736. static u32 headphonr_insert;
  737. static int headphonr_insert_counter=2;
  738. u32 read_tilt;
  739. static u32 tilt_status_previous;
  740. static int tilt_counter=3;
  741. static u32 mmc_status_previous = 0xF;
  742. static int mmc_counter=16;
  743. //struct s3c_keypad_qisda *pdata = (struct s3c_keypad_qisda *)data;
  744. pdata = (struct s3c_keypad_qisda *)data;
  745. struct input_dev *dev = pdata->dev;
  746. #ifdef CONFIG_QISDA_AS090B00
  747. read_pin = readl(S3C2410_GPFDAT);
  748. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 0); // Page down
  749. s3c_keypad_deal(dev, (read_pin & (0x1<<1)), 21); // SD card
  750. if(headphonr_insert != (read_pin & (1<<4))){ // Headphone
  751. if(headphonr_insert_counter != 0){
  752. headphonr_insert_counter --;
  753. }
  754. else{
  755. if(read_pin & (1<<4)){
  756. //printk("Earphone insert!!!!!!!!!!!!!!!!\n");
  757. input_report_switch(dev, SW_HEADPHONE_INSERT, 1);
  758. input_sync(dev);
  759. }
  760. else {
  761. //printk("Earphone remove!!!!!!!!!!!!!!!!!!!!!\n");
  762. input_report_switch(dev, SW_HEADPHONE_INSERT, 0);
  763. input_sync(dev);
  764. }
  765. headphonr_insert = read_pin & (1<<4);
  766. headphonr_insert_counter = 2;
  767. }
  768. }
  769. else{
  770. headphonr_insert_counter = 2;
  771. }
  772. read_pin = readl(S3C2410_GPGDAT);
  773. s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 6); // Function
  774. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 1); // Page up
  775. read_pin = readl(S3C2410_GPHDAT);
  776. s3c_keypad_deal(dev, read_pin & 1<<5, 2); // Volume down
  777. s3c_keypad_deal(dev, read_pin & 1<<4, 3); // Volume up
  778. read_pin = readl(S3C2410_GPDDAT);
  779. s3c_keypad_deal(dev, read_pin & 1<<14, 5); // Menu
  780. s3c_keypad_deal(dev, read_pin & 1<<15, 7); // Return
  781. read_tilt = (readl(S3C2410_GPDDAT) & (0x3<<10)) >> 10;
  782. if(tilt_status_previous != read_tilt){
  783. if(tilt_counter != 0){
  784. tilt_counter--;
  785. }
  786. else{
  787. if(read_tilt == QISDA_TILT_270){
  788. s3c_keypad_deal(dev, 1, 16);
  789. s3c_keypad_deal(dev, 1, 17);
  790. s3c_keypad_deal(dev, 1, 18);
  791. s3c_keypad_deal(dev, 0, 19);
  792. }
  793. else if(read_tilt == QISDA_TILT_90){
  794. s3c_keypad_deal(dev, 1, 16);
  795. s3c_keypad_deal(dev, 1, 18);
  796. s3c_keypad_deal(dev, 1, 19);
  797. s3c_keypad_deal(dev, 0, 17);
  798. }
  799. else if(read_tilt == QISDA_TILT_180){
  800. s3c_keypad_deal(dev, 1, 16);
  801. s3c_keypad_deal(dev, 1, 17);
  802. s3c_keypad_deal(dev, 1, 19);
  803. s3c_keypad_deal(dev, 0, 18);
  804. }
  805. else{ //QISDA_TILT_0
  806. s3c_keypad_deal(dev, 1, 17);
  807. s3c_keypad_deal(dev, 1, 18);
  808. s3c_keypad_deal(dev, 1, 19);
  809. s3c_keypad_deal(dev, 0, 16);
  810. }
  811. tilt_status_previous = read_tilt;
  812. tilt_counter = 3;
  813. }
  814. }
  815. else{
  816. tilt_counter = 3;
  817. s3c_keypad_deal(dev, 1, 16);
  818. s3c_keypad_deal(dev, 1, 17);
  819. s3c_keypad_deal(dev, 1, 18);
  820. s3c_keypad_deal(dev, 1, 19);
  821. }
  822. #endif
  823. #ifdef CONFIG_QISDA_QD090B00
  824. read_pin = readl(S3C2410_GPFDAT);
  825. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 2); // Page down
  826. /* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
  827. #ifndef CONFIG_SD_SW_DEBOUNCE
  828. if(mmc_status_previous != (read_pin & (0x1<<1))){
  829. if(mmc_counter != 0){
  830. mmc_counter--;
  831. }
  832. else{
  833. s3c_keypad_deal(dev, (read_pin & (0x1<<1)), 16); // SD card
  834. mmc_status_previous = (read_pin & (0x1<<1));
  835. mmc_counter=16;
  836. }
  837. }
  838. else{
  839. mmc_counter=16;
  840. }
  841. #endif /* CONFIG_SD_SW_DEBOUNCE */
  842. /* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
  843. if(headphonr_insert != (read_pin & (1<<4))){ // Headphone
  844. if(headphonr_insert_counter != 0){
  845. headphonr_insert_counter --;
  846. }
  847. else{
  848. if(read_pin & (1<<4)){
  849. //printk("Earphone insert!!!!!!!!!!!!!!!!\n");
  850. input_report_switch(dev, SW_HEADPHONE_INSERT, 1);
  851. input_sync(dev);
  852. }
  853. else {
  854. //printk("Earphone remove!!!!!!!!!!!!!!!!!!!!!\n");
  855. input_report_switch(dev, SW_HEADPHONE_INSERT, 0);
  856. input_sync(dev);
  857. }
  858. headphonr_insert = read_pin & (1<<4);
  859. headphonr_insert_counter = 2;
  860. }
  861. }
  862. else{
  863. headphonr_insert_counter = 2;
  864. }
  865. read_pin = readl(S3C2410_GPGDAT);
  866. s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 8); // Refresh
  867. s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 0); // Menu
  868. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 3); // Page up
  869. /*Qisda , wenny cheng , 20091224 , board id info {*/
  870. //if(hw_version_for_keypad){
  871. if(board_id !=QD090B00_S02)
  872. {
  873. //new
  874. s3c_keypad_deal(dev, read_pin & 1<<2, 1); // Search
  875. s3c_keypad_deal(dev, read_pin & 1<<3, 4); // Return
  876. }
  877. /*Qisda , wenny cheng , 20091224 , board id info }*/
  878. read_pin = readl(S3C2410_GPHDAT);
  879. s3c_keypad_deal(dev, read_pin & 1<<5, 5); // Volume down
  880. s3c_keypad_deal(dev, read_pin & 1<<4, 6); // Volume up
  881. read_pin = readl(S3C2410_GPDDAT);
  882. /*Qisda , wenny cheng , 20091224 , board id info {*/
  883. //if(!hw_version_for_keypad){
  884. if(board_id ==QD090B00_S02)
  885. {
  886. //old
  887. s3c_keypad_deal(dev, read_pin & 1<<14, 1); // Search
  888. s3c_keypad_deal(dev, read_pin & 1<<15, 4); // Return
  889. }
  890. /*Qisda , wenny cheng , 20091224 , board id info }*/
  891. read_tilt = (read_pin & (0x3<<10)) >> 10;
  892. if(tilt_status_previous != read_tilt){
  893. if(tilt_counter != 0){
  894. tilt_counter--;
  895. }
  896. else{
  897. if(read_tilt == QISDA_TILT_270){
  898. s3c_keypad_deal(dev, 1, 12);
  899. s3c_keypad_deal(dev, 1, 13);
  900. s3c_keypad_deal(dev, 1, 14);
  901. s3c_keypad_deal(dev, 0, 15);
  902. }
  903. else if(read_tilt == QISDA_TILT_90){
  904. s3c_keypad_deal(dev, 1, 12);
  905. s3c_keypad_deal(dev, 1, 15);
  906. s3c_keypad_deal(dev, 1, 14);
  907. s3c_keypad_deal(dev, 0, 13);
  908. }
  909. else if(read_tilt == QISDA_TILT_180){
  910. s3c_keypad_deal(dev, 1, 15);
  911. s3c_keypad_deal(dev, 1, 12);
  912. s3c_keypad_deal(dev, 1, 13);
  913. s3c_keypad_deal(dev, 0, 14);
  914. }
  915. else{ //QISDA_TILT_0
  916. s3c_keypad_deal(dev, 1, 15);
  917. s3c_keypad_deal(dev, 1, 13);
  918. s3c_keypad_deal(dev, 1, 14);
  919. s3c_keypad_deal(dev, 0, 12);
  920. }
  921. tilt_status_previous = read_tilt;
  922. tilt_counter = 3;
  923. }
  924. }
  925. else{
  926. tilt_counter = 3;
  927. s3c_keypad_deal(dev, 1, 12);
  928. s3c_keypad_deal(dev, 1, 13);
  929. s3c_keypad_deal(dev, 1, 14);
  930. s3c_keypad_deal(dev, 1, 15);
  931. }
  932. #endif
  933. #ifdef CONFIG_QISDA_QD060B00
  934. read_pin = readl(S3C2410_GPFDAT);
  935. #ifdef QISDA_E600
  936. #ifdef CONFIG_QISDA_BQ060B00_DVT
  937. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 2); // Page down
  938. #else
  939. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 4); // Back
  940. #endif
  941. #endif
  942. #ifdef QISDA_L600
  943. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 13); // Right
  944. #endif
  945. /* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
  946. #ifndef CONFIG_SD_SW_DEBOUNCE
  947. if(mmc_status_previous != (read_pin & (0x1<<1))){
  948. if(mmc_counter != 0){
  949. mmc_counter--;
  950. }
  951. else{
  952. s3c_keypad_deal(dev, (read_pin & (0x1<<1)), 18); // SD card
  953. mmc_status_previous = (read_pin & (0x1<<1));
  954. printk("Key-SD_CHANGE(%d)\n",mmc_status_previous);
  955. mmc_counter=16;
  956. }
  957. }
  958. else{
  959. mmc_counter=16;
  960. }
  961. #endif /* CONFIG_SD_SW_DEBOUNCE */
  962. /* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
  963. if(headphonr_insert != (read_pin & (1<<4))){ // Headphone
  964. if(headphonr_insert_counter != 0){
  965. headphonr_insert_counter --;
  966. }
  967. else{
  968. if(read_pin & (1<<4)){
  969. //printk("Earphone removed\n");
  970. input_report_switch(dev, SW_HEADPHONE_INSERT, 0);
  971. input_sync(dev);
  972. }
  973. else {
  974. //printk("Earphone inserted\n");
  975. input_report_switch(dev, SW_HEADPHONE_INSERT, 1);
  976. input_sync(dev);
  977. }
  978. headphonr_insert = read_pin & (1<<4);
  979. headphonr_insert_counter = 2;
  980. }
  981. }
  982. else{
  983. headphonr_insert_counter = 2;
  984. }
  985. read_pin = readl(S3C2410_GPGDAT);
  986. #ifdef QISDA_E600
  987. #ifdef CONFIG_QISDA_BQ060B00_DVT
  988. //s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 8); // Refresh
  989. s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 1); // Search
  990. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 3); // Page up
  991. if(board_id ==BQ060B00_A02)
  992. {
  993. s3c_keypad_deal(dev, (read_pin & (0x1<<3)), 0); // Menu
  994. s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 4); // Back
  995. }
  996. #else
  997. s3c_keypad_deal(dev, (read_pin & (0x1<<4)), 3); // Page up
  998. if(board_id ==QD060B00_A02) {
  999. s3c_keypad_deal(dev, (read_pin & (0x1<<3)), 0); // Menu
  1000. s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 2); // Page down
  1001. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 1); // Search
  1002. } else if(board_id == QD060B00_A01_And_Before){
  1003. s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 6); // Volume
  1004. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 8); // Refresh
  1005. }
  1006. #endif
  1007. #endif
  1008. #ifdef QISDA_L600
  1009. s3c_keypad_deal(dev, (read_pin & (0x1<<6)), 11); // Down
  1010. s3c_keypad_deal(dev, (read_pin & (0x1<<7)), 12); // Left
  1011. #endif
  1012. #ifdef CONFIG_QISDA_BK060B00
  1013. s3c_keypad_deal(dev, (read_pin & (0x1<<0)), 12); // LEFT
  1014. s3c_keypad_deal(dev, (read_pin & (0x1<<2)), 13); // RIGHT
  1015. #endif
  1016. read_pin = readl(S3C2410_GPHDAT);
  1017. #ifdef QISDA_E600
  1018. #ifdef CONFIG_QISDA_BQ060B00_DVT
  1019. s3c_keypad_deal(dev, read_pin & 1<<4, 5); // Volume down
  1020. s3c_keypad_deal(dev, read_pin & 1<<5, 6); // Volume up
  1021. #else
  1022. // Qisda Jonas modify for keypad rework 20100104
  1023. if(board_id ==QD060B00_A02) {
  1024. s3c_keypad_deal(dev, read_pin & 1<<5, 8); // Refresh
  1025. } else if (board_id == QD060B00_A01_And_Before){
  1026. s3c_keypad_deal(dev, read_pin & 1<<5, 1); // Search
  1027. }
  1028. // Qisda Jonas modify for keypad rework
  1029. #endif
  1030. #endif
  1031. #ifdef QISDA_L600
  1032. s3c_keypad_deal(dev, read_pin & 1<<4, 9); // OK
  1033. s3c_keypad_deal(dev, read_pin & 1<<5, 10); // Up
  1034. #endif
  1035. read_pin = readl(S3C2410_GPDDAT);
  1036. #ifdef QISDA_E600
  1037. #ifdef CONFIG_QISDA_BQ060B00_DVT
  1038. // Qisda Jonas modify for keypad rework 20100103
  1039. if(board_id ==BQ060B00_A01_And_Before)
  1040. {
  1041. s3c_keypad_deal(dev, read_pin & 1<<14, 0); // Menu
  1042. s3c_keypad_deal(dev, read_pin & 1<<15, 4); // Back
  1043. }
  1044. #else
  1045. // Qisda Jonas modify for keypad rework
  1046. if(board_id == QD060B00_A02) {
  1047. s3c_keypad_deal(dev, read_pin & 1<<15, 6); // Volumn
  1048. } else if(board_id == QD060B00_A01_And_Before){
  1049. s3c_keypad_deal(dev, read_pin & 1<<14, 0); // Menu
  1050. s3c_keypad_deal(dev, read_pin & 1<<15, 2); // Page down
  1051. }
  1052. #endif
  1053. #endif
  1054. #ifdef QISDA_L600
  1055. s3c_keypad_deal(dev, read_pin & 1<<15, 4); // Back
  1056. #endif
  1057. //Benq,Aaron: no tilt sensor in Plato
  1058. #ifndef CONFIG_QISDA_BQ060B00_DVT
  1059. #ifdef CONFIG_QISDA_BK060B00
  1060. read_pin = readl(S3C2410_GPGDAT);
  1061. read_tilt = (read_pin & (0x3<<3)) >> 3;
  1062. #else
  1063. read_tilt = (read_pin & (0x3<<10)) >> 10;
  1064. #endif
  1065. if(tilt_status_previous != read_tilt){
  1066. if(tilt_counter != 0){
  1067. tilt_counter--;
  1068. }
  1069. else{
  1070. if(read_tilt == QISDA_TILT_270){
  1071. s3c_keypad_deal(dev, 1, 14);
  1072. s3c_keypad_deal(dev, 1, 15);
  1073. s3c_keypad_deal(dev, 1, 16);
  1074. s3c_keypad_deal(dev, 0, 17);
  1075. }
  1076. else if(read_tilt == QISDA_TILT_90){
  1077. s3c_keypad_deal(dev, 1, 14);
  1078. s3c_keypad_deal(dev, 1, 17);
  1079. s3c_keypad_deal(dev, 1, 16);
  1080. s3c_keypad_deal(dev, 0, 15);
  1081. }
  1082. else if(read_tilt == QISDA_TILT_180){
  1083. s3c_keypad_deal(dev, 1, 17);
  1084. s3c_keypad_deal(dev, 1, 14);
  1085. s3c_keypad_deal(dev, 1, 15);
  1086. s3c_keypad_deal(dev, 0, 16);
  1087. }
  1088. else{ //QISDA_TILT_0
  1089. s3c_keypad_deal(dev, 1, 17);
  1090. s3c_keypad_deal(dev, 1, 15);
  1091. s3c_keypad_deal(dev, 1, 16);
  1092. s3c_keypad_deal(dev, 0, 14);
  1093. }
  1094. tilt_status_previous = read_tilt;
  1095. tilt_counter = 3;
  1096. }
  1097. }
  1098. else{
  1099. tilt_counter = 3;
  1100. s3c_keypad_deal(dev, 1, 14);
  1101. s3c_keypad_deal(dev, 1, 15);
  1102. s3c_keypad_deal(dev, 1, 16);
  1103. s3c_keypad_deal(dev, 1, 17);
  1104. }
  1105. #endif // #ifndef CONFIG_QISDA_BQ060B00_DVT
  1106. #endif
  1107. if (is_timer_on_qisda == FALSE) {
  1108. add_timer(&keypad_timer_qisda);
  1109. is_timer_on_qisda = TRUE;
  1110. } else {
  1111. keypad_timer_qisda.expires = jiffies + (HZ/8);
  1112. mod_timer(&keypad_timer_qisda,keypad_timer_qisda.expires);
  1113. }
  1114. if(!keypad_set_irq){
  1115. s3c_keypad_set_irq(pdata->dev);
  1116. keypad_set_irq = TRUE;
  1117. }
  1118. }
  1119. static int __init s3c_keypad_qisda_probe(struct platform_device *pdev)
  1120. {
  1121. int ret=0;
  1122. int i;
  1123. struct input_dev *input_dev;
  1124. struct s3c_keypad_qisda *s3c_keypad_qisda;
  1125. DPRINTK("s3c_keypad_qisda_probe for Qisda eBook\n");
  1126. keypad_port_initialize();
  1127. s3c_keypad_qisda = kzalloc(sizeof(struct s3c_keypad_qisda), GFP_KERNEL);
  1128. input_dev = input_allocate_device();
  1129. if (!s3c_keypad_qisda || !input_dev) {
  1130. ret = -ENOMEM;
  1131. goto out;
  1132. }
  1133. platform_set_drvdata(pdev, s3c_keypad_qisda);
  1134. s3c_keypad_qisda->dev = input_dev;
  1135. /* create and register the input driver */
  1136. set_bit(EV_KEY, input_dev->evbit);
  1137. //set_bit(EV_REP, input_dev->evbit);
  1138. set_bit(EV_SW, input_dev->evbit);
  1139. set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
  1140. for(i=0; i<MAX_KEYPAD_QISDA; i++){
  1141. s3c_keypad_qisda->keycodes[i] = keypad_keycode_qisda[i];
  1142. s3c_keypad_qisda->pressed[i] = 0;
  1143. set_bit(s3c_keypad_qisda->keycodes[i] & KEY_MAX, input_dev->keybit);
  1144. }
  1145. input_dev->name = DEVICE_NAME;
  1146. input_dev->phys = "s3c-keypad-qisda/input0";
  1147. input_dev->cdev.dev = &pdev->dev;
  1148. input_dev->private = s3c_keypad_qisda;
  1149. input_dev->id.bustype = BUS_HOST;
  1150. input_dev->id.vendor = 0x0001;
  1151. input_dev->id.product = 0x0001;
  1152. input_dev->id.version = 0x0001;
  1153. input_dev->keycode = keypad_keycode_qisda;
  1154. input_register_device(input_dev);
  1155. /* Scan timer init */
  1156. init_timer(&keypad_timer_qisda);
  1157. keypad_timer_qisda.function = keypad_timer_handler_qisda;
  1158. keypad_timer_qisda.data = (unsigned long)s3c_keypad_qisda;
  1159. keypad_timer_qisda.expires = jiffies + (HZ*10);
  1160. if (is_timer_on_qisda == FALSE) {
  1161. add_timer(&keypad_timer_qisda);
  1162. is_timer_on_qisda = TRUE;
  1163. } else {
  1164. mod_timer(&keypad_timer_qisda,keypad_timer_qisda.expires);
  1165. }
  1166. /* Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb {*/
  1167. init_timer(&charger_source_timer);
  1168. charger_source_timer.function = charger_source_handler;
  1169. /* } Qisda, ShiYong Lin, 2009/11/11, Fix the trembling voice issue when plugging usb */
  1170. /*joey add timer to avoid bouncing with usb in/out 20100127*/
  1171. init_timer(&battery_status_timer);
  1172. battery_status_timer.function = battery_status_handler;
  1173. /* Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading {*/
  1174. init_timer(&power_fail_timer);
  1175. power_fail_timer.function = power_fail_handler;
  1176. INIT_WORK(&power_fail_workq, power_fail_workqueue);
  1177. /* } Qisda, ShiYong Lin, 2009/11/11, Modify for pwr fail event occurring wrongly when heavy loading */
  1178. //initial work queue
  1179. //INIT_WORK(&wqReadData,s3c_keypad_qisda_workqueue);
  1180. //{Benq,Andy add for USB cable unplug bugfix
  1181. //If boot up with USB cable, s3c_adc_init will set charging_source to 0, without sending input_report_key,
  1182. //so recheck is needed when initializing keypad, setting KEY_CHA_STA_USB to 1
  1183. if( charging_source == 0 ){
  1184. if ( ((readl(S3C2410_GPGDAT) & (1<<1)) != 0) && (IsWallCharger() == 0) )
  1185. input_report_key(s3c_keypad_qisda->dev, KEY_CHA_STA_USB, 1);
  1186. }
  1187. //}Benq,Andy add for USB cable unplug bugfix
  1188. DPRINTK("s3c_keypad_qisda_probe finished\n");
  1189. /* Qisda, ShiYong Lin, 2009/08/27, Implement for message for AP {*/
  1190. Message_dev = input_dev;
  1191. /* } Qisda, ShiYong Lin, 2009/08/27, Implement for message for AP */
  1192. return 0;
  1193. out:
  1194. input_unregister_device(input_dev);
  1195. kfree(s3c_keypad_qisda);
  1196. return ret;
  1197. }
  1198. static int s3c_keypad_qisda_remove(struct platform_device *pdev)
  1199. {
  1200. struct input_dev *input_dev = platform_get_drvdata(pdev);
  1201. del_timer(&keypad_timer_qisda);
  1202. input_unregister_device(input_dev);
  1203. kfree(pdev->dev.platform_data);
  1204. DPRINTK("Removed");
  1205. return 0;
  1206. }
  1207. #ifdef CONFIG_PM
  1208. static int s3c_keypad_qisda_suspend(struct platform_device *dev, pm_message_t state)
  1209. {
  1210. return 0;
  1211. }
  1212. static int s3c_keypad_qisda_resume(struct platform_device *dev)
  1213. {
  1214. keypad_port_initialize();
  1215. return 0;
  1216. }
  1217. #else
  1218. #define s3c_keypad_suspend_qisda NULL
  1219. #define s3c_keypad_resume_qisda NULL
  1220. #endif /* CONFIG_PM */
  1221. static struct platform_driver s3c_keypad_qisda_driver = {
  1222. .probe = s3c_keypad_qisda_probe,
  1223. .remove = s3c_keypad_qisda_remove,
  1224. .suspend = s3c_keypad_qisda_suspend,
  1225. .resume = s3c_keypad_qisda_resume,
  1226. .driver = {
  1227. .owner = THIS_MODULE,
  1228. .name = DEVICE_NAME,
  1229. },
  1230. };
  1231. static int __init s3c_keypad_qisda_init(void) { return platform_driver_register(&s3c_keypad_qisda_driver); }
  1232. static void __exit s3c_keypad_qisda_exit(void) { platform_driver_unregister(&s3c_keypad_qisda_driver); }
  1233. module_init(s3c_keypad_qisda_init);
  1234. module_exit(s3c_keypad_qisda_exit);
  1235. MODULE_AUTHOR("Tony YC Huang");
  1236. MODULE_LICENSE("GPL");
  1237. MODULE_DESCRIPTION("KeyPad interface for Samsung S3C 2416,Qisda eBook");
  1238. // Qisda Tony 090324, add keypad ]