s3c-hsmmc.c 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611
  1. /*
  2. * linux/drivers/mmc/s3c-hsmmc.c - Samsung S3C24XX HS-MMC driver
  3. *
  4. * $Id: s3c-hsmmc.c,v 1.73 2008/04/13 23:56:19 jsgood Exp $
  5. *
  6. * Copyright (C) 2006 Samsung Electronics, All Rights Reserved.
  7. * by Suh, Seung-Chull<sc.suh@samsung.com>
  8. *
  9. * This driver is made for High Speed MMC interface. This interface
  10. * is adopted and implemented since s3c2443 was made.
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2 as
  14. * published by the Free Software Foundation.
  15. *
  16. * Modified by Ryu,Euiyoul <steven.ryu@samsung.com>
  17. * Modified by Suh, Seung-chull to support s3c6400
  18. *
  19. * Note: s3c-hsmmc.c can be used for 1 channel only at same time.
  20. *
  21. */
  22. #include <linux/module.h>
  23. #include <linux/init.h>
  24. #include <linux/ioport.h>
  25. #include <linux/platform_device.h>
  26. #include <linux/delay.h>
  27. #include <linux/interrupt.h>
  28. #include <linux/highmem.h>
  29. #include <linux/dma-mapping.h>
  30. #include <linux/mmc/host.h>
  31. #include <linux/mmc/protocol.h>
  32. #include <linux/mmc/card.h>
  33. #include <linux/err.h>
  34. #include <linux/clk.h>
  35. #include <linux/proc_fs.h>
  36. #include <linux/irq.h>
  37. #include <linux/major.h> //Qisda, Asaku Chen, 2009/08/20, for wifi power
  38. #include <asm/dma.h>
  39. #include <asm/dma-mapping.h>
  40. #include <asm/io.h>
  41. #include <asm/irq.h>
  42. #include <asm/scatterlist.h>
  43. #include <asm/sizes.h>
  44. #include <asm/mach/mmc.h>
  45. #include <asm/arch/regs-gpio.h>
  46. #include <asm/arch/regs-gpioj.h>
  47. #include <asm/arch/regs-hsmmc.h>
  48. #include <asm/plat-s3c24xx/clock.h>
  49. #include <asm/arch/dma.h>
  50. #include <asm/arch/hsmmc.h>
  51. /*Qisda , wenny cheng , 20091224 , board id info {*/
  52. #include <../include/asm-arm/plat-s3c24xx/common-smdk.h>
  53. /*Qisda , wenny cheng , 20091224 , board id info }*/
  54. /*Trevor add for debug*/
  55. /*#define CONFIG_S3CMMC_DEBUG*/
  56. #ifdef CONFIG_S3CMMC_DEBUG
  57. #define DBG(x...) printk(PFX x)
  58. #else
  59. #define DBG(x...) do { } while (0)
  60. #endif
  61. #include "s3c-hsmmc.h"
  62. #define DRIVER_NAME "s3c-hsmmc"
  63. #define PFX DRIVER_NAME ": "
  64. #define MULTICARD_ON_SINGLEBUS_SUPPORT
  65. #undef MULTICARD_ON_SINGLEBUS_SUPPORT
  66. #define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
  67. #if defined(CONFIG_PM)
  68. struct s3c_hsmmc_host *global_host[3];
  69. #endif
  70. static void s3c_hsmmc_tasklet_finish (unsigned long param);
  71. /*Qisda , wenny cheng , 20091224 , board id info {*/
  72. extern int board_id;
  73. /*Qisda , wenny cheng , 20091224 , board id info }*/
  74. static int inResume = 0; //howard, 2009/12/22, fix resume card-detect
  75. /*Qisda,2009/7/28,Leo SJ Yang {*/
  76. /*Fix: Must plug-in twice ,SD is reconginzed by system*/
  77. /* GEORGE 20090608 update for module on board.*/
  78. static int card_detect = 0;
  79. static int card_detect2 = 2;
  80. /* GEORGE 20090608 update for module on board.*/
  81. /*}Qisda,2009/7/28,Leo SJ Yang*/
  82. /* Qisda , howard hsu, 2010/01/16 , op_mode-delay key event {*/
  83. //extern void op_mode_delay_message_to_ap();
  84. /* } Qisda , howard hsu, 2010/01/16 , op_mode-delay key event */
  85. /* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
  86. // disable it first, wait integration test
  87. #ifdef CONFIG_SD_SW_DEBOUNCE
  88. static int SDCardStatus = 16;
  89. #define SD_INSERTED 0
  90. #define SD_REMOVED 2
  91. #define CHECK_MSEC 50
  92. #define INSERT_MSEC 800
  93. #define REMOVE_MSEC 800
  94. static struct timer_list sd_detect_timer;
  95. static void sdcard_debounce_timer(unsigned long data);
  96. static int ReadSDCardStatus()
  97. {
  98. int SDStatus= 0;
  99. #if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  100. SDStatus = readl(S3C2410_GPFDAT);
  101. SDStatus &= SD_REMOVED; /* GPF1 */
  102. #elif defined(CONFIG_CPU_S3C6410)
  103. SDStatus = readl(S3C_GPNDAT);
  104. SDStatus &= 0x2000; /* GPN13 */
  105. #endif
  106. return SDStatus;
  107. }
  108. static void sdcard_debounce_timer(unsigned long data)
  109. {
  110. static unsigned int StayCount = 0;
  111. static unsigned int MaxCount = 2*INSERT_MSEC/CHECK_MSEC;
  112. static unsigned int MidCount = INSERT_MSEC/CHECK_MSEC;
  113. static unsigned int MinCount = INSERT_MSEC/CHECK_MSEC/2;
  114. static int LastSDCardStatus = 0xF;
  115. int RawStatus = ReadSDCardStatus();
  116. /* stay count in case of resume in progress */
  117. if (inResume == 1)
  118. {
  119. mod_timer(&sd_detect_timer ,jiffies+msecs_to_jiffies(CHECK_MSEC));
  120. return;
  121. }
  122. if ( SDCardStatus == RawStatus )
  123. {
  124. StayCount++;
  125. if (StayCount >= MaxCount)
  126. {
  127. StayCount = 0;
  128. LastSDCardStatus = SDCardStatus;
  129. del_timer(&sd_detect_timer);
  130. }
  131. else if (StayCount == MidCount)
  132. {
  133. struct s3c_hsmmc_host *s3c_host = global_host[0];
  134. struct mmc_host *host = s3c_host->mmc;
  135. if (SDCardStatus == LastSDCardStatus )
  136. {
  137. //StayCount = 0;
  138. //LastSDCardStatus = 0xF;
  139. }
  140. mmc_detect_change(host, 1);
  141. mod_timer(&sd_detect_timer, jiffies+msecs_to_jiffies(CHECK_MSEC));
  142. }
  143. else if ( StayCount==MinCount )
  144. {
  145. /* call detect twice for SD_INSERTED case */
  146. //if (SDCardStatus == LastSDCardStatus )
  147. if (SDCardStatus == SD_INSERTED )
  148. {
  149. struct s3c_hsmmc_host *s3c_host = global_host[0];
  150. struct mmc_host *host = s3c_host->mmc;
  151. mmc_detect_change(host, 1);
  152. }
  153. mod_timer(&sd_detect_timer, jiffies+msecs_to_jiffies(CHECK_MSEC));
  154. }
  155. else
  156. {
  157. mod_timer(&sd_detect_timer, jiffies+msecs_to_jiffies(CHECK_MSEC));
  158. }
  159. }
  160. else
  161. {
  162. SDCardStatus = RawStatus;
  163. if (SDCardStatus==SD_INSERTED) {
  164. MaxCount = 2*INSERT_MSEC/CHECK_MSEC;
  165. MidCount = INSERT_MSEC/CHECK_MSEC;
  166. }
  167. else {
  168. MaxCount = 2*REMOVE_MSEC/CHECK_MSEC;
  169. MidCount = REMOVE_MSEC/CHECK_MSEC;
  170. }
  171. StayCount = 0;
  172. mod_timer(&sd_detect_timer ,jiffies+msecs_to_jiffies(CHECK_MSEC));
  173. }
  174. }
  175. #endif /* CONFIG_SD_SW_DEBOUNCE */
  176. /* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
  177. /*****************************************************************************\
  178. * *
  179. * Low level functions *
  180. * *
  181. \*****************************************************************************/
  182. static struct s3c_hsmmc_cfg s3c_hsmmc_platform = {
  183. .hwport = 0,
  184. .enabled = 0,
  185. .host_caps = (MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE),
  186. .base = NULL,
  187. .highspeed = 0,
  188. /* ctrl for mmc */
  189. .fd_ctrl[0] = {
  190. .ctrl2 = 0xC0004100, /* ctrl2 for mmc */
  191. .ctrl3[0] = 0x80808080, /* ctrl3 for low speed */
  192. .ctrl3[1] = 0x00000080, /* ctrl3 for high speed */
  193. .ctrl4 = 0,
  194. },
  195. /* ctrl for sd */
  196. .fd_ctrl[1] = {
  197. .ctrl2 = 0xC0000100, /* ctrl2 for sd */
  198. .ctrl3[0] = 0, /* ctrl3 for low speed */
  199. .ctrl3[1] = 0, /* ctrl3 for high speed */
  200. .ctrl4 = 0,
  201. },
  202. };
  203. static int s3c_hsmmc_power_switch(int channel, int arg)
  204. {
  205. //printk("\n== s3c_hsmmc_power_switch, channel: %d, power: %d\n", channel, arg);
  206. if(arg){
  207. if(channel == 0){
  208. //Power on
  209. #ifdef CONFIG_QISDA_QD090B00
  210. /*Qisda , wenny cheng , 20091224 , board id info {*/
  211. //if((readl(S3C2416_GPKDAT) & (0x3<<3))){
  212. if(board_id!=QD090B00_S02){
  213. s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_OUTP);
  214. s3c2410_gpio_setpin(S3C2410_GPD14, 1);
  215. }
  216. else{
  217. s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
  218. s3c2410_gpio_setpin(S3C2410_GPG2, 1);
  219. }
  220. /*Qisda , wenny cheng , 20091224 , board id info }*/
  221. #endif
  222. #ifdef CONFIG_QISDA_QD060B00
  223. #ifdef CONFIG_QISDA_BK060B00
  224. s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP);
  225. s3c2410_gpio_setpin(S3C2410_GPH4, 1);
  226. #else
  227. s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
  228. s3c2410_gpio_setpin(S3C2410_GPG2, 1);
  229. #endif
  230. #endif
  231. //Signal
  232. s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2450_GPE5_SD0_CLK);
  233. s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2450_GPE6_SD0_CMD);
  234. s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2450_GPE7_SD0_DAT0);
  235. s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2450_GPE8_SD0_DAT1);
  236. s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2450_GPE9_SD0_DAT2);
  237. s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2450_GPE10_SD0_DAT3);
  238. }
  239. else if(channel == 1){
  240. s3c2410_gpio_cfgpin(S3C2443_GPL8, S3C2450_GPL8_SD1CMD);
  241. s3c2410_gpio_cfgpin(S3C2443_GPL9, S3C2450_GPL9_SD1CLK);
  242. s3c2410_gpio_cfgpin(S3C2443_GPL0, S3C2450_GPL0_SD1DAT0);
  243. s3c2410_gpio_cfgpin(S3C2443_GPL1, S3C2450_GPL1_SD1DAT1);
  244. s3c2410_gpio_cfgpin(S3C2443_GPL2, S3C2450_GPL2_SD1DAT2);
  245. s3c2410_gpio_cfgpin(S3C2443_GPL3, S3C2450_GPL3_SD1DAT3);
  246. }
  247. }
  248. else{
  249. if(channel == 0){
  250. //Power off
  251. #ifdef CONFIG_QISDA_QD090B00
  252. /*Qisda , wenny cheng , 20091224 , board id info {*/
  253. //if((readl(S3C2416_GPKDAT) & (0x3<<3))){
  254. if(board_id!=QD090B00_S02){
  255. s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_OUTP);
  256. s3c2410_gpio_setpin(S3C2410_GPD14, 0);
  257. }
  258. else{
  259. s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
  260. s3c2410_gpio_setpin(S3C2410_GPG2, 0);
  261. }
  262. /*Qisda , wenny cheng , 20091224 , board id info }*/
  263. #endif
  264. #ifdef CONFIG_QISDA_QD060B00
  265. #ifdef CONFIG_QISDA_BK060B00
  266. s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP);
  267. s3c2410_gpio_setpin(S3C2410_GPH4, 0);
  268. #else
  269. s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
  270. s3c2410_gpio_setpin(S3C2410_GPG2, 0);
  271. #endif
  272. #endif
  273. //Signal
  274. s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_INP);
  275. s3c2410_gpio_pullup(S3C2410_GPE5, 1);
  276. s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_INP);
  277. s3c2410_gpio_pullup(S3C2410_GPE6, 1);
  278. s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_INP);
  279. s3c2410_gpio_pullup(S3C2410_GPE7, 1);
  280. s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_INP);
  281. s3c2410_gpio_pullup(S3C2410_GPE8, 1);
  282. s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_INP);
  283. s3c2410_gpio_pullup(S3C2410_GPE9, 1);
  284. s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_INP);
  285. s3c2410_gpio_pullup(S3C2410_GPE10, 1);
  286. }
  287. else if(channel == 1){
  288. s3c2410_gpio_cfgpin(S3C2443_GPL8, S3C2443_GPL8_INP);
  289. s3c2410_gpio_pullup(S3C2443_GPL8, 0);
  290. s3c2410_gpio_cfgpin(S3C2443_GPL9, S3C2443_GPL9_INP);
  291. s3c2410_gpio_pullup(S3C2443_GPL9, 1);
  292. s3c2410_gpio_cfgpin(S3C2443_GPL0, S3C3443_GPL0_INP);
  293. s3c2410_gpio_pullup(S3C2443_GPL0, 0);
  294. s3c2410_gpio_cfgpin(S3C2443_GPL1, S3C2443_GPL1_INP);
  295. s3c2410_gpio_pullup(S3C2443_GPL1, 0);
  296. s3c2410_gpio_cfgpin(S3C2443_GPL2, S3C2443_GPL2_INP);
  297. s3c2410_gpio_pullup(S3C2443_GPL2, 0);
  298. s3c2410_gpio_cfgpin(S3C2443_GPL3, S3C2443_GPL3_INP);
  299. s3c2410_gpio_pullup(S3C2443_GPL3, 0);
  300. }
  301. }
  302. }
  303. /* s3c_hsmmc_get_platdata
  304. *
  305. * get the platform data associated with the given device, or return
  306. * the default if there is none
  307. */
  308. static struct s3c_hsmmc_cfg *s3c_hsmmc_get_platdata (struct device *dev)
  309. {
  310. if (dev->platform_data != NULL)
  311. return (struct s3c_hsmmc_cfg *)dev->platform_data;
  312. return &s3c_hsmmc_platform;
  313. }
  314. static void s3c_hsmmc_reset (struct s3c_hsmmc_host *host, u8 mask)
  315. {
  316. unsigned long timeout;
  317. s3c_hsmmc_writeb(mask, S3C_HSMMC_SWRST);
  318. if (mask & S3C_HSMMC_RESET_ALL)
  319. host->clock = (uint)-1;
  320. /* Wait max 100 ms */
  321. timeout = 100;
  322. /* hw clears the bit when it's done */
  323. while (s3c_hsmmc_readb(S3C_HSMMC_SWRST) & mask) {
  324. if (timeout == 0) {
  325. printk("%s: Reset 0x%x never completed. \n",
  326. mmc_hostname(host->mmc), (int)mask);
  327. return;
  328. }
  329. timeout--;
  330. mdelay(1);
  331. }
  332. }
  333. static void s3c_hsmmc_ios_init (struct s3c_hsmmc_host *host)
  334. {
  335. u32 intmask;
  336. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_ALL);
  337. intmask = S3C_HSMMC_INT_BUS_POWER | S3C_HSMMC_INT_DATA_END_BIT |
  338. S3C_HSMMC_INT_DATA_CRC | S3C_HSMMC_INT_DATA_TIMEOUT | S3C_HSMMC_INT_INDEX |
  339. S3C_HSMMC_INT_END_BIT | S3C_HSMMC_INT_CRC | S3C_HSMMC_INT_TIMEOUT |
  340. S3C_HSMMC_INT_CARD_REMOVE | S3C_HSMMC_INT_CARD_INSERT |
  341. S3C_HSMMC_INT_DATA_AVAIL | S3C_HSMMC_INT_SPACE_AVAIL |
  342. S3C_HSMMC_INT_DATA_END | S3C_HSMMC_INT_RESPONSE;
  343. #ifdef CONFIG_HSMMC_SCATTERGATHER
  344. intmask |= S3C_HSMMC_INT_DMA_END;
  345. #endif
  346. s3c_hsmmc_writel(intmask, S3C_HSMMC_NORINTSTSEN);
  347. s3c_hsmmc_writel(intmask, S3C_HSMMC_NORINTSIGEN);
  348. }
  349. /*****************************************************************************\
  350. * *
  351. * Tasklets *
  352. * *
  353. \*****************************************************************************/
  354. static void s3c_hsmmc_tasklet_card (ulong param)
  355. {
  356. struct s3c_hsmmc_host *host;
  357. unsigned long iflags;
  358. host = (struct s3c_hsmmc_host*)param;
  359. spin_lock_irqsave(&host->lock, iflags);
  360. if (!(s3c_hsmmc_readl(S3C_HSMMC_PRNSTS) & S3C_HSMMC_CARD_PRESENT)) {
  361. if (host->mrq) {
  362. printk(KERN_ERR "%s: Card removed during transfer!\n",
  363. mmc_hostname(host->mmc));
  364. printk(KERN_ERR "%s: Resetting controller.\n",
  365. mmc_hostname(host->mmc));
  366. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_CMD);
  367. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_DATA);
  368. host->mrq->cmd->error = MMC_ERR_FAILED;
  369. /* tasklet_schedule(&host->finish_tasklet); */
  370. s3c_hsmmc_tasklet_finish((unsigned long) host);
  371. }
  372. }
  373. spin_unlock_irqrestore(&host->lock, iflags);
  374. /* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
  375. #ifdef CONFIG_SD_SW_DEBOUNCE
  376. int exist = timer_pending(&sd_detect_timer);
  377. if (exist == 0)
  378. {
  379. sd_detect_timer.expires = jiffies+msecs_to_jiffies(CHECK_MSEC);
  380. add_timer(&sd_detect_timer);
  381. }
  382. #else
  383. mmc_detect_change(host->mmc, msecs_to_jiffies(500));
  384. #endif /* CONFIG_SD_SW_DEBOUNCE */
  385. /* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
  386. }
  387. static void s3c_hsmmc_activate_led(struct s3c_hsmmc_host *host)
  388. {
  389. #if 0
  390. u8 ctrl;
  391. ctrl = s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL);
  392. ctrl |= S3C_HSMMC_CTRL_LED;
  393. s3c_hsmmc_writeb(ctrl, S3C_HSMMC_HOSTCTL);
  394. #endif
  395. #if 0 // for 6400
  396. s3c_gpio_cfgpin(S3C_GPJ13, S3C_GPJ13_SD0LED);
  397. #endif
  398. }
  399. static void s3c_hsmmc_deactivate_led(struct s3c_hsmmc_host *host)
  400. {
  401. #if 0
  402. u8 ctrl;
  403. ctrl = s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL);
  404. ctrl &= ~S3C_HSMMC_CTRL_LED;
  405. s3c_hsmmc_writeb(ctrl, S3C_HSMMC_HOSTCTL);
  406. #endif
  407. #if 0 // for 6400
  408. s3c_gpio_cfgpin(S3C_GPJ13, S3C_GPJ13_INP);
  409. #endif
  410. }
  411. /*****************************************************************************\
  412. * *
  413. * Core functions *
  414. * *
  415. \*****************************************************************************/
  416. #ifdef CONFIG_HSMMC_SCATTERGATHER
  417. static inline uint s3c_hsmmc_build_dma_table (struct s3c_hsmmc_host *host,
  418. struct mmc_data *data)
  419. {
  420. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C2443)
  421. uint i, j = 0, sub_num = 0;
  422. dma_addr_t addr;
  423. uint size, length, end;
  424. int boundary, xor_bit;
  425. struct scatterlist * sg = data->sg;
  426. /* build dma table except last one */
  427. for (i=0; i<(host->sg_len-1); i++) {
  428. addr = sg[i].dma_address;
  429. size = sg[i].length;
  430. DBG("%d - addr: %08x, size: %08x\n", i, addr, size);
  431. for (; (j<CONFIG_S3C_HSMMC_MAX_HW_SEGS*4) && size; j++) {
  432. end = addr + size;
  433. xor_bit = min(7+(2+8+2), fls(addr^end) -1);
  434. DBG("%08x %08x %08x %d\n", addr, size, end, xor_bit);
  435. host->dblk[j].dma_address = addr;
  436. length = (end & ~((1<<xor_bit)-1)) - addr;
  437. boundary = xor_bit - (2+8+2);
  438. DBG("length: %x, boundary: %d\n", length, boundary);
  439. if (length < S3C_HSMMC_MALLOC_SIZE) {
  440. boundary = 0;
  441. if ((addr+length) & (S3C_HSMMC_MALLOC_SIZE-1)) {
  442. void *dest;
  443. DBG("#########error fixing: %08x, %x\n", addr, length);
  444. dest = host->sub_block[sub_num] + S3C_HSMMC_MALLOC_SIZE - length;
  445. if (data->flags & MMC_DATA_WRITE) { /* write */
  446. memcpy(dest, phys_to_virt(addr), length);
  447. }
  448. host->dblk[j].original = phys_to_virt(addr);
  449. host->dblk[j].dma_address = dma_map_single(NULL, dest, length, host->dma_dir);
  450. sub_num++;
  451. }
  452. }
  453. host->dblk[j].length = length;
  454. host->dblk[j].boundary = boundary;
  455. DBG(" %d: %08x, %08x %x\n",
  456. j, addr, length, boundary);
  457. addr += length;
  458. size -= length;
  459. }
  460. }
  461. /* the last one */
  462. host->dblk[j].dma_address = sg[i].dma_address;
  463. host->dblk[j].length = sg[i].length;
  464. host->dblk[j].boundary = 0x7;
  465. return (j+1);
  466. #elif defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  467. uint i;
  468. struct scatterlist * sg = data->sg;
  469. /* build dma table except the last one */
  470. for (i=0; i<(host->sg_len-1); i++) {
  471. host->sdma_descr_tbl[i].dma_address = sg[i].dma_address;
  472. host->sdma_descr_tbl[i].length_attr = (sg[i].length << 16) | (S3C_HSMMC_ADMA_ATTR_ACT_TRAN) |
  473. (S3C_HSMMC_ADMA_ATTR_VALID);
  474. DBG(" ADMA2 descr table[%d] - addr: %08x, size+attr: %08x\n", i, host->sdma_descr_tbl[i].dma_address,
  475. host->sdma_descr_tbl[i].length_attr);
  476. }
  477. /* the last one */
  478. host->sdma_descr_tbl[i].dma_address = sg[i].dma_address;
  479. host->sdma_descr_tbl[i].length_attr = (sg[i].length << 16) | (S3C_HSMMC_ADMA_ATTR_ACT_TRAN) |
  480. (S3C_HSMMC_ADMA_ATTR_END | S3C_HSMMC_ADMA_ATTR_VALID);
  481. DBG(" ADMA2 descr table[%d] - addr: %08x, size+attr: %08x\n", i, host->sdma_descr_tbl[i].dma_address,
  482. host->sdma_descr_tbl[i].length_attr);
  483. return (i);
  484. #endif
  485. }
  486. #endif
  487. static inline void s3c_hsmmc_prepare_data (struct s3c_hsmmc_host *host,
  488. struct mmc_command *cmd)
  489. {
  490. #if defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  491. u8 reg8;
  492. #endif
  493. u32 reg;
  494. struct mmc_data *data = cmd->data;
  495. if (data == NULL) {
  496. reg = s3c_hsmmc_readl(S3C_HSMMC_NORINTSTSEN) | S3C_HSMMC_NIS_CMDCMP;
  497. s3c_hsmmc_writel(reg, S3C_HSMMC_NORINTSTSEN);
  498. return;
  499. }
  500. reg = s3c_hsmmc_readl(S3C_HSMMC_NORINTSTSEN) & ~S3C_HSMMC_NIS_CMDCMP;
  501. s3c_hsmmc_writel(reg, S3C_HSMMC_NORINTSTSEN);
  502. host->dma_dir = (data->flags & MMC_DATA_READ)
  503. ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
  504. #ifdef CONFIG_HSMMC_SCATTERGATHER
  505. host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
  506. host->dma_dir);
  507. reg = s3c_hsmmc_readl(S3C_HSMMC_NORINTSTSEN);
  508. if (host->sg_len == 1) {
  509. reg &= ~S3C_HSMMC_NIS_DMA;
  510. } else {
  511. reg |= S3C_HSMMC_NIS_DMA;
  512. }
  513. s3c_hsmmc_writel(reg, S3C_HSMMC_NORINTSTSEN);
  514. #if defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  515. reg8 = s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL);
  516. reg8 |= S3C_HSMMC_CTRL_ADMA2_32;
  517. s3c_hsmmc_writeb(reg8, S3C_HSMMC_HOSTCTL);
  518. DBG("HOSTCTL(0x28) = 0x%02x\n", s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL));
  519. #endif
  520. DBG("data->flags(direction) = 0x%x\n", data->flags);
  521. DBG("data->blksz: %d\n", data->blksz);
  522. DBG("data->blocks: %d\n", data->blocks);
  523. DBG("data->sg_len: %d\n", data->sg_len);
  524. DBG("data->sg->addr: 0x%x\n", data->sg->dma_address);
  525. DBG("data->sg->length: 0x%x\n", data->sg->length);
  526. host->dma_blk = s3c_hsmmc_build_dma_table(host, data);
  527. host->next_blk = 0;
  528. #else
  529. DBG("data->flags(direction) = 0x%x\n", data->flags);
  530. DBG("data->blksz: %d\n", data->blksz);
  531. DBG("data->blocks: %d\n", data->blocks);
  532. DBG("data->sg_len: %d\n", data->sg_len);
  533. dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
  534. host->dma_dir);
  535. #endif
  536. }
  537. static inline void s3c_hsmmc_set_transfer_mode (struct s3c_hsmmc_host *host,
  538. struct mmc_data *data)
  539. {
  540. u16 mode;
  541. mode = S3C_HSMMC_TRNS_DMA;
  542. if (data->stop)
  543. mode |= S3C_HSMMC_TRNS_ACMD12;
  544. if (data->flags & MMC_DATA_MULTI)
  545. mode |= S3C_HSMMC_TRNS_MULTI | S3C_HSMMC_TRNS_BLK_CNT_EN;
  546. if (data->flags & MMC_DATA_READ)
  547. mode |= S3C_HSMMC_TRNS_READ;
  548. s3c_hsmmc_writew(mode, S3C_HSMMC_TRNMOD);
  549. }
  550. static inline void s3c_hsmmc_send_register (struct s3c_hsmmc_host *host)
  551. {
  552. struct mmc_command *cmd = host->cmd;
  553. struct mmc_data *data = cmd->data;
  554. u32 cmd_val;
  555. if (data) {
  556. #ifdef CONFIG_HSMMC_SCATTERGATHER
  557. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C2443)
  558. struct s3c_hsmmc_dma_blk *dblk;
  559. dblk = &host->dblk[0];
  560. s3c_hsmmc_writew(S3C_HSMMC_MAKE_BLKSZ(dblk->boundary, data->blksz),
  561. S3C_HSMMC_BLKSIZE);
  562. s3c_hsmmc_writel(dblk->dma_address, S3C_HSMMC_SYSAD);
  563. #elif defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  564. s3c_hsmmc_writew(S3C_HSMMC_MAKE_BLKSZ(0x7, data->blksz), S3C_HSMMC_BLKSIZE);
  565. s3c_hsmmc_writel(virt_to_phys(host->sdma_descr_tbl), S3C_HSMMC_ADMASYSADDR);
  566. DBG("S3C_HSMMC_ADMASYSADDR(0x58) = 0x%08x\n", s3c_hsmmc_readl(S3C_HSMMC_ADMASYSADDR));
  567. #endif
  568. #else
  569. s3c_hsmmc_writew(S3C_HSMMC_MAKE_BLKSZ(0x7, data->blksz), S3C_HSMMC_BLKSIZE);
  570. s3c_hsmmc_writel(sg_dma_address(data->sg), S3C_HSMMC_SYSAD);
  571. #endif
  572. s3c_hsmmc_writew(data->blocks, S3C_HSMMC_BLKCNT);
  573. s3c_hsmmc_set_transfer_mode(host, data);
  574. }
  575. s3c_hsmmc_writel(cmd->arg, S3C_HSMMC_ARGUMENT);
  576. cmd_val = (cmd->opcode << 8);
  577. if (cmd_val == (12<<8))
  578. cmd_val |= (3 << 6);
  579. if (cmd->flags & MMC_RSP_136) /* Long RSP */
  580. cmd_val |= S3C_HSMMC_CMD_RESP_LONG;
  581. else if (cmd->flags & MMC_RSP_BUSY) /* R1B */
  582. cmd_val |= S3C_HSMMC_CMD_RESP_SHORT_BUSY;
  583. else if (cmd->flags & MMC_RSP_PRESENT) /* Normal RSP */
  584. cmd_val |= S3C_HSMMC_CMD_RESP_SHORT;
  585. if (cmd->flags & MMC_RSP_OPCODE)
  586. cmd_val |= S3C_HSMMC_CMD_INDEX;
  587. if (cmd->flags & MMC_RSP_CRC)
  588. cmd_val |= S3C_HSMMC_CMD_CRC;
  589. if (data)
  590. cmd_val |= S3C_HSMMC_CMD_DATA;
  591. s3c_hsmmc_writew(cmd_val, S3C_HSMMC_CMDREG);
  592. }
  593. static inline void s3c_hsmmc_send_command (struct s3c_hsmmc_host *host,
  594. struct mmc_command *cmd)
  595. {
  596. u32 mask=1;
  597. ulong timeout;
  598. #if defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  599. while (s3c_hsmmc_readl(S3C_HSMMC_CONTROL4) & mask);
  600. #endif
  601. DBG("Sending cmd=(%d), arg=0x%x\n", cmd->opcode, cmd->arg);
  602. /* Wait max 10 ms */
  603. timeout = 10;
  604. mask = S3C_HSMMC_CMD_INHIBIT;
  605. if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
  606. mask |= S3C_HSMMC_DATA_INHIBIT;
  607. while (s3c_hsmmc_readl(S3C_HSMMC_PRNSTS) & mask) {
  608. printk("########### waiting controller wakeup\n");
  609. if (timeout == 0) {
  610. printk(KERN_ERR "%s: Controller never released "
  611. "inhibit bit(s).\n", mmc_hostname(host->mmc));
  612. cmd->error = MMC_ERR_FAILED;
  613. /* tasklet_schedule(&host->finish_tasklet); */
  614. s3c_hsmmc_tasklet_finish((unsigned long) host);
  615. return;
  616. }
  617. timeout--;
  618. mdelay(1);
  619. }
  620. mod_timer(&host->timer, jiffies + 10 * HZ);
  621. host->cmd = cmd;
  622. s3c_hsmmc_prepare_data(host, cmd);
  623. s3c_hsmmc_send_register(host);
  624. }
  625. static void s3c_hsmmc_finish_data (struct s3c_hsmmc_host *host)
  626. {
  627. struct mmc_data *data;
  628. u16 blocks;
  629. //BUG_ON(!host->data);
  630. if(!host->data) return;
  631. data = host->data;
  632. host->data = NULL;
  633. dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
  634. (data->flags & MMC_DATA_READ)
  635. ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
  636. /*
  637. * Controller doesn't count down when in single block mode.
  638. */
  639. if ((data->blocks == 1) && (data->error == MMC_ERR_NONE))
  640. blocks = 0;
  641. else {
  642. blocks = s3c_hsmmc_readw(S3C_HSMMC_BLKCNT);
  643. }
  644. data->bytes_xfered = data->blksz * (data->blocks - blocks);
  645. if ((data->error == MMC_ERR_NONE) && blocks) {
  646. printk(KERN_ERR "%s: Controller signalled completion even "
  647. "though there were blocks left. : %d\n",
  648. mmc_hostname(host->mmc), blocks);
  649. data->error = MMC_ERR_FAILED;
  650. }
  651. DBG("data->flags(direction) FINISHED = %d\n", data->flags);
  652. DBG("data->blksz FINISHED = %d\n", data->blksz);
  653. DBG("data->blocks FINISHED = %d\n", data->blocks);
  654. DBG("Not FINISHED blocks = %d\n", blocks);
  655. DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered);
  656. DBG("\n");
  657. /* tasklet_schedule(&host->finish_tasklet); */
  658. s3c_hsmmc_tasklet_finish((unsigned long) host);
  659. }
  660. static void s3c_hsmmc_finish_command (struct s3c_hsmmc_host *host)
  661. {
  662. int i;
  663. //BUG_ON(host->cmd == NULL);
  664. if(!host->cmd) return;
  665. if (host->cmd->flags & MMC_RSP_PRESENT) {
  666. if (host->cmd->flags & MMC_RSP_136) {
  667. /* CRC is stripped so we need to do some shifting. */
  668. for (i=0; i<4; i++) {
  669. host->cmd->resp[i] = s3c_hsmmc_readl(S3C_HSMMC_RSPREG0+ (3-i)*4) << 8;
  670. if (i != 3)
  671. host->cmd->resp[i] |= s3c_hsmmc_readb(S3C_HSMMC_RSPREG0 + (3-i)*4-1);
  672. DBG("cmd (%d) resp[%d] = 0x%x\n", host->cmd->opcode, i, host->cmd->resp[i]);
  673. }
  674. } else {
  675. host->cmd->resp[0] = s3c_hsmmc_readl(S3C_HSMMC_RSPREG0);
  676. DBG("cmd (%d) resp[%d] = 0x%x\n", host->cmd->opcode, 0, host->cmd->resp[0]);
  677. }
  678. }
  679. host->cmd->error = MMC_ERR_NONE;
  680. DBG("Ending cmd (%d)\n", host->cmd->opcode);
  681. DBG("\n");
  682. if (host->cmd->data)
  683. host->data = host->cmd->data;
  684. else
  685. /* tasklet_schedule(&host->finish_tasklet); */
  686. s3c_hsmmc_tasklet_finish((unsigned long) host);
  687. host->cmd = NULL;
  688. }
  689. static void s3c_hsmmc_tasklet_finish (unsigned long param)
  690. {
  691. struct s3c_hsmmc_host *host;
  692. unsigned long iflags;
  693. struct mmc_request *mrq;
  694. host = (struct s3c_hsmmc_host*)param;
  695. //BUG_ON(!host->mrq);
  696. if(!host->mrq) return;
  697. spin_lock_irqsave(&host->lock, iflags);
  698. del_timer(&host->timer);
  699. mrq = host->mrq;
  700. udelay(10);
  701. /*
  702. * The controller needs a reset of internal state machines
  703. * upon error conditions.
  704. */
  705. if ((mrq->cmd->error != MMC_ERR_NONE) ||
  706. (mrq->data && (mrq->data->error != MMC_ERR_NONE)) ) {
  707. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_CMD);
  708. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_DATA);
  709. }
  710. host->mrq = NULL;
  711. host->cmd = NULL;
  712. host->data = NULL;
  713. s3c_hsmmc_deactivate_led(host);
  714. mmiowb();
  715. spin_unlock_irqrestore(&host->lock, iflags);
  716. mmc_request_done(host->mmc, mrq);
  717. }
  718. /*****************************************************************************
  719. * *
  720. * Interrupt handling *
  721. * *
  722. *****************************************************************************/
  723. static void s3c_hsmmc_cmd_irq (struct s3c_hsmmc_host *host, u32 intmask)
  724. {
  725. if (!host->cmd) {
  726. printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
  727. "though no command operation was in progress.\n",
  728. mmc_hostname(host->mmc), (unsigned)intmask);
  729. return;
  730. }
  731. if (intmask & S3C_HSMMC_INT_TIMEOUT)
  732. host->cmd->error = MMC_ERR_TIMEOUT;
  733. else if (intmask & S3C_HSMMC_INT_CRC)
  734. host->cmd->error = MMC_ERR_BADCRC;
  735. else if (intmask & (S3C_HSMMC_INT_END_BIT | S3C_HSMMC_INT_INDEX))
  736. host->cmd->error = MMC_ERR_FAILED;
  737. else
  738. host->cmd->error = MMC_ERR_INVALID;
  739. /* tasklet_schedule(&host->finish_tasklet); */
  740. s3c_hsmmc_tasklet_finish((unsigned long) host);
  741. }
  742. static void s3c_hsmmc_data_irq (struct s3c_hsmmc_host *host, u32 intmask)
  743. {
  744. if (!host->data) {
  745. /*
  746. * A data end interrupt is sent together with the response
  747. * for the stop command.
  748. */
  749. if (intmask & S3C_HSMMC_INT_DATA_END)
  750. return;
  751. printk(KERN_ERR "%s: Got data interrupt even though no "
  752. "data operation was in progress.\n",
  753. mmc_hostname(host->mmc));
  754. return;
  755. }
  756. if (intmask & S3C_HSMMC_INT_DATA_TIMEOUT)
  757. host->data->error = MMC_ERR_TIMEOUT;
  758. else if (intmask & S3C_HSMMC_INT_DATA_CRC)
  759. host->data->error = MMC_ERR_BADCRC;
  760. else if (intmask & S3C_HSMMC_INT_DATA_END_BIT)
  761. host->data->error = MMC_ERR_FAILED;
  762. if (host->data->error != MMC_ERR_NONE)
  763. s3c_hsmmc_finish_data(host);
  764. }
  765. /*****************************************************************************\
  766. * *
  767. * Interrupt handling *
  768. * *
  769. \*****************************************************************************/
  770. /*
  771. * ISR for SDI Interface IRQ
  772. * Communication between driver and ISR works as follows:
  773. * host->mrq points to current request
  774. * host->complete_what tells the ISR when the request is considered done
  775. *
  776. * 1) Driver sets up host->mrq and host->complete_what
  777. * 2) Driver prepares the transfer
  778. * 3) Driver enables interrupts
  779. * 4) Driver starts transfer
  780. * 5) Driver waits for host->complete_rquest
  781. * 6) ISR checks for request status (errors and success)
  782. * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error
  783. * 7) ISR completes host->complete_request
  784. * 8) ISR disables interrupts
  785. * 9) Driver wakes up and takes care of the request
  786. */
  787. static irqreturn_t s3c_hsmmc_irq (int irq, void *dev_id)
  788. {
  789. irqreturn_t result = 0;
  790. struct s3c_hsmmc_host *host = dev_id;
  791. struct mmc_request *mrq;
  792. u32 intsts;
  793. #ifdef CONFIG_HSMMC_S3C_IRQ_WORKAROUND
  794. uint i, org_irq_sts;
  795. #endif
  796. spin_lock(&host->lock);
  797. mrq = host->mrq;
  798. intsts = s3c_hsmmc_readw(S3C_HSMMC_NORINTSTS);
  799. /* Sometimes, hsmmc does not update its status bit immediately
  800. * when it generates irqs. by scsuh.
  801. */
  802. #ifdef CONFIG_HSMMC_S3C_IRQ_WORKAROUND
  803. for (i=0; i<0x1000; i++) {
  804. if ((intsts = s3c_hsmmc_readw(S3C_HSMMC_NORINTSTS)))
  805. break;
  806. }
  807. #endif
  808. if (unlikely(!intsts)) {
  809. result = IRQ_NONE;
  810. goto out;
  811. }
  812. intsts = s3c_hsmmc_readl(S3C_HSMMC_NORINTSTS);
  813. #ifdef CONFIG_HSMMC_S3C_IRQ_WORKAROUND
  814. org_irq_sts = intsts;
  815. #endif
  816. DBG("Got interrupt = 0x%08x\n", intsts);
  817. if (unlikely(intsts & S3C_HSMMC_INT_CARD_CHANGE)) {
  818. u32 reg16;
  819. if (intsts & S3C_HSMMC_INT_CARD_INSERT)
  820. printk(PFX "card inserted.\n");
  821. else if (intsts & S3C_HSMMC_INT_CARD_REMOVE)
  822. printk(PFX "card removed.\n");
  823. reg16 = s3c_hsmmc_readw(S3C_HSMMC_NORINTSTSEN);
  824. s3c_hsmmc_writew(reg16 & ~S3C_HSMMC_INT_CARD_CHANGE,
  825. S3C_HSMMC_NORINTSTSEN);
  826. s3c_hsmmc_writew(S3C_HSMMC_INT_CARD_CHANGE, S3C_HSMMC_NORINTSTS);
  827. s3c_hsmmc_writew(reg16, S3C_HSMMC_NORINTSTSEN);
  828. intsts &= ~S3C_HSMMC_INT_CARD_CHANGE;
  829. tasklet_schedule(&host->card_tasklet);
  830. goto insert;
  831. }
  832. if (likely(!(intsts & S3C_HSMMC_NIS_ERR))) {
  833. s3c_hsmmc_writel(intsts, S3C_HSMMC_NORINTSTS);
  834. if (intsts & S3C_HSMMC_NIS_CMDCMP) {
  835. DBG("command done\n");
  836. s3c_hsmmc_finish_command(host);
  837. }
  838. if (intsts & S3C_HSMMC_NIS_TRSCMP) {
  839. DBG("transfer done\n\n");
  840. s3c_hsmmc_finish_command(host);
  841. s3c_hsmmc_finish_data(host);
  842. intsts &= ~S3C_HSMMC_NIS_DMA;
  843. }
  844. #ifdef CONFIG_HSMMC_SCATTERGATHER
  845. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C2443)
  846. if (intsts & S3C_HSMMC_NIS_DMA) {
  847. struct s3c_hsmmc_dma_blk *dblk;
  848. dblk = &host->dblk[host->next_blk];
  849. if (dblk->original) {
  850. /* on read */
  851. if (host->dma_dir == DMA_FROM_DEVICE) {
  852. memcpy(dblk->original, phys_to_virt(dblk->dma_address), dblk->length);
  853. }
  854. dma_unmap_single(NULL, dblk->dma_address, dblk->length, host->dma_dir);
  855. dblk->original = 0;
  856. }
  857. host->next_blk++;
  858. dblk = &host->dblk[host->next_blk];
  859. if (host->next_blk == (host->dma_blk-1)) {
  860. u32 reg;
  861. reg = s3c_hsmmc_readl(S3C_HSMMC_NORINTSTSEN);
  862. reg &= ~S3C_HSMMC_NIS_DMA;
  863. s3c_hsmmc_writel(reg, S3C_HSMMC_NORINTSTSEN);
  864. }
  865. /* We do not handle DMA boundaries, so set it to max (512 KiB) */
  866. s3c_hsmmc_writew((dblk->boundary<<12 | 0x200), S3C_HSMMC_BLKSIZE);
  867. s3c_hsmmc_writel(dblk->dma_address, S3C_HSMMC_SYSAD);
  868. }
  869. #endif
  870. #endif
  871. } else {
  872. DBG("command FAIL : found bad irq [0x%8x]\n", intsts);
  873. DBG("\n");
  874. if (intsts & S3C_HSMMC_INT_CMD_MASK) {
  875. s3c_hsmmc_writel(intsts & S3C_HSMMC_INT_CMD_MASK, S3C_HSMMC_NORINTSTS);
  876. s3c_hsmmc_cmd_irq(host, intsts & S3C_HSMMC_INT_CMD_MASK);
  877. }
  878. if (intsts & S3C_HSMMC_INT_DATA_MASK) {
  879. s3c_hsmmc_writel(intsts & S3C_HSMMC_INT_DATA_MASK, S3C_HSMMC_NORINTSTS);
  880. s3c_hsmmc_finish_command(host);
  881. s3c_hsmmc_data_irq(host, intsts & S3C_HSMMC_INT_DATA_MASK);
  882. }
  883. intsts &= ~(S3C_HSMMC_INT_CMD_MASK | S3C_HSMMC_INT_DATA_MASK);
  884. }
  885. /* XXX: fix later by scsuh */
  886. #if 0
  887. if (intsts & S3C_HSMMC_INT_BUS_POWER) {
  888. printk(KERN_ERR "%s: Card is consuming too much power!\n",
  889. mmc_hostname(host->mmc));
  890. s3c_hsmmc_writel(S3C_HSMMC_INT_BUS_POWER, S3C_HSMMC_NORINTSTS);
  891. }
  892. intsts &= S3C_HSMMC_INT_BUS_POWER;
  893. if (intsts) {
  894. printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
  895. mmc_hostname(host->mmc), intsts);
  896. s3c_hsmmc_writel(intsts, S3C_HSMMC_NORINTSTS);
  897. }
  898. #endif
  899. #ifdef CONFIG_HSMMC_S3C_IRQ_WORKAROUND
  900. for (i=0; i<0x1000; i++) {
  901. if (org_irq_sts != s3c_hsmmc_readl(S3C_HSMMC_NORINTSTS))
  902. break;
  903. }
  904. #endif
  905. insert:
  906. result = IRQ_HANDLED;
  907. mmiowb();
  908. out:
  909. spin_unlock(&host->lock);
  910. return result;
  911. }
  912. #include <linux/cyio.h>
  913. int Cyio_PushEvent(char eventId, char unique);
  914. static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
  915. {
  916. struct s3c_hsmmc_host *host = dev_id;
  917. int ext_CD_int = 0;
  918. #if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  919. ext_CD_int = readl(S3C2410_GPFDAT);
  920. ext_CD_int &= 0x2; /* GPF1 */
  921. #elif defined(CONFIG_CPU_S3C6410)
  922. ext_CD_int = readl(S3C_GPNDAT);
  923. ext_CD_int &= 0x2000; /* GPN13 */
  924. #endif
  925. //printk("\ns3c_hsmmc_irq_cd, ext_CD_int: %d, card_detect: %d, card_detect2: %d\n", ext_CD_int, card_detect, card_detect2);
  926. if(ext_CD_int && card_detect) {
  927. printk("s3c-hsmmc channel-0(EXT): card removed.\n");
  928. /*Qisda Qube for sd card detect20091124*/
  929. //set_irq_type(host->irq_cd, IRQT_FALLING);
  930. set_irq_type(host->irq_cd, IRQT_LOW);
  931. /*Qisda Qube for sd card detect20091124*/
  932. card_detect = 0;
  933. //Qisda, Asaku Chen, 2009/11/03, SD power off
  934. s3c_hsmmc_power_switch(0, 0);
  935. card_detect2 = 2;
  936. /* Send CyIO event */
  937. Cyio_PushEvent(CYEVENT_SD_OUT, 1);
  938. }
  939. else if(!ext_CD_int && !card_detect) {
  940. printk("s3c-hsmmc channel-0(EXT): card inserted.\n");
  941. /*Qisda Qube for sd card detect20091124*/
  942. //set_irq_type(host->irq_cd, IRQT_RISING);
  943. set_irq_type(host->irq_cd, IRQT_HIGH);
  944. /*Qisda Qube for sd card detect20091124*/
  945. //Qisda, Asaku Chen, 2009/11/03, SD power on
  946. if (inResume!=1)//howard, 2009/12/22, fix resume card-detect
  947. {
  948. card_detect = 1;
  949. s3c_hsmmc_power_switch(0, 1);
  950. }
  951. if(card_detect2 == 3){
  952. printk("resume host first\n");
  953. s3c_hsmmc_ios_init(host);
  954. mmc_resume_host(host->mmc);
  955. card_detect2 = 2;
  956. }
  957. /* Send CyIO event */
  958. Cyio_PushEvent(CYEVENT_SD_IN, 1);
  959. }
  960. //Qisda, Asaku Chen, 2009/11/03 {
  961. else if(card_detect2 == 1){
  962. printk("SD power on\n");
  963. s3c_hsmmc_power_switch(0, 1);
  964. card_detect2 = 2;
  965. }
  966. else if(card_detect2 == 0){
  967. printk("SD power off\n");
  968. s3c_hsmmc_power_switch(0, 0);
  969. card_detect2 = -1;
  970. }
  971. //Qisda, Asaku Chen, 2009/11/03 }
  972. else
  973. return IRQ_HANDLED;
  974. tasklet_schedule(&host->card_tasklet);
  975. mmiowb();
  976. spin_unlock(&host->lock);
  977. return IRQ_HANDLED;
  978. }
  979. static void s3c_hsmmc_check_status (unsigned long data)
  980. {
  981. struct s3c_hsmmc_host *host = (struct s3c_hsmmc_host *)data;
  982. s3c_hsmmc_irq(0, host);
  983. }
  984. static void s3c_hsmmc_request (struct mmc_host *mmc, struct mmc_request *mrq)
  985. {
  986. struct s3c_hsmmc_host *host = mmc_priv(mmc);
  987. unsigned long flags;
  988. DBG("hsmmc(%d) request: [CMD] opcode:%d arg:0x%08x flags:0x%02x retries:%u\n",
  989. host->plat_data->hwport,
  990. mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags, mrq->cmd->retries);
  991. spin_lock_irqsave(&host->lock, flags);
  992. WARN_ON(host->mrq != NULL);
  993. s3c_hsmmc_activate_led(host);
  994. host->mrq = mrq;
  995. if ((s3c_hsmmc_readl(S3C_HSMMC_PRNSTS) & S3C_HSMMC_CARD_PRESENT) || card_detect) {
  996. s3c_hsmmc_send_command(host, mrq->cmd);
  997. } else {
  998. host->mrq->cmd->error = MMC_ERR_TIMEOUT;
  999. /* tasklet_schedule(&host->finish_tasklet); */
  1000. s3c_hsmmc_tasklet_finish((unsigned long) host);
  1001. }
  1002. mmiowb();
  1003. spin_unlock_irqrestore(&host->lock, flags);
  1004. }
  1005. /* return 0: OK
  1006. * return -1: error
  1007. */
  1008. static int s3c_set_bus_width (struct s3c_hsmmc_host *host, uint width)
  1009. {
  1010. u8 reg;
  1011. reg = s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL);
  1012. switch (width) {
  1013. case MMC_BUS_WIDTH_1:
  1014. reg &= ~(S3C_HSMMC_CTRL_4BIT | S3C_HSMMC_CTRL_8BIT);
  1015. DBG("bus width: 1 bit\n");
  1016. break;
  1017. case MMC_BUS_WIDTH_4:
  1018. DBG("bus width: 4 bit\n");
  1019. reg &= ~(S3C_HSMMC_CTRL_8BIT);
  1020. reg |= S3C_HSMMC_CTRL_4BIT;
  1021. break;
  1022. default:
  1023. DBG("bus width: Error\n");
  1024. return -1;
  1025. }
  1026. s3c_hsmmc_writeb(reg, S3C_HSMMC_HOSTCTL);
  1027. DBG("HOSTCTL(0x28) = 0x%02x\n", s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL));
  1028. return 0;
  1029. }
  1030. static void s3c_hsmmc_set_clock (struct s3c_hsmmc_host *host, ulong clock)
  1031. {
  1032. struct s3c_hsmmc_cfg *cfg = host->plat_data;
  1033. //int cardtype = host->mmc->mode;
  1034. int cardtype = MMC_MODE_MMC;
  1035. u32 val = 0, tmp_clk = 0, clk_src = 0, i, j;
  1036. u16 div = (u16)-1;
  1037. ulong timeout;
  1038. u8 ctrl;
  1039. /* if we already set, just out. */
  1040. if (clock == host->clock) {
  1041. printk("%p:host->clock0 : %d Hz\n", host->base, host->clock);
  1042. return;
  1043. }
  1044. /* before setting clock, clkcon must be disabled. */
  1045. s3c_hsmmc_writew(0, S3C_HSMMC_CLKCON);
  1046. s3c_hsmmc_writeb(S3C_HSMMC_TIMEOUT_MAX, S3C_HSMMC_TIMEOUTCON);
  1047. /* change the edge type according to frequency */
  1048. ctrl = s3c_hsmmc_readb(S3C_HSMMC_HOSTCTL);
  1049. if (cfg->highspeed)
  1050. ctrl |= S3C_HSMMC_CTRL_HIGHSPEED;
  1051. else
  1052. ctrl &= ~S3C_HSMMC_CTRL_HIGHSPEED;
  1053. s3c_hsmmc_writeb(ctrl, S3C_HSMMC_HOSTCTL);
  1054. if (clock == 0) {
  1055. DBG(" In case of 0 Hz of clock, I'm afraid DO NOTHING ..\n");
  1056. return;
  1057. }
  1058. /* calculate optimal clock. by scsuh */
  1059. DBG("Requested clock is %ld Hz\n", clock);
  1060. for (i=0; i<NUM_OF_HSMMC_CLKSOURCES; i++) {
  1061. if ((tmp_clk = clk_get_rate(host->clk[i])) <= clock) {
  1062. if (tmp_clk >= val) {
  1063. val = tmp_clk;
  1064. div = 0;
  1065. clk_src = i+1;
  1066. }
  1067. }
  1068. for (j=0x1; j<=0x80; j <<= 1) {
  1069. tmp_clk = clk_get_rate(host->clk[i]) / (j<<1);
  1070. if ((val < tmp_clk) && (tmp_clk <= clock)) {
  1071. val = tmp_clk;
  1072. div = j;
  1073. clk_src = i+1;
  1074. break;
  1075. }
  1076. }
  1077. DBG(" tmp_val[%d]: %d\n", i, val);
  1078. }
  1079. DBG("Optimal clock : %d Hz, div: 0x%x, SelBaseclk_src: %d\n", val, div, clk_src);
  1080. /* CONTROL2 */
  1081. s3c_hsmmc_writel(cfg->fd_ctrl[cardtype].ctrl2 | (clk_src << 4), S3C_HSMMC_CONTROL2);
  1082. /* CONTROL3 */
  1083. if (clock > 25000000)
  1084. s3c_hsmmc_writel(cfg->fd_ctrl[cardtype].ctrl3[SPEED_HIGH], S3C_HSMMC_CONTROL3);
  1085. else
  1086. s3c_hsmmc_writel(cfg->fd_ctrl[cardtype].ctrl3[SPEED_NORMAL], S3C_HSMMC_CONTROL3);
  1087. #if defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  1088. s3c_hsmmc_writel(cfg->fd_ctrl[cardtype].ctrl4 << 16, S3C_HSMMC_CONTROL4);
  1089. #endif
  1090. s3c_hsmmc_writew(((div << 8) | S3C_HSMMC_CLOCK_INT_EN), S3C_HSMMC_CLKCON);
  1091. timeout = 10;
  1092. while (!((val = s3c_hsmmc_readw(S3C_HSMMC_CLKCON))
  1093. & S3C_HSMMC_CLOCK_INT_STABLE)) {
  1094. if (!timeout) {
  1095. printk("Error in INTERNAL clock stabilization: %08x\n", val);
  1096. return;
  1097. }
  1098. timeout--;
  1099. mdelay(1);
  1100. }
  1101. s3c_hsmmc_writew(val | S3C_HSMMC_CLOCK_CARD_EN, S3C_HSMMC_CLKCON);
  1102. timeout = 10;
  1103. while (!((val = s3c_hsmmc_readw(S3C_HSMMC_CLKCON))
  1104. & S3C_HSMMC_CLOCK_EXT_STABLE)) {
  1105. if (!timeout) {
  1106. printk("Error in EXTERNAL clock stabilization: %08x\n", val);
  1107. return;
  1108. }
  1109. timeout--;
  1110. mdelay(1);
  1111. }
  1112. }
  1113. static void s3c_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
  1114. {
  1115. struct s3c_hsmmc_host *host = mmc_priv(mmc);
  1116. unsigned long iflags;
  1117. spin_lock_irqsave(&host->lock, iflags);
  1118. /*
  1119. * Reset the chip on each power off.
  1120. * Should clear out any weird states.
  1121. */
  1122. if (ios->power_mode == MMC_POWER_OFF) {
  1123. s3c_hsmmc_writew(0, S3C_HSMMC_NORINTSIGEN);
  1124. s3c_hsmmc_ios_init(host);
  1125. //Qisda, Asaku Chen, 2009/11/03 {
  1126. if(host->plat_data->hwport==0){
  1127. //printk("== s3c_hsmmc_set_ios: %d, MMC_POWER_OFF\n", host->plat_data->hwport);
  1128. s3c_hsmmc_power_switch(0, 0);
  1129. }
  1130. }
  1131. else{
  1132. //Enable SD power
  1133. if((host->plat_data->hwport==0) && (card_detect2 > 0)){
  1134. //printk("== s3c_hsmmc_set_ios: %d, MMC_POWER_ON\n", host->plat_data->hwport);
  1135. s3c_hsmmc_power_switch(0, 1);
  1136. }
  1137. }
  1138. if((ios->power_mode == MMC_POWER_OFF) && (host->plat_data->hwport==0)){
  1139. //do nothing
  1140. }else{
  1141. if (host->plat_data->enabled)
  1142. hsmmc_set_gpio(host->plat_data->hwport, host->plat_data->bus_width);
  1143. }
  1144. if((host->plat_data->hwport == 1) && (ios->clock > 26000000)){
  1145. ios->clock = 26000000;
  1146. }
  1147. DBG("ios->clock: %d Hz\n", ios->clock);
  1148. s3c_hsmmc_set_clock(host, ios->clock);
  1149. DBG("ios->bus_width: %d\n", ios->bus_width);
  1150. s3c_set_bus_width(host, ios->bus_width);
  1151. DBG("S3C_HSMMC_CONTROL2(0x80) = 0x%08x\n", s3c_hsmmc_readl(S3C_HSMMC_CONTROL2));
  1152. DBG("S3C_HSMMC_CONTROL3(0x84) = 0x%08x\n", s3c_hsmmc_readl(S3C_HSMMC_CONTROL3));
  1153. DBG("S3C_HSMMC_CLKCON (0x2c) = 0x%04x\n", s3c_hsmmc_readw(S3C_HSMMC_CLKCON));
  1154. if (ios->power_mode == MMC_POWER_OFF)
  1155. s3c_hsmmc_writeb(S3C_HSMMC_POWER_OFF, S3C_HSMMC_PWRCON);
  1156. else
  1157. s3c_hsmmc_writeb(S3C_HSMMC_POWER_ON_ALL, S3C_HSMMC_PWRCON);
  1158. udelay(1000);
  1159. spin_unlock_irqrestore(&host->lock, iflags);
  1160. }
  1161. static struct mmc_host_ops s3c_hsmmc_ops = {
  1162. .request = s3c_hsmmc_request,
  1163. .set_ios = s3c_hsmmc_set_ios,
  1164. };
  1165. //Qisda, Asaku Chen, 2009/08/20, for wifi power {
  1166. static int s3c_wifi_open(struct inode *inode, struct file *file)
  1167. {
  1168. return 0;
  1169. }
  1170. #define S3C_WIFI_POWER_ON 1
  1171. #define S3C_WIFI_POWER_OFF 2
  1172. #define S3C_READ_TILT_STATUS 3
  1173. #define S3C_READ_GPIO_VALUE 4
  1174. #define S3C_SET_GPIO_ADDR 5
  1175. #define S3C_WRITE_GPIO_VALUE 6
  1176. #define S3C_READ_HW_VERSION 7
  1177. #define S3C_TCON_ERASE 10
  1178. #define S3C_TCON_ID 11
  1179. #define S3C_TCON_READ 12
  1180. #define S3C_TCON_BYTE_COUNT 13
  1181. #define S3C_TCON_WRITE 14
  1182. #define MMC_DEVICE_POWER_STATE 20
  1183. #define S3C_BT_POWER_ON 1
  1184. #define S3C_BT_POWER_OFF 2
  1185. static unsigned char s3c_tcon_read_byte(void)
  1186. {
  1187. /*
  1188. Unsigned char Get data () //Receive a byte from Serial flash
  1189. {
  1190. unsigned char k, temdata =0, i;
  1191. for ( k = 0; k++; k< 8)
  1192. {
  1193. if ( SO == 1 )
  1194. {
  1195. i = (0x80 >> k);
  1196. temdata = (temdata || i);
  1197. }
  1198. SCLK = 1;
  1199. SCLK = 0;
  1200. }
  1201. return (temdata);
  1202. }
  1203. */
  1204. unsigned char k, temdata =0, i=0;
  1205. u32 read_pin;
  1206. for(k=0; k<8; k++){
  1207. read_pin = (readl(S3C2410_GPEDAT) & (1<<11));
  1208. //printk(" [%d]: 0x%X 0x%X\n", k, read_pin, readl(S3C2410_GPEDAT));
  1209. if(read_pin){
  1210. i = (0x80 >> k);
  1211. temdata = (temdata | i);
  1212. }
  1213. s3c2410_gpio_setpin(S3C2410_GPE13, 1);
  1214. udelay(2);
  1215. s3c2410_gpio_setpin(S3C2410_GPE13, 0);
  1216. udelay(2);
  1217. }
  1218. //printk("s3c_tcon_read_byte: 0x%2X\n", temdata);
  1219. return (temdata);
  1220. }
  1221. static void s3c_tcon_write_byte(char w_data)
  1222. {
  1223. /*
  1224. Send data (unsigned char indata) // Send 1 byte data to Serial flash
  1225. {
  1226. unsigned char k;
  1227. for ( k = 0; k++; k< 8)
  1228. {
  1229. if( (indata & 0x80) == 0x80)
  1230. SI = 1;
  1231. else
  1232. SI = 0;
  1233. SCLK = 1;
  1234. SCLK = 0;
  1235. indata = (indata << 1);
  1236. }
  1237. }
  1238. */
  1239. unsigned char k;
  1240. //printk("s3c_tcon_write_byte: 0x%2X\n", w_data);
  1241. for(k=0; k<8; k++){
  1242. if((w_data & 0x80))
  1243. s3c2410_gpio_setpin(S3C2410_GPE12, 1);
  1244. else
  1245. s3c2410_gpio_setpin(S3C2410_GPE12, 0);
  1246. s3c2410_gpio_setpin(S3C2410_GPE13, 1);
  1247. udelay(2);
  1248. s3c2410_gpio_setpin(S3C2410_GPE13, 0);
  1249. udelay(2);
  1250. w_data = (w_data << 1);
  1251. }
  1252. }
  1253. extern void mmc_rescan(struct work_struct *work);
  1254. static int s3c_wifi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1255. {
  1256. static char s3c_power_off = 0;
  1257. static unsigned int gpio_addr = 0;
  1258. static unsigned int tcon_byte_count;
  1259. static unsigned int tcon_address;
  1260. unsigned char tcon_buffer[128];
  1261. unsigned char r_data;
  1262. int ret, i;
  1263. u32 read_pin;
  1264. switch(cmd){
  1265. #ifdef CONFIG_QISDA_BK060B00
  1266. case S3C_WIFI_POWER_ON:
  1267. printk("BCM4329-WIFI_BT_POWER_ON\n");
  1268. //TCON Flash disable, and select WiFi
  1269. s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
  1270. s3c2410_gpio_setpin(S3C2410_GPH6, 0);
  1271. //bcm4329 module power on control
  1272. //GPK7, WIFI PA 3.3V
  1273. writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
  1274. writel((readl(S3C2416_GPKDAT) | (1<<7)), S3C2416_GPKDAT);
  1275. //GPK6, PA 1.8V
  1276. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1277. writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
  1278. //GPK5, PA 3.3V
  1279. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1280. writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
  1281. //GPK9 (green light), pull high
  1282. writel(((readl(S3C2416_GPKCON) & ~(1<<19)) | (1<<18)), S3C2416_GPKCON);
  1283. writel((readl(S3C2416_GPKDAT) | (1<<9)), S3C2416_GPKDAT);
  1284. //WIFI_BT_EN (GPD11) pull high
  1285. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
  1286. s3c2410_gpio_setpin(S3C2410_GPD11, 0);
  1287. //writel(((readl(S3C2416_GPGCON) & ~(1<<9)) | (1<<8)), S3C2416_GPGCON);
  1288. //writel((readl(S3C2416_GPGDAT) & ~(1<<4)), S3C2416_GPGDAT);
  1289. mdelay(1);
  1290. s3c2410_gpio_setpin(S3C2410_GPD11, 1);
  1291. //writel((readl(S3C2416_GPGDAT) | (1<<4)), S3C2416_GPGDAT);
  1292. mdelay(20);
  1293. //EXT_N_WIFI_RST (GPD8) pull high
  1294. s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
  1295. s3c2410_gpio_setpin(S3C2410_GPD8, 0);
  1296. //writel(((readl(S3C2416_GPDCON) & ~(1<<17)) | (1<<16)), S3C2416_GPDCON);
  1297. //writel((readl(S3C2416_GPDDAT) & ~(1<<8)), S3C2416_GPDDAT);
  1298. mdelay(1);
  1299. s3c2410_gpio_setpin(S3C2410_GPD8, 1);
  1300. //writel((readl(S3C2416_GPDDAT) | (1<<8)), S3C2416_GPDDAT);
  1301. mdelay(20);
  1302. //EXT_N_BT_RST (GPA2) pull high
  1303. s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
  1304. s3c2410_gpio_setpin(S3C2410_GPA2, 0);
  1305. mdelay(1);
  1306. s3c2410_gpio_setpin(S3C2410_GPA2, 1);
  1307. mdelay(20);
  1308. //UART1 CTS1 (GPH10) set
  1309. s3c2410_gpio_cfgpin(S3C2410_GPH10, S3C2410_GPH10_CLKOUT1);
  1310. //writel(((readl(S3C2416_GPHCON) | (1<<21)) & ~ (1<<20)), S3C2416_GPHCON);
  1311. //writel(((readl(S3C2416_GPHUDP) & ~ (1<<21)) & ~ (1<<20)), S3C2416_GPHUDP);
  1312. //writel((readl(S3C2416_GPHDAT) & ~(1<<10)), S3C2416_GPHDAT);
  1313. mdelay(1);
  1314. //UART1 RTS1 (GPH11) set
  1315. s3c2410_gpio_cfgpin(S3C2410_GPH11, S3C2410_GPH11_nRTS);
  1316. //writel(((readl(S3C2416_GPHCON) | (1<<23)) & ~(1<<22)), S3C2416_GPHCON);
  1317. //writel((readl(S3C2416_GPHDAT) & ~(1<<11)), S3C2416_GPHDAT);
  1318. //writel(((readl(S3C2416_GPHUDP) & ~ (1<<23)) & ~ (1<<22)), S3C2416_GPHUDP);
  1319. mdelay(1);
  1320. break;
  1321. case S3C_WIFI_POWER_OFF:
  1322. printk("BCM4329-WIFI_POWER_OFF\n");
  1323. //TCON Flash disable, and select WiFi
  1324. s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
  1325. s3c2410_gpio_setpin(S3C2410_GPH6, 0);
  1326. //bcm4329 module power off control
  1327. //EXT_N_WIFI_RST (GPD8) pull down
  1328. s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
  1329. s3c2410_gpio_setpin(S3C2410_GPD8, 0);
  1330. //WIFI_BT_EN (GPD11) pull down
  1331. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
  1332. s3c2410_gpio_setpin(S3C2410_GPD11, 0);
  1333. //EXT_N_BT_RST (GPA2) pull down
  1334. s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
  1335. s3c2410_gpio_setpin(S3C2410_GPA2, 0);
  1336. mdelay(20);
  1337. //GPK9 (green light), pull down
  1338. writel(((readl(S3C2416_GPKCON) & ~(1<<19)) | (1<<18)), S3C2416_GPKCON);
  1339. writel((readl(S3C2416_GPKDAT) & ~(1<<9)), S3C2416_GPKDAT);
  1340. //GPK7, WIFI PA 3.3V
  1341. writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
  1342. writel((readl(S3C2416_GPKDAT) & ~(1<<7)), S3C2416_GPKDAT);
  1343. //GPK6, PA 1.8V
  1344. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1345. writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
  1346. //GPK5, PA 3.3V
  1347. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1348. writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
  1349. break;
  1350. #else
  1351. case S3C_WIFI_POWER_ON:
  1352. printk("WIFI_POWER_ON\n");
  1353. //TCON Flash disable, and select WiFi
  1354. s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
  1355. s3c2410_gpio_setpin(S3C2410_GPH6, 0);
  1356. //GPL13, SPI_CS
  1357. s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_SS0);
  1358. //SPI DI
  1359. s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0);
  1360. //SPI DO
  1361. s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0);
  1362. //SPI CLK
  1363. s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0);
  1364. //GPK6, PA 1.8V
  1365. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1366. writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
  1367. //GPK5, PA 3.3V
  1368. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1369. writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
  1370. //GPD8, RESET
  1371. s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
  1372. s3c2410_gpio_setpin(S3C2410_GPD8, 0);
  1373. mdelay(1);
  1374. s3c2410_gpio_setpin(S3C2410_GPD8, 1);
  1375. mdelay(20);
  1376. break;
  1377. case S3C_WIFI_POWER_OFF:
  1378. printk("WIFI_POWER_OFF\n");
  1379. //TCON Flash disable, and select WiFi
  1380. s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
  1381. s3c2410_gpio_setpin(S3C2410_GPH6, 0);
  1382. //GPK5, PA 3.3V
  1383. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1384. writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
  1385. //GPK6, PA 1.8V
  1386. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1387. writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
  1388. //GPD8, RESET
  1389. s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
  1390. s3c2410_gpio_setpin(S3C2410_GPD8, 0);
  1391. //GPL13, SPI_CS
  1392. s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_OUTP);
  1393. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1394. //SPI DI
  1395. s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_INP);
  1396. s3c2410_gpio_pullup(S3C2410_GPE11, 1);
  1397. //SPI DO
  1398. s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_INP);
  1399. s3c2410_gpio_pullup(S3C2410_GPE12, 1);
  1400. //SPI CLK
  1401. s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_INP);
  1402. s3c2410_gpio_pullup(S3C2410_GPE13, 1);
  1403. break;
  1404. #endif
  1405. case S3C_READ_TILT_STATUS:
  1406. if( ((readl(S3C2410_GPDDAT) & (0x3<<10)) >> 10) == 2){
  1407. return 270;
  1408. }
  1409. else if( ((readl(S3C2410_GPDDAT) & (0x3<<10)) >> 10) == 1){
  1410. return 90;
  1411. }
  1412. else if( ((readl(S3C2410_GPDDAT) & (0x3<<10)) >> 10) == 3){
  1413. return 180;
  1414. }
  1415. else{
  1416. return 0;
  1417. }
  1418. break;
  1419. case S3C_READ_GPIO_VALUE:
  1420. printk("S3C_READ_GPIO_VALUE\n");
  1421. printk("addr: 0x%x\n", arg+0x56000000);
  1422. arg = arg + S3C24XX_VA_GPIO;
  1423. printk("value: 0x%x\n", readl(arg));
  1424. break;
  1425. case S3C_SET_GPIO_ADDR:
  1426. printk("S3C_SET_GPIO_ADDR\n");
  1427. printk("set addr: 0x%x\n", arg + 0x56000000);
  1428. gpio_addr = arg + S3C24XX_VA_GPIO;
  1429. break;
  1430. case S3C_WRITE_GPIO_VALUE:
  1431. printk("S3C_WRITE_GPIO_VALUE\n");
  1432. printk("set addr: 0x%x, value: 0x%x\n", (gpio_addr-0xA0400000), arg);
  1433. writel(arg, gpio_addr);
  1434. break;
  1435. case MMC_DEVICE_POWER_STATE:
  1436. printk("MMC_DEVICE_POWER_STATE: %d\n", arg);
  1437. if(arg == 0){
  1438. card_detect2 = 1;
  1439. s3c_hsmmc_irq_cd (0, global_host[0]);
  1440. }
  1441. else if(arg == 3){
  1442. card_detect2 = 0;
  1443. s3c_hsmmc_irq_cd (0, global_host[0]);
  1444. }
  1445. else{
  1446. printk("no such state\n");
  1447. }
  1448. break;
  1449. case S3C_READ_HW_VERSION:
  1450. //printk("S3C_READ_HW_VERSION\n");
  1451. read_pin = readl(S3C2416_GPKDAT) & 0x1E;
  1452. //printk(" read_pin: 0x%x\n", read_pin);
  1453. ret = 0;
  1454. if((read_pin & (1<<4)))
  1455. ret = ret + 0x1000;
  1456. if((read_pin & (1<<3)))
  1457. ret = ret + 0x0100;
  1458. if((read_pin & (1<<2)))
  1459. ret = ret + 0x0010;
  1460. if((read_pin & (1<<1)))
  1461. ret = ret + 0x0001;
  1462. printk("Board ID: 0x%04x\n", ret);
  1463. return ret;
  1464. break;
  1465. case S3C_TCON_ERASE:
  1466. printk("S3C_TCON_ERASE\n");
  1467. //WiFi off
  1468. //GPK5, PA 3.3V off
  1469. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1470. writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
  1471. //GPK6, PA 1.8V
  1472. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1473. writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
  1474. //GPD8, RESET
  1475. s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
  1476. s3c2410_gpio_setpin(S3C2410_GPD8, 0);
  1477. //GPH6, TCON_FLASH enable, and select TCON flash
  1478. s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
  1479. s3c2410_gpio_setpin(S3C2410_GPH6, 1);
  1480. mdelay(200);
  1481. //Set GPIO for TCON update
  1482. //Chip Select
  1483. s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_OUTP);
  1484. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1485. //GPE11 SPIMISO0
  1486. s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_INP);
  1487. s3c2410_gpio_pullup(S3C2410_GPE11, 0);
  1488. //GPE12 SPIMOSI0
  1489. s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_OUTP);
  1490. s3c2410_gpio_setpin(S3C2410_GPE12, 1);
  1491. //GPE13 SPI CLK
  1492. s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_OUTP);
  1493. s3c2410_gpio_setpin(S3C2410_GPE13, 0);
  1494. msleep(50);
  1495. //Erase TCON Flash
  1496. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1497. udelay(50);
  1498. s3c_tcon_write_byte(0x06); //Setting Write Enable Latch bit
  1499. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1500. udelay(50);
  1501. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1502. udelay(50);
  1503. s3c_tcon_write_byte(0x60); //Write Chip Erase command
  1504. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1505. msleep(500);
  1506. do{
  1507. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1508. udelay(50);
  1509. s3c_tcon_write_byte(0x05); //Write Read Status command
  1510. r_data = s3c_tcon_read_byte();
  1511. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1512. //printk("r_data: 0x%02x\n", r_data);
  1513. msleep(500);
  1514. }while(r_data & 0x01);
  1515. tcon_byte_count = 0;
  1516. tcon_address = 0;
  1517. break;
  1518. case S3C_TCON_ID:
  1519. printk("S3C_TCON_ID: ");
  1520. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1521. udelay(50);
  1522. s3c_tcon_write_byte(0x9F);
  1523. r_data = s3c_tcon_read_byte();
  1524. printk("0x%02X ", r_data);
  1525. r_data = s3c_tcon_read_byte();
  1526. printk("0x%02X ", r_data);
  1527. r_data = s3c_tcon_read_byte();
  1528. printk("0x%02X\n", r_data);
  1529. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1530. break;
  1531. case S3C_TCON_READ:
  1532. printk("S3C_TCON_READ\n");
  1533. printk("\n\ns3c_tcon_read_content 1\n");
  1534. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1535. udelay(50);
  1536. s3c_tcon_write_byte(0x03);
  1537. s3c_tcon_write_byte(0x00);
  1538. s3c_tcon_write_byte(0x00);
  1539. s3c_tcon_write_byte(0x00);
  1540. for(i=0; i<300; i++){
  1541. printk("0x%02x\n", s3c_tcon_read_byte());
  1542. }
  1543. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1544. msleep(50);
  1545. printk("\n\ns3c_tcon_read_content 2\n");
  1546. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1547. udelay(50);
  1548. s3c_tcon_write_byte(0x03);
  1549. s3c_tcon_write_byte(0x02);
  1550. s3c_tcon_write_byte(0x0F);
  1551. s3c_tcon_write_byte(0xA0);
  1552. for(i=0; i<40; i++){
  1553. printk("0x%02x\n", s3c_tcon_read_byte());
  1554. }
  1555. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1556. break;
  1557. case S3C_TCON_BYTE_COUNT:
  1558. tcon_byte_count = arg;
  1559. //printk("S3C_TCON_BYTE_COUNT: %d\n", tcon_byte_count);
  1560. break;
  1561. case S3C_TCON_WRITE:
  1562. //printk("+ S3C_TCON_WRITE: %d\n ", tcon_address);
  1563. copy_from_user(tcon_buffer, arg, tcon_byte_count);
  1564. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1565. udelay(20);
  1566. s3c_tcon_write_byte(0x06); //Setting Write Enable Latch bit
  1567. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1568. udelay(20);
  1569. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1570. udelay(20);
  1571. //printk("0x%x 0x%x 0x%x\n", (tcon_address & 0xFF0000) >> 16, (tcon_address & 0xFF00) >> 8, (tcon_address & 0xFF));
  1572. s3c_tcon_write_byte(0x02); //Write Page Program command
  1573. s3c_tcon_write_byte( (tcon_address & 0xFF0000) >> 16 );
  1574. s3c_tcon_write_byte( (tcon_address & 0xFF00) >> 8 );
  1575. s3c_tcon_write_byte( (tcon_address & 0xFF) );
  1576. for(i=0; i<tcon_byte_count; i++){
  1577. //printk("0x%02X ", tcon_buffer[i]);
  1578. s3c_tcon_write_byte(tcon_buffer[i]);
  1579. }
  1580. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1581. udelay(400);
  1582. do{
  1583. s3c2410_gpio_setpin(S3C2410_GPL13, 0);
  1584. udelay(50);
  1585. s3c_tcon_write_byte(0x05); //Write Read Status command
  1586. r_data = s3c_tcon_read_byte();
  1587. s3c2410_gpio_setpin(S3C2410_GPL13, 1);
  1588. //printk("r_data: 0x%02x\n", r_data);
  1589. udelay(100);
  1590. }while(r_data & 0x01);
  1591. tcon_address = tcon_address + tcon_byte_count;
  1592. //printk("\n- S3C_TCON_WRITE: %d\n\n", tcon_address);
  1593. break;
  1594. default:
  1595. printk("no this command\n");
  1596. }
  1597. return 0;
  1598. }
  1599. #ifdef CONFIG_QISDA_BK060B00
  1600. static int s3c_bt_open(struct inode *inode, struct file *file);
  1601. static int s3c_bt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
  1602. /* File operations struct for character device */
  1603. static const struct file_operations s3c_bt_fops = {
  1604. .owner = THIS_MODULE,
  1605. .ioctl = s3c_bt_ioctl,
  1606. .open = s3c_bt_open,
  1607. .release = NULL
  1608. };
  1609. //Qisda, Ralph Chang, 2010/02/09, for bt power }
  1610. //Qisda, Ralph Chang, 2010/02/09, for bt power {
  1611. static int s3c_bt_open(struct inode *inode, struct file *file)
  1612. {
  1613. return 0;
  1614. }
  1615. static int s3c_bt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1616. {
  1617. switch(cmd){
  1618. case S3C_BT_POWER_ON:
  1619. printk("BCM4329-BT_POWER_ON\n");
  1620. //bcm4329 module power on control
  1621. //GPK7, WIFI PA 3.3V
  1622. writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
  1623. writel((readl(S3C2416_GPKDAT) | (1<<7)), S3C2416_GPKDAT);
  1624. //GPK6, PA 1.8V
  1625. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1626. writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
  1627. //GPK5, PA 3.3V
  1628. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1629. writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
  1630. mdelay(1);
  1631. //GPL8 (blue light), pull high
  1632. //printk ("\n GPL8 (blue light), pull high\n");
  1633. //writel(((readl(S3C2416_GPLCON) & ~(1<<17)) | (1<<16)), S3C2416_GPLCON);
  1634. //writel((readl(S3C2416_GPLDAT) | (1<<8)), S3C2416_GPLDAT);
  1635. //writel(((readl(S3C2416_GPLUDP) | (1<<17)) & ~(1<<16)), S3C2416_GPLUDP); //pull up enable
  1636. //s3c2410_gpio_cfgpin(S3C2410_GPL8, S3C2410_GPL8_OUTP);
  1637. //s3c2410_gpio_setpin(S3C2410_GPL8, 1);
  1638. //s3c2410_gpio_pullup(S3C2410_GPL8, 1);
  1639. //WIFI_BT_EN (GPD11) pull high
  1640. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
  1641. s3c2410_gpio_setpin(S3C2410_GPD11, 0);
  1642. //writel(((readl(S3C2416_GPGCON) & ~(1<<9)) | (1<<8)), S3C2416_GPGCON);
  1643. //writel((readl(S3C2416_GPGDAT) & ~(1<<4)), S3C2416_GPGDAT);
  1644. mdelay(1);
  1645. s3c2410_gpio_setpin(S3C2410_GPD11, 1);
  1646. //writel((readl(S3C2416_GPGDAT) | (1<<4)), S3C2416_GPGDAT);
  1647. mdelay(20);
  1648. /*
  1649. printk("EXT_N_WIFI_RST (GPD8) set high\n");
  1650. //s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
  1651. //s3c2410_gpio_setpin(S3C2410_GPD8, 0);
  1652. writel(((readl(S3C2416_GPDCON) & ~(1<<17)) | (1<<16)), S3C2416_GPDCON);
  1653. writel((readl(S3C2416_GPDDAT) & ~(1<<8)), S3C2416_GPDDAT);
  1654. mdelay(1);
  1655. //s3c2410_gpio_setpin(S3C2410_GPD8, 1);
  1656. writel((readl(S3C2416_GPDDAT) | (1<<8)), S3C2416_GPDDAT);
  1657. mdelay(20);
  1658. */
  1659. //EXT_N_BT_RST (GPA2) pull high
  1660. s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
  1661. s3c2410_gpio_setpin(S3C2410_GPA2, 0);
  1662. mdelay(1);
  1663. s3c2410_gpio_setpin(S3C2410_GPA2, 1);
  1664. mdelay(20);
  1665. //UART1 CTS1 (GPH10) set
  1666. s3c2410_gpio_cfgpin(S3C2410_GPH10, S3C2410_GPH10_CLKOUT1);
  1667. //writel(((readl(S3C2416_GPHCON) | (1<<21)) & ~ (1<<20)), S3C2416_GPHCON);
  1668. //writel(((readl(S3C2416_GPHUDP) & ~ (1<<21)) & ~ (1<<20)), S3C2416_GPHUDP);
  1669. //writel((readl(S3C2416_GPHDAT) & ~(1<<10)), S3C2416_GPHDAT);
  1670. mdelay(1);
  1671. //"UART1 RTS1 (GPH11) set
  1672. s3c2410_gpio_cfgpin(S3C2410_GPH11, S3C2410_GPH11_nRTS);
  1673. //writel(((readl(S3C2416_GPHCON) | (1<<23)) & ~(1<<22)), S3C2416_GPHCON);
  1674. //writel((readl(S3C2416_GPHDAT) & ~(1<<11)), S3C2416_GPHDAT);
  1675. //writel(((readl(S3C2416_GPHUDP) & ~ (1<<23)) & ~ (1<<22)), S3C2416_GPHUDP);
  1676. mdelay(1);
  1677. break;
  1678. case S3C_BT_POWER_OFF:
  1679. printk("BCM4329-BT_POWER_OFF\n");
  1680. //bcm4329 module power off control
  1681. //EXT_N_BT_RST (GPA2) pull down
  1682. s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
  1683. s3c2410_gpio_setpin(S3C2410_GPA2, 0);
  1684. mdelay(20);
  1685. //WIFI_BT_EN (GPD11) pull down
  1686. s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
  1687. s3c2410_gpio_setpin(S3C2410_GPD11, 0);
  1688. //GPL8 (blue light), pull down
  1689. //writel(((readl(S3C2416_GPLCON) & ~(1<<17)) | (1<<16)), S3C2416_GPLCON);
  1690. //writel((readl(S3C2416_GPLDAT) & ~(1<<8)), S3C2416_GPLDAT);
  1691. //s3c2410_gpio_cfgpin(S3C2410_GPL8, S3C2410_GPL8_OUTP);
  1692. //s3c2410_gpio_setpin(S3C2410_GPL8, 0);
  1693. //GPK7, WIFI PA 3.3V
  1694. writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
  1695. writel((readl(S3C2416_GPKDAT) & ~(1<<7)), S3C2416_GPKDAT);
  1696. //GPK6, PA 1.8V
  1697. writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
  1698. writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
  1699. //GPK5, PA 3.3V
  1700. writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
  1701. writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
  1702. break;
  1703. default:
  1704. printk("no this command\n");
  1705. }
  1706. return 0;
  1707. }
  1708. #endif
  1709. /* File operations struct for character device */
  1710. static const struct file_operations s3c_wifi_fops = {
  1711. .owner = THIS_MODULE,
  1712. .ioctl = s3c_wifi_ioctl,
  1713. .open = s3c_wifi_open,
  1714. .release = NULL
  1715. };
  1716. //Qisda, Asaku Chen, 2009/08/20, for wifi power }
  1717. static int s3c_hsmmc_probe (struct platform_device *pdev)
  1718. {
  1719. struct mmc_host *mmc;
  1720. struct s3c_hsmmc_host *host;
  1721. struct s3c_hsmmc_cfg *plat_data;
  1722. uint i;
  1723. int ret;
  1724. #if 0
  1725. unsigned long gpdat;
  1726. unsigned long gpcon;
  1727. /* Trevor Fix QISDA WIFIPMP SD_GPIO, Move to hsmmc_set_gpio*/
  1728. gpcon = __raw_readl(S3C_GPL1CON);
  1729. gpcon = (gpcon & ~(0xf<<12)) | (1<<12); // SD_GPIO(GPL11) Enable control
  1730. __raw_writel(gpcon, S3C_GPL1CON);
  1731. gpdat = __raw_readl(S3C_GPLDAT);
  1732. gpdat |= (1<<11);
  1733. __raw_writel(gpdat, S3C_GPLDAT);
  1734. #endif
  1735. mmc = mmc_alloc_host(sizeof(struct s3c_hsmmc_host), &pdev->dev);
  1736. if (!mmc)
  1737. ret = -ENOMEM;
  1738. plat_data = s3c_hsmmc_get_platdata(&pdev->dev);
  1739. //Qisda, Asaku Chen, 2009/08/20, for wifi power {
  1740. if(plat_data->hwport==1){
  1741. if (register_chrdev (S3C_WIFI_MAJOR, "s3c_wifi_cmd", &s3c_wifi_fops)) {
  1742. printk("unable to get major S3C_WIFI_MAJOR\n");
  1743. }
  1744. }
  1745. //Qisda, Asaku Chen, 2009/08/20, for wifi power }
  1746. #ifdef CONFIG_QISDA_BK060B00
  1747. //Qisda, Ralph Chang, 2010/02/09, for bt power {
  1748. if(plat_data->hwport==1){
  1749. if (register_chrdev (S3C_BT_MAJOR, "s3c_bt_cmd", &s3c_bt_fops)) {
  1750. printk("unable to get major S3C_BT_MAJOR\n");
  1751. }
  1752. }
  1753. //Qisda, Asaku Chen, 2009/08/20, for wifi power }
  1754. #endif
  1755. host = mmc_priv(mmc);
  1756. host->mmc = mmc;
  1757. host->plat_data = plat_data;
  1758. host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1759. if (!host->mem) {
  1760. printk("Failed to get io memory region resouce.\n");
  1761. ret = -ENOENT;
  1762. goto probe_free_host;
  1763. }
  1764. host->mem = request_mem_region(host->mem->start,
  1765. RESSIZE(host->mem), pdev->name);
  1766. if (!host->mem) {
  1767. printk("Failed to request io memory region.\n");
  1768. ret = -ENOENT;
  1769. goto probe_free_host;
  1770. }
  1771. host->base = ioremap(host->mem->start, (host->mem->end - host->mem->start)+1);
  1772. if (host->base == NULL) {
  1773. printk(KERN_ERR "Failed to remap register block\n");
  1774. return -ENOMEM;
  1775. }
  1776. host->irq = platform_get_irq(pdev, 0);
  1777. if (host->irq == 0) {
  1778. printk("Failed to get interrupt resouce.\n");
  1779. ret = -EINVAL;
  1780. goto untasklet;
  1781. }
  1782. DBG("platform_device(pdev): pdev(0x%p), name(%s)\n", pdev, pdev->name);
  1783. DBG("s3c_hsmmc_host(host): mem->start(0x%08x), base(0x%p), size(%d)\n", host->mem->start, host->base, RESSIZE(host->mem));
  1784. DBG("s3c_hsmmc_cfg(plat_data): enabled(%d) hwport(%d)\n", plat_data->enabled, plat_data->hwport);
  1785. /* To detect a card inserted on channel 0, an external interrupt is used. */
  1786. /* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
  1787. #ifdef CONFIG_SD_SW_DEBOUNCE
  1788. if( plat_data->hwport == 0)
  1789. {
  1790. init_timer(&sd_detect_timer);
  1791. sd_detect_timer.function=sdcard_debounce_timer;
  1792. }
  1793. #endif /* CONFIG_SD_SW_DEBOUNCE */
  1794. /* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
  1795. /* Qisda, howard hsu, 2010/01/21, fix start slot for SD card { */
  1796. if( plat_data->hwport == 0)
  1797. {
  1798. mmc->first_devidx = 1;
  1799. }
  1800. else
  1801. {
  1802. mmc->first_devidx = 0;
  1803. }
  1804. /* } Qisda, howard hsu, 2010/01/21, fix start slot for SD card */
  1805. if ((plat_data->enabled == 1) && (plat_data->hwport == 0)) {
  1806. host->irq_cd = platform_get_irq(pdev, 1);
  1807. if (host->irq_cd == 0) {
  1808. printk("Failed to get interrupt resouce.\n");
  1809. ret = -EINVAL;
  1810. goto untasklet;
  1811. }
  1812. #if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  1813. set_irq_type(host->irq_cd, IRQT_BOTHEDGE);
  1814. #elif defined(CONFIG_CPU_S3C6410)
  1815. set_irq_type(host->irq_cd, IRQT_LOW);
  1816. #endif
  1817. }
  1818. host->flags |= S3C_HSMMC_USE_DMA;
  1819. #ifdef CONFIG_HSMMC_SCATTERGATHER
  1820. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C2443)
  1821. for (i=0; i<S3C_HSMMC_MAX_SUB_BUF; i++)
  1822. host->sub_block[i] = kmalloc(S3C_HSMMC_MALLOC_SIZE, GFP_KERNEL);
  1823. #endif
  1824. #endif
  1825. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_ALL);
  1826. /* register some clock sources if exist */
  1827. for (i=0; i<NUM_OF_HSMMC_CLKSOURCES; i++) {
  1828. host->clk[i] = clk_get(&pdev->dev, plat_data->clk_name[i]);
  1829. if (IS_ERR(host->clk[i])) {
  1830. ret = PTR_ERR(host->clk[i]);
  1831. host->clk[i] = ERR_PTR(-ENOENT);
  1832. }
  1833. if (clk_enable(host->clk[i])) {
  1834. host->clk[i] = ERR_PTR(-ENOENT);
  1835. }
  1836. if (!IS_ERR(host->clk[i])) {
  1837. DBG("MMC clock source[%d], %s is %ld Hz\n",i, plat_data->clk_name[i], clk_get_rate(host->clk[i]));
  1838. }
  1839. }
  1840. mmc->ops = &s3c_hsmmc_ops;
  1841. mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
  1842. mmc->f_min = 400 * 1000; /* at least 400kHz */
  1843. /* you must make sure that our hsmmc block can support
  1844. * up to 52MHz. by scsuh
  1845. */
  1846. //mmc->f_max = 100 * MHZ;
  1847. mmc->f_max = 25 * MHZ;
  1848. mmc->caps = plat_data->host_caps;
  1849. DBG("mmc->caps: %08lx\n", mmc->caps);
  1850. printk(KERN_INFO "mmc->caps: %08lx\n", mmc->caps);
  1851. spin_lock_init(&host->lock);
  1852. /*
  1853. * Maximum number of segments. Hardware cannot do scatter lists.
  1854. * XXX: must modify later. by scsuh
  1855. */
  1856. #ifdef CONFIG_HSMMC_SCATTERGATHER
  1857. mmc->max_hw_segs = CONFIG_S3C_HSMMC_MAX_HW_SEGS;
  1858. mmc->max_phys_segs = CONFIG_S3C_HSMMC_MAX_HW_SEGS;
  1859. #else
  1860. mmc->max_hw_segs = 1;
  1861. #endif
  1862. /*
  1863. * Maximum number of sectors in one transfer. Limited by DMA boundary
  1864. * size (512KiB), which means (512 KiB/512=) 1024 entries.
  1865. */
  1866. //mmc->max_sectors = 128; /* 65535/512=128 */
  1867. /*
  1868. * Maximum segment size. Could be one segment with the maximum number
  1869. * of sectors.
  1870. */
  1871. mmc->max_blk_size = 512;
  1872. mmc->max_seg_size = 128 * mmc->max_blk_size;
  1873. mmc->max_blk_count = 128;
  1874. mmc->max_req_size = mmc->max_seg_size;
  1875. init_timer(&host->timer);
  1876. host->timer.data = (unsigned long)host;
  1877. host->timer.function = s3c_hsmmc_check_status;
  1878. host->timer.expires = jiffies + HZ;
  1879. /*
  1880. * Init tasklets.
  1881. */
  1882. tasklet_init(&host->card_tasklet,
  1883. s3c_hsmmc_tasklet_card, (unsigned long)host);
  1884. #if 0
  1885. tasklet_init(&host->finish_tasklet,
  1886. s3c_hsmmc_tasklet_finish, (unsigned long)host);
  1887. #endif
  1888. ret = request_irq(host->irq, s3c_hsmmc_irq, 0, DRIVER_NAME, host);
  1889. if (ret)
  1890. goto untasklet;
  1891. #if defined(CONFIG_CPU_S3C6410) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
  1892. if ((plat_data->enabled == 1) && (plat_data->hwport == 0)) {
  1893. ret = request_irq(host->irq_cd, s3c_hsmmc_irq_cd, 0, DRIVER_NAME, host);
  1894. if (ret)
  1895. goto untasklet;
  1896. enable_irq_wake(host->irq_cd);
  1897. }
  1898. #endif
  1899. s3c_hsmmc_ios_init(host);
  1900. DBG("before mmc_add_host()\n");
  1901. mmc_add_host(mmc);
  1902. DBG("after mmc_add_host()\n");
  1903. #if defined(CONFIG_PM)
  1904. global_host[plat_data->hwport] = host;
  1905. #endif
  1906. printk(KERN_INFO "[s3c_hsmmc_probe]: %s.%d: at 0x%p with irq %d. clk src:",
  1907. pdev->name, pdev->id, host->base, host->irq);
  1908. for (i=0; i<NUM_OF_HSMMC_CLKSOURCES; i++) {
  1909. if (!IS_ERR(host->clk[i]))
  1910. printk(" %s", host->clk[i]->name);
  1911. }
  1912. printk("\n");
  1913. return 0;
  1914. untasklet:
  1915. tasklet_kill(&host->card_tasklet);
  1916. /* tasklet_kill(&host->finish_tasklet); */
  1917. for (i=0; i<NUM_OF_HSMMC_CLKSOURCES; i++) {
  1918. if (host->clk[i] != ERR_PTR(-ENOENT)) {
  1919. clk_disable(host->clk[i]);
  1920. clk_put(host->clk[i]);
  1921. }
  1922. }
  1923. probe_free_host:
  1924. mmc_free_host(mmc);
  1925. return ret;
  1926. }
  1927. static int s3c_hsmmc_remove(struct platform_device *dev)
  1928. {
  1929. struct mmc_host *mmc = platform_get_drvdata(dev);
  1930. struct s3c_hsmmc_host *host = mmc_priv(mmc);
  1931. int i;
  1932. mmc = host->mmc;
  1933. mmc_remove_host(mmc);
  1934. s3c_hsmmc_reset(host, S3C_HSMMC_RESET_ALL);
  1935. for (i=0; i<NUM_OF_HSMMC_CLKSOURCES; i++) {
  1936. clk_disable(host->clk[i]);
  1937. clk_put(host->clk[i]);
  1938. }
  1939. free_irq(host->irq, host);
  1940. del_timer_sync(&host->timer);
  1941. tasklet_kill(&host->card_tasklet);
  1942. /* tasklet_kill(&host->finish_tasklet); */
  1943. #ifdef CONFIG_HSMMC_SCATTERGATHER
  1944. #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C2443)
  1945. kfree(host->sub_block);
  1946. #endif
  1947. #endif
  1948. mmc_free_host(mmc);
  1949. return 0;
  1950. }
  1951. #ifdef CONFIG_PM
  1952. static int s3c_hsmmc_suspend(struct platform_device *pdev, pm_message_t state)
  1953. {
  1954. // struct mmc_card *card;
  1955. struct s3c_hsmmc_host *s3c_host = global_host[pdev->id];
  1956. struct mmc_host *host = s3c_host->mmc;
  1957. #if 0
  1958. /*
  1959. * Fix me later by jsgood
  1960. */
  1961. list_for_each_entry(card, &host->cards, node) {
  1962. if (card->state & MMC_STATE_PRESENT)
  1963. card->state &= ~MMC_STATE_PRESENT;
  1964. }
  1965. #endif
  1966. //USB20_EN
  1967. //writel((readl(S3C2410_GPHCON) & ~(1<<29) | 1<<28), S3C2410_GPHCON);
  1968. //writel((readl(S3C2410_GPHDAT) &~(1<<14)), S3C2410_GPHDAT);
  1969. if(((readl(S3C2410_GPGDAT) &(1<<1))==0)&&((readl(S3C2410_GPHDAT) &(1<<11))==0))
  1970. {
  1971. //if((readl(S3C2410_GPHDAT) &(1<<11))==0)
  1972. {
  1973. printk("\nUSB_UDC_DEVICE_s3c_hsmmc_suspend: usb\n");
  1974. // writel((readl(S3C2410_GPHCON) & ~(1<<29) | (1<<28)), S3C2410_GPHCON);
  1975. s3c2410_gpio_pullup(S3C2443_GPH14,1);
  1976. s3c2410_gpio_cfgpin(S3C2443_GPH14, S3C2443_GPH14_OUTP);
  1977. s3c2410_gpio_setpin(S3C2443_GPH14, 0); /* usb power enbale */
  1978. s3c2410_gpio_pullup(S3C2410_GPD13,1);
  1979. s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPD13_INP);
  1980. }
  1981. }
  1982. if((readl(S3C2410_GPHDAT) &(1<<11))==0)
  1983. {
  1984. printk("\nUSB_UDC_DEVICE_s3c_hsmmc_suspend: 3g\n");
  1985. s3c2410_gpio_pullup(S3C2410_GPH11,1);
  1986. s3c2410_gpio_cfgpin(S3C2410_GPH11, S3C2410_GPH11_OUTP);
  1987. s3c2410_gpio_setpin(S3C2410_GPH11, 0); /* usb power enbale */
  1988. s3c2410_gpio_pullup(S3C2410_GPH8,1);
  1989. s3c2410_gpio_cfgpin(S3C2410_GPH8, S3C2410_GPH8_OUTP);
  1990. s3c2410_gpio_setpin(S3C2410_GPH8, 0); /* usb power enbale */
  1991. s3c2410_gpio_cfgpin(S3C2410_GPH8, S3C2410_GPH9_OUTP);
  1992. s3c2410_gpio_setpin(S3C2410_GPH9, 0); /* usb power enbale */
  1993. // s3c2410_gpio_pullup(S3C2410_GPG3,1);
  1994. // s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_OUTP);
  1995. // s3c2410_gpio_setpin(S3C2410_GPG3, 0); /* usb power enbale */
  1996. }
  1997. mmc_suspend_host(host, state);
  1998. //mmc suspend GPIO config
  1999. s3c_hsmmc_power_switch(s3c_host->plat_data->hwport, 0);
  2000. /* Qisda, Howard, 2009/12/22, fix resume card-detect { */
  2001. if(s3c_host->plat_data->hwport==0)
  2002. {
  2003. inResume = 1;
  2004. card_detect2 = 2;
  2005. }
  2006. /* } Qisda, Howard, 2009/12/22, fix resume card-detect */
  2007. return 0;
  2008. }
  2009. static int s3c_hsmmc_resume(struct platform_device *pdev)
  2010. {
  2011. struct s3c_hsmmc_host *s3c_host = global_host[pdev->id];
  2012. struct mmc_host *host = s3c_host->mmc;
  2013. int read_pin;
  2014. //USB20_EN
  2015. //writel((readl(S3C2410_GPHCON) & ~(1<<29) | 1<<28), S3C2410_GPHCON);
  2016. //writel((readl(S3C2410_GPHDAT) |(1<<14)), S3C2410_GPHDAT);
  2017. if((readl(S3C2410_GPGDAT) &(1<<1))!=0)
  2018. {
  2019. printk("\nUSB_UDC_DEVICE_POWER_STATE: %d\n");
  2020. writel((readl(S3C2410_GPHCON) & ~(1<<29) | 1<<28), S3C2410_GPHCON);
  2021. s3c2410_gpio_pullup(S3C2443_GPH14,2);
  2022. s3c2410_gpio_cfgpin(S3C2443_GPH14,S3C2443_GPH14_OUTP);
  2023. s3c2410_gpio_setpin(S3C2443_GPH14,1); /* usb power enbale */
  2024. }
  2025. //PWREN_SD
  2026. if(s3c_host->plat_data->hwport==0){
  2027. read_pin = readl(S3C2410_GPFDAT) & (1<<1);
  2028. if(read_pin && !card_detect){
  2029. printk("\nNO CARD\n");
  2030. s3c_hsmmc_power_switch(0, 0);
  2031. /* Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger { */
  2032. //set_irq_type(s3c_host->irq_cd, IRQT_FALLING);
  2033. set_irq_type(s3c_host->irq_cd, IRQT_LOW);
  2034. /* } Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger */
  2035. card_detect2 = 3;
  2036. }
  2037. else{
  2038. if(read_pin){
  2039. printk("no card\n");
  2040. /* Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger { */
  2041. //set_irq_type(s3c_host->irq_cd, IRQT_FALLING);
  2042. set_irq_type(s3c_host->irq_cd, IRQT_LOW);
  2043. /* } Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger */
  2044. card_detect = 0;
  2045. //s3c_hsmmc_power_switch(0, 0);
  2046. }
  2047. else{
  2048. printk("card in\n");
  2049. /* Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger { */
  2050. //set_irq_type(s3c_host->irq_cd, IRQT_RISING);
  2051. set_irq_type(s3c_host->irq_cd, IRQT_HIGH);
  2052. /* } Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger */
  2053. card_detect = 1;
  2054. //s3c_hsmmc_power_switch(0, 1);
  2055. }
  2056. card_detect2 = 2;
  2057. s3c_hsmmc_power_switch(0, 1);
  2058. s3c_hsmmc_ios_init(s3c_host);
  2059. mmc_resume_host(host);
  2060. }
  2061. inResume = 0; //howard, 2009/12/22, fix resume card-detect
  2062. }
  2063. else if(s3c_host->plat_data->hwport==1){
  2064. s3c_hsmmc_power_switch(1, 1);
  2065. s3c_hsmmc_ios_init(s3c_host);
  2066. mmc_resume_host(host);
  2067. }
  2068. #if 0
  2069. /* Qisda, Daniel Lee, 2009/07/23, e600 { */
  2070. // For EVT0
  2071. // Set MMC insert/remove irq back.
  2072. if(card_detect)
  2073. set_irq_type(s3c_host->irq_cd, IRQT_RISING);
  2074. else
  2075. set_irq_type(s3c_host->irq_cd, IRQT_FALLING);
  2076. /* Qisda, Daniel Lee, 2009/07/23, e600 } */
  2077. #endif
  2078. /*}Qisda,2009/7/28,Leo SJ Yang*/
  2079. //s3c_hsmmc_ios_init(s3c_host);
  2080. //mmc_resume_host(host);
  2081. /*Qisda,2009/7/28,Leo SJ Yang {*/
  2082. /* Add SD Card,WIFI,USB power management*/
  2083. if(s3c_host->plat_data->hwport==0)
  2084. {
  2085. //card_detect=1;
  2086. }
  2087. /*}Qisda,2009/7/28,Leo SJ Yang*/
  2088. return 0;
  2089. }
  2090. #else
  2091. #define s3c_hsmmc_suspend NULL
  2092. #define s3c_hsmmc_resume NULL
  2093. #endif
  2094. static struct platform_driver s3c_hsmmc_driver =
  2095. {
  2096. .probe = s3c_hsmmc_probe,
  2097. .remove = s3c_hsmmc_remove,
  2098. .suspend = s3c_hsmmc_suspend,
  2099. .resume = s3c_hsmmc_resume,
  2100. .driver = {
  2101. .name = "s3c-hsmmc",
  2102. .owner = THIS_MODULE,
  2103. },
  2104. };
  2105. static int __init s3c_hsmmc_drv_init(void)
  2106. {
  2107. //Disable SD power
  2108. s3c_hsmmc_power_switch(0, 0);
  2109. /*Qisda,2009/7/28,Leo SJ Yang{*/
  2110. //s3c2410_gpio_cfgpin(S3C2410_GPF1,S3C2410_GPF1_EINT1);
  2111. s3c2410_gpio_cfgpin(S3C2410_GPF1,S3C2410_GPF1_INP);
  2112. s3c2410_gpio_pullup(S3C2410_GPF1, 2);
  2113. /*}Qisda,2009/7/28,Leo SJ Yang*/
  2114. return platform_driver_register(&s3c_hsmmc_driver);
  2115. }
  2116. static void __exit s3c_hsmmc_drv_exit(void)
  2117. {
  2118. platform_driver_unregister(&s3c_hsmmc_driver);
  2119. }
  2120. void s3c_moviNAND_power_off(void)
  2121. {
  2122. struct s3c_hsmmc_host *host = global_host[1];
  2123. printk("s3c_moviNAND_power_off");
  2124. s3c_hsmmc_writeb(S3C_HSMMC_POWER_OFF, S3C_HSMMC_PWRCON);
  2125. }
  2126. module_init(s3c_hsmmc_drv_init);
  2127. module_exit(s3c_hsmmc_drv_exit);
  2128. MODULE_DESCRIPTION("S3C SD HOST I/F 1.0 and 2.0 Driver");
  2129. MODULE_LICENSE("GPL");