gpio.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. /************************************************************
  2. * *
  3. * GPIO driver should be build alone, do not reference other drivers *
  4. * *
  5. *************************************************************/
  6. #include <linux/module.h>
  7. #include <linux/types.h>
  8. #include <linux/init.h>
  9. #include <linux/pci.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/delay.h>
  12. #include <linux/wait.h>
  13. #include <asm/irq.h>
  14. #include "gpio.h"
  15. #include <drv_spi_flashalloc_internal.h>
  16. #include <linux/vmalloc.h>
  17. #include <drv_platform.h>
  18. #include <drv2kmf.h>
  19. #include <drv_event.h>
  20. #include <linux/version.h>
  21. #include <gpio_pin_define.h>
  22. #include <Customization.h>
  23. #define HWEMIFunction 1
  24. PGPIO_DEV pGPIODev;
  25. INT8 gpiotablename[] = "gGPIOTableMain";
  26. /* ===============================================================================
  27. Global Misc
  28. ================================================================================= */
  29. static inline void SetMMIO_DWORD(UINT8* mmiobase, ULONG dwIndex, ULONG dwData)
  30. {
  31. writel(dwData, mmiobase+dwIndex);
  32. }
  33. static inline void SetMMIO_DWORD_MASK(UINT8* mmiobase, ULONG dwIndex, ULONG dwData, ULONG dwMask)
  34. {
  35. ULONG dwRes, dwValue;
  36. dwRes = readl(mmiobase+dwIndex);
  37. dwValue = ((dwData & dwMask) | (dwRes & ~dwMask));
  38. writel(dwValue, mmiobase+dwIndex);
  39. }
  40. static inline ULONG GetMMIO_DWORD(UINT8* mmiobase, ULONG dwIndex)
  41. {
  42. ULONG dwRes;
  43. dwRes = readl(mmiobase+dwIndex);
  44. return dwRes;
  45. }
  46. /* ===============================================================================
  47. Global Driver code
  48. ================================================================================= */
  49. static UINT32 GPIOWriteValueH, GPIOWriteValueL;
  50. #define PWM0_PeriodReg 0xbe0f0100
  51. #define PWM0_CtrlReg 0xbe0f0104
  52. #define PWM_EnableBit 0x80000000
  53. #define PWM_PeriodOneSec 0x02ee0000
  54. #define GPIOModeMask 0x80 // 80:GPIO mode, 00:PWM mode
  55. #define GreenLEDMask 0x80
  56. #define RedLedMask 0x40
  57. typedef struct _LED_FLICK_DEV_
  58. {
  59. struct cdev cdev;
  60. struct delayed_work LED_FLICK_Work;
  61. }LED_FLICK_DEV,*PLED_FLICK_DEV;
  62. static LED_FLICK_DEV LED_FLICK_dev, *pLED_FLICK_dev=NULL;
  63. static UINT8 led_flick_value, led_flick_status, led_flick_flag;
  64. static UINT8 led_g_pwm_pin, led_r_pwm_pin;
  65. static CUSTIMIZATION_TABLEPTR pCustTAB = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR;
  66. static void LED_FLICK_fun(void)
  67. {
  68. int flick_time;
  69. led_flick_flag = 0;
  70. if ( led_flick_value & 0x0f ) {
  71. if ( (led_flick_value & 0x0f) == 0x0f ) {
  72. flick_time = (2 * HZ);
  73. }
  74. else {
  75. flick_time = (2 * HZ) / (15-(led_flick_value & 0x0f));
  76. }
  77. }
  78. else {
  79. if (pCustTAB->GreenLEDMode) {
  80. if ( led_flick_value & 0x80 ) {
  81. GPIOWriteFun((UINT8)pCustTAB->GreenLEDNum, 1);
  82. }
  83. else {
  84. GPIOWriteFun((UINT8)pCustTAB->GreenLEDNum, 0);
  85. }
  86. }
  87. if (pCustTAB->RedLEDMode) {
  88. if ( led_flick_value & 0x40 ) {
  89. GPIOWriteFun((UINT8)pCustTAB->RedLEDNum, 1);
  90. }
  91. else {
  92. GPIOWriteFun((UINT8)pCustTAB->RedLEDNum, 0);
  93. }
  94. }
  95. return;
  96. }
  97. if ( pCustTAB->GreenLEDMode && (led_flick_value & 0x80) ) { // Green LED
  98. GPIOWriteFun((UINT8)pCustTAB->GreenLEDNum, led_flick_status);
  99. }
  100. if ( pCustTAB->RedLEDMode && (led_flick_value & 0x40) ) { // Red LED
  101. GPIOWriteFun((UINT8)pCustTAB->RedLEDNum, led_flick_status);
  102. }
  103. if ( led_flick_status == 1 ) {
  104. led_flick_status = 0;
  105. }
  106. else {
  107. led_flick_status = 1;
  108. }
  109. if ( led_flick_value & 0xc0 ) {
  110. if ( flick_time != 0 ) {
  111. schedule_delayed_work(&pLED_FLICK_dev->LED_FLICK_Work, flick_time );
  112. led_flick_flag = 1;
  113. }
  114. }
  115. }
  116. void GPIOFunctionSelect(UINT8 index, UINT8 mode)
  117. {
  118. UINT8* mmiobase;
  119. ULONG Reg;
  120. UINT8 bits;
  121. if(index >= SIS326_GPIO_MAXNUM) {
  122. printk(KERN_EMERG "DisableGPIO ERR index\n");
  123. return;
  124. }
  125. mmiobase = pGPIODev->mmio_vbase;
  126. if(index<=63)
  127. {
  128. mode = mode & 0x3;
  129. // set "function selection" mux to "GPIO (set '00') "
  130. Reg = 0x600 + (index / 16) * 4;
  131. bits = (index % 16) * 2;
  132. SetMMIO_DWORD_MASK(mmiobase, Reg, (mode << bits), (0x3 << bits)); // set '00' to select default function
  133. }
  134. DBG_MSG1(DBGCFG_GPIO, "Disable GPIO%d\n", index);
  135. }
  136. EXPORT_SYMBOL(GPIOFunctionSelect);
  137. static UINT8 RM_GPIOReadFunc(UINT8 index)
  138. {
  139. #if (CONFIG_CHIPID == 0x531) || (CONFIG_CHIPID == 0x533)
  140. UINT8 value=0;
  141. index = index - RM_GPIO_0; // index must between RM_GPIO_0 to RM_GPIO_8
  142. //RMIIRXD0 as GPIO in "0xbe000210[20]='1'0xbe00019c[15]='0'" 0xbe000210[1]='1' 0xbe0001d4[1]
  143. if (index == 0) {
  144. *(volatile UINT32 *)(0xbe000210) = *(volatile UINT32 *)(0xbe000210) | 0x02 | (1<<20);
  145. *(volatile UINT32 *)(0xbe00019c) = *(volatile UINT32 *)(0xbe00019c) & (~(1<<15));
  146. value = (*(volatile UINT8 *)(0xbe0001d4) & 0x02) >> 1;
  147. DBG_MSG1(DBGCFG_GPIO,"RM_GPIO%d = %d\n", index, value);
  148. return value;
  149. }
  150. return 0;
  151. #else
  152. return 0;
  153. #endif
  154. #if 0
  155. UINT32 rmGPIOtmpVal=0;
  156. rmGPIOtmpVal = *(volatile UINT32 *)(RM_GPIO_SEL_REG);
  157. if ( rmGPIOtmpVal & (1<<(index<<1)) ) {
  158. value = 1;
  159. }
  160. else {
  161. value = 0;
  162. }
  163. //DBG_MSG1(DBGCFG_GPIO,"RM_GPIO%d read %d\n",index, value);
  164. return value;
  165. #endif
  166. }
  167. static UINT8 LVDS_GPIOReadFunc(UINT8 index, UINT8 tryRead)
  168. {
  169. UINT8 value=0;
  170. UINT32 tmpVal=0;
  171. if(tryRead==0)
  172. {
  173. *(volatile UINT32 *)(0xbe00012c) &= (~(R_EN_2ND_UARTA | R_EN_1ST_UARTB));
  174. switch(index){
  175. case GPO_TXP4:
  176. case GPO_TXN4:
  177. #if (CONFIG_CHIPID == 0x331) || (CONFIG_CHIPID == 0x131) || (CONFIG_CHIPID == 0x8506)|| (CONFIG_CHIPID == 0x6710)
  178. *(volatile UINT32 *)(0xbe000208) &= (~(1<<4));
  179. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) |= (1<<3);
  180. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) &= (~(1<<0));
  181. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~((1<<4) | (1<<17))); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[4] = '0' and 0xbe00025c[17] = '0'
  182. #else
  183. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~(1<<4)); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[4] = '0'
  184. #endif
  185. break;
  186. case GPO_TXP9:
  187. case GPO_TXN9:
  188. #if (CONFIG_CHIPID == 0x331) || (CONFIG_CHIPID == 0x131) || (CONFIG_CHIPID == 0x8506) || (CONFIG_CHIPID == 0x6710)
  189. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) &= (~(1<<1));
  190. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) |= (1<<4);
  191. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~((1<<9) | (1<<17))); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[9] = '0' and 0xbe00025c[17] = '0'
  192. #else
  193. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~(1<<9)); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[9] = '0'
  194. #endif
  195. break;
  196. }
  197. }
  198. tmpVal = *(volatile UINT32 *)(LVDS_GPIO_SEL_REG);
  199. if(tmpVal & (1<<(16+(index%GPO_TXP4)))){
  200. value=1;
  201. }
  202. else{
  203. value=0;
  204. }
  205. if (index == GPO_TXP4) {
  206. if((*(volatile UINT32 *)0xbe0001c8)&0x40)
  207. value = 1;
  208. else
  209. value = 0;
  210. }
  211. else if (index == GPO_TXN4) {
  212. if((*(volatile UINT32 *)0xbe0001c8)&0x2)
  213. value = 1;
  214. else
  215. value = 0;
  216. }
  217. else if (index == GPO_TXP9) {
  218. if((*(volatile UINT32 *)0xbe0001c8)&0x4)
  219. value = 1;
  220. else
  221. value = 0;
  222. }
  223. else if (index == GPO_TXN9) {
  224. if((*(volatile UINT32 *)0xbe0001c8)&0x8)
  225. value = 1;
  226. else
  227. value = 0;
  228. }
  229. //DBG_MSG1(DBGCFG_GPIO,"LVDS_GPIO%d read %d\n",index, value);
  230. return value;
  231. }
  232. static void RM_GPIOWriteFunc(UINT8 index, UINT8 value)
  233. {
  234. UINT32 rmGPIOtmpVal=0;
  235. index = index - RM_GPIO_0;
  236. rmGPIOtmpVal = *(volatile UINT32 *)(RM_GPIO_SEL_REG);
  237. if ( index != 6 ) {
  238. // enable GPIO mode
  239. rmGPIOtmpVal |= (1<<(index+20));
  240. if ( value ) {
  241. rmGPIOtmpVal |= (1<<(index<<1));
  242. }
  243. else {
  244. rmGPIOtmpVal &= (~(1<<(index<<1)));
  245. }
  246. }
  247. else {
  248. if ( value ) {
  249. rmGPIOtmpVal |= (1<<(index+20)); // Output mode enable for RM_GPO_6 to high
  250. }
  251. else {
  252. rmGPIOtmpVal &= (~(1<<(index+20))); // Output mode disable for RM_GPO_6 to low
  253. }
  254. }
  255. *(volatile UINT32 *)(RM_GPIO_SEL_REG) = rmGPIOtmpVal;
  256. DBG_MSG1(DBGCFG_GPIO,"RM_GPIO%d set %d\t%08x\n",index, value, *(volatile UINT32 *)(RM_GPIO_SEL_REG));
  257. }
  258. static void LVDS_GPIOWriteFunc(UINT8 index, UINT8 value)
  259. {
  260. UINT32 tmpVal=0;
  261. *(volatile UINT32 *)(0xbe00012c) &= (~(R_EN_2ND_UARTA | R_EN_1ST_UARTB));
  262. //0xbe00012c[13] = 0 //0xbe00012c[14] = 0
  263. tmpVal = *(volatile UINT32 *)(LVDS_GPIO_SEL_REG);
  264. switch(index){
  265. case GPO_TXP4:
  266. case GPO_TXN4:
  267. #if (CONFIG_CHIPID == 0x331) || (CONFIG_CHIPID == 0x131) || (CONFIG_CHIPID == 0x8506)|| (CONFIG_CHIPID == 0x6710)
  268. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) |= (1<<0);
  269. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) &= (~(1<<3));
  270. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~((1<<4) | (1<<17))); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[4] = '0' and 0xbe00025c[17] = '0'
  271. #else
  272. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~(1<<4)); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[4] = '0'
  273. #endif
  274. tmpVal |= (1<<0);
  275. break;
  276. case GPO_TXP9:
  277. case GPO_TXN9:
  278. #if (CONFIG_CHIPID == 0x331) || (CONFIG_CHIPID == 0x131) || (CONFIG_CHIPID == 0x8506) || (CONFIG_CHIPID == 0x6710)
  279. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) |= (1<<1);
  280. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) &= (~(1<<4));
  281. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~((1<<9) | (1<<17))); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[9] = '0' and 0xbe00025c[17] = '0'
  282. #else
  283. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG1) &= (~(1<<9)); // LVA_TXP4/LVA_TXN4 as GPO ==> 0xbe00025c[9] = '0'
  284. #endif
  285. tmpVal |= (1<<1);
  286. break;
  287. case GPO_TCP2:
  288. case GPO_TCN2:
  289. tmpVal |= (1<<2);
  290. break;
  291. }
  292. if ( value ) {
  293. tmpVal |= (1<<(16+(index%GPO_TXP4)));
  294. }
  295. else {
  296. tmpVal &= (~(1<<(16+(index%GPO_TXP4))));
  297. }
  298. *(volatile UINT32 *)(LVDS_GPIO_SEL_REG) = tmpVal;
  299. DBG_MSG1(DBGCFG_GPIO,"LVDS_GPIO%d set %d\t%08x\n",index, value, *(volatile UINT32 *)(LVDS_GPIO_SEL_REG));
  300. }
  301. void SetLed(UINT8 LED_NO, UINT8 LED_MODE, UINT8 LED_Mask, UINT8 LED_Status)
  302. {
  303. UINT8 LEDvalue;
  304. UINT32 pwmProid = 0;
  305. led_flick_value = LED_Status;
  306. if ( LED_MODE ) { // GPIO mode
  307. //DBG_MSG1(DBGCFG_GPIO, "[GPIO]LED GPIO mdoe: %02x S:%02x\n", LED_NO, LED_Status);
  308. if ( LED_Status & LED_Mask ) { // check Green status High
  309. LEDvalue = 1;
  310. }
  311. else {
  312. LEDvalue = 0;
  313. }
  314. GPIOWriteFun(LED_NO, LEDvalue);
  315. DBG_MSG1(DBGCFG_GPIO, "LED GPIO%d:%d\n", LED_NO, LEDvalue);
  316. }
  317. else { // PWM mode
  318. if ( LED_NO > 3 ) {
  319. DBG_MSG1(DBGCFG_GPIO, "LED PWM ERR: %02x\n", LED_NO);
  320. return;
  321. }
  322. if(LED_Mask & RedLedMask)
  323. GPIOFunctionSelect(led_r_pwm_pin, 0); // disable GPIO mode
  324. else if(LED_Mask & GreenLEDMask)
  325. GPIOFunctionSelect(led_g_pwm_pin, 0); // disable GPIO mode
  326. else {}
  327. //DBG_MSG1(DBGCFG_GPIO, "[GPIO]LED PWM mdoe: %02x S:%02x\n", LED_NO, LED_Status);
  328. pwmProid = PWM_PeriodOneSec >> (LED_Status & 0x0f);
  329. *(UINT32 *)(PWM0_PeriodReg + LED_NO * 8) = pwmProid;
  330. *(UINT32 *)(PWM0_CtrlReg + LED_NO * 8) = 0;
  331. if ( LED_Status & LED_Mask ) {
  332. if ( LED_Status & 0x0f ) {
  333. *(UINT32 *)(PWM0_CtrlReg + LED_NO * 8) = (pwmProid >> 1) | PWM_EnableBit;
  334. }
  335. else {
  336. *(UINT32 *)(PWM0_CtrlReg + LED_NO * 8) = pwmProid | PWM_EnableBit;
  337. }
  338. }
  339. DBG_MSG1(DBGCFG_GPIO, "Period:%08x\tCtrl:%08x\n", *(UINT32 *)(PWM0_PeriodReg + LED_NO * 8), *(UINT32 *)(PWM0_CtrlReg + LED_NO * 8));
  340. }
  341. if ( (LED_Status & 0x0f )!= 0 ) {
  342. schedule_delayed_work(&pLED_FLICK_dev->LED_FLICK_Work, ((2 * HZ)/(LED_Status & 0x0f)) );
  343. led_flick_flag = 1;
  344. }
  345. else if ( led_flick_flag == 1 ) {
  346. cancel_delayed_work(&pLED_FLICK_dev->LED_FLICK_Work);
  347. flush_delayed_work(&pLED_FLICK_dev->LED_FLICK_Work);
  348. led_flick_flag = 0;
  349. }
  350. }
  351. void CustomLedFun(UINT8 LedStatus)
  352. {
  353. led_flick_value = LedStatus;
  354. #ifndef CONFIG_GLED_DISABLE
  355. SetLed(pCustTAB->GreenLEDNum, pCustTAB->GreenLEDMode, GreenLEDMask, LedStatus);
  356. #endif
  357. SetLed(pCustTAB->RedLEDNum, pCustTAB->RedLEDMode, RedLedMask, LedStatus);
  358. }
  359. EXPORT_SYMBOL(CustomLedFun);
  360. UINT8 GPIOReadFun(UINT8 index)
  361. {
  362. ULONG Reg;
  363. UINT8 bits;
  364. ULONG W_Data;
  365. UINT8 gpiovalue = 0;
  366. if(index > (S2IC_GPIO_MAXNUM - 1))
  367. {
  368. printk(KERN_EMERG "GPIORd ERR index\n");
  369. return STATUS_DATA_ERROR;
  370. }
  371. if (index < SIS326_GPIO_MAXNUM) {
  372. #if (CONFIG_CHIPID == 0x6710)
  373. if ( index == GPIO_7 || index == GPIO_8)
  374. *(volatile UINT32 *)(GPIO_HDMI_SEL_REG) |= (1 << 20);
  375. else if ( index == GPIO_12 || index == GPIO_13)
  376. *(volatile UINT32 *)(GPIO_HDMI_SEL_REG) |= (1 << 21);
  377. #endif
  378. // set GPIO input / output control register to "input mode"
  379. Reg = 0x618 + (index / 32) * 4;
  380. bits = index % 32;
  381. SetMMIO_DWORD_MASK(pGPIODev->mmio_vbase, Reg, (0x1 << bits), (0x1 << bits)); // set '1' to select "input mode"
  382. // set "function selection" mux to "GPIO (set '01') "
  383. Reg = 0x600 + (index / 16) * 4;
  384. bits = (index % 16) * 2;
  385. SetMMIO_DWORD_MASK(pGPIODev->mmio_vbase, Reg, (0x1 << bits), (0x3 << bits)); // set '01' to select "GPIO"
  386. // get GPIO input value
  387. Reg = 0x610 + (index / 32) * 4;
  388. bits = index % 32;
  389. W_Data = (GetMMIO_DWORD(pGPIODev->mmio_vbase, Reg) >> bits) & 0x1;
  390. DBG_MSG1(DBGCFG_GPIO, "Rd GPIO%d:%x\n", (UINT32)index, (UINT32)W_Data);
  391. gpiovalue = (UINT8)W_Data;
  392. }
  393. else if ((index >= GPO_TXP4) && (index <= GPO_TCN2)) { // lvds GPO read function
  394. gpiovalue = LVDS_GPIOReadFunc(index,0);
  395. }
  396. else if ((index >= RM_GPIO_0) && (index <= RM_GPIO_8)) { // RM_GPO read function
  397. gpiovalue = RM_GPIOReadFunc(index);
  398. }
  399. return gpiovalue;
  400. }
  401. EXPORT_SYMBOL(GPIOReadFun);
  402. UINT8 GPIOTryRead(UINT8 index) //only read value, donot change status
  403. {
  404. ULONG Reg;
  405. UINT8 bits;
  406. ULONG W_Data = 0;
  407. if (index > (S2IC_GPIO_MAXNUM - 1)) {
  408. printk(KERN_EMERG "GPIOTryRd ERR index\n");
  409. return STATUS_DATA_ERROR;
  410. }
  411. if (index < SIS326_GPIO_MAXNUM) {
  412. // get GPIO input value
  413. Reg = 0x610 + (index / 32) * 4;
  414. bits = index % 32;
  415. W_Data = (GetMMIO_DWORD(pGPIODev->mmio_vbase, Reg) >> bits) & 0x1;
  416. }
  417. else if ((index >= GPO_TXP4) && (index <= GPO_TCN2)) { // lvds GPO read function
  418. W_Data = LVDS_GPIOReadFunc(index,1);
  419. }
  420. else if ((index >= RM_GPIO_0) && (index <= RM_GPIO_8)) { // RM_GPO read function
  421. W_Data = RM_GPIOReadFunc(index);
  422. }
  423. return (UINT8)W_Data;
  424. }
  425. EXPORT_SYMBOL(GPIOTryRead);
  426. void GPIOWriteFun(UINT8 index, UINT8 value)
  427. {
  428. UINT8* mmiobase;
  429. ULONG Reg;
  430. UINT8 bits;
  431. if(index > (S2IC_GPIO_MAXNUM - 1))
  432. {
  433. DBG_MSG1(DBGCFG_GPIO, "GPIOWr ERR index\n");
  434. return;
  435. }
  436. mmiobase = pGPIODev->mmio_vbase;
  437. if(value > 1)
  438. {
  439. DBG_MSG1(DBGCFG_GPIO, "GPIOWr ERR val\n");
  440. return;
  441. }
  442. // set GPIO output value
  443. //Reg = 0x610 + (index / 32) * 4;
  444. //bits = index % 32;
  445. //SetMMIO_DWORD_MASK(mmiobase, Reg, (value << bits), (0x1 << bits)); // set output value
  446. bits = index % 32;
  447. #ifdef CONFIG_SUPPORT_IR_TX
  448. GPIOWriteValueL = GetMMIO_DWORD(pGPIODev->mmio_vbase, 0x610);
  449. GPIOWriteValueH = GetMMIO_DWORD(pGPIODev->mmio_vbase, 0x614);
  450. #endif
  451. if ( index < 32 ) {
  452. if ( value == 1 ) {
  453. GPIOWriteValueL = GPIOWriteValueL | (0x01 << bits);
  454. }
  455. else {
  456. GPIOWriteValueL = GPIOWriteValueL & (~(0x01 << bits));
  457. }
  458. #if (CONFIG_CHIPID == 0x6710)
  459. if ( index == GPIO_7 || index == GPIO_8)
  460. *(volatile UINT32 *)(GPIO_HDMI_SEL_REG) |= (1 << 20);
  461. else if ( index == GPIO_12 || index == GPIO_13)
  462. *(volatile UINT32 *)(GPIO_HDMI_SEL_REG) |= (1 << 21);
  463. #endif
  464. SetMMIO_DWORD(mmiobase, 0x610, GPIOWriteValueL);
  465. }
  466. else if ( index >= 32 && index < 64 ){
  467. if ( value == 1 ) {
  468. GPIOWriteValueH = GPIOWriteValueH | (0x01 << bits);
  469. }
  470. else {
  471. GPIOWriteValueH = GPIOWriteValueH & ~((0x01 << bits));
  472. }
  473. SetMMIO_DWORD(mmiobase, 0x614, GPIOWriteValueH);
  474. }
  475. else if ((index >= GPO_TXP4) && (index <= GPO_TCN2)) { // lvds GPO read function
  476. LVDS_GPIOWriteFunc(index, value);
  477. return;
  478. }
  479. else if( index >= RM_GPIO_0 && index <= RM_GPIO_8 ){
  480. RM_GPIOWriteFunc(index, value);
  481. return;
  482. }
  483. else if ( index == GPO_IVDD_SEL ) {
  484. if ( value == 1 ) {
  485. *(volatile UINT32 *)(GPO_IVDD_SEL_REG) = *(volatile UINT32 *)(GPO_IVDD_SEL_REG) | (1<<29);
  486. }
  487. else {
  488. *(volatile UINT32 *)(GPO_IVDD_SEL_REG) = *(volatile UINT32 *)(GPO_IVDD_SEL_REG) & (~(1<<29));
  489. }
  490. return;
  491. } else if (GPO_VBUS_EN == index) {
  492. if (1 == value) {
  493. *(volatile UINT8 *)(GPO_VBUS_EN_REG) = *(volatile UINT8 *)(GPO_VBUS_EN_REG) | (1 << 7);
  494. } else {
  495. *(volatile UINT8 *)(GPO_VBUS_EN_REG) = *(volatile UINT8 *)(GPO_VBUS_EN_REG) & (~(1 << 7));
  496. }
  497. return;
  498. } else {
  499. printk(KERN_EMERG "GPIO(%d) number overflow\n",index);
  500. return;
  501. }
  502. // set GPIO input / output control register to "output mode"
  503. Reg = 0x618 + (index / 32) * 4;
  504. bits = index % 32;
  505. SetMMIO_DWORD_MASK(mmiobase, Reg, (0x0 << bits), (0x1 << bits)); // set '0' to select "output mode"
  506. // set "function selection" mux to "GPIO (set '01') "
  507. Reg = 0x600 + (index / 16) * 4;
  508. bits = (index % 16) * 2;
  509. SetMMIO_DWORD_MASK(mmiobase, Reg, (0x1 << bits), (0x3 << bits)); // set '01' to select "GPIO"
  510. DBG_MSG1(DBGCFG_GPIO, "Wr GPIO%d:%x\n", index, value);
  511. }
  512. EXPORT_SYMBOL(GPIOWriteFun);
  513. void GPIOOpenDrainWriteFun(UINT8 index, UINT8 value)
  514. {
  515. ULONG Reg;
  516. UINT8 bits;
  517. //DBG_MSG1(DBGCFG_GPIO, "GPIOOpenDrainWriteFun index 0x%x value 0x%x\n",index,value);
  518. if(index > (S2IC_GPIO_MAXNUM - 1)) {
  519. DBG_MSG1(DBGCFG_GPIO, "GPIOOpenDrainWr ERR index\n");
  520. return;
  521. }
  522. if(value > 1) {
  523. DBG_MSG1(DBGCFG_GPIO, "GPIOOpenDrainWr ERR val\n");
  524. return;
  525. }
  526. if (index < SIS326_GPIO_MAXNUM) {
  527. // (disable the "pull-low" enable bit and) enable the "pull-high" enable bit
  528. Reg = 0x624; // pull-high enable register (for GPIO32-35)
  529. bits = index - 32;
  530. SetMMIO_DWORD_MASK(pGPIODev->mmio_vbase, (Reg + 8), 0, (0x1 << bits)); // disable the pull-low enable bit
  531. SetMMIO_DWORD_MASK(pGPIODev->mmio_vbase, Reg, (0x1 << bits), (0x1 << bits)); // enable the pull-high enable bit
  532. // set GPIO output value to '0'
  533. //Reg = 0x610 + (index / 32) * 4;
  534. //bits = index % 32;
  535. //SetMMIO_DWORD_MASK(mmiobase, Reg, (0x0 << bits), (0x1 << bits)); // set output value = 0
  536. bits = index % 32;
  537. if ( index < 32 ) {
  538. GPIOWriteValueL = GPIOWriteValueL & (~(0x01 << bits));
  539. SetMMIO_DWORD(pGPIODev->mmio_vbase, 0x610, GPIOWriteValueL);
  540. }
  541. else {
  542. GPIOWriteValueH = GPIOWriteValueH & (~(0x01 << bits));
  543. SetMMIO_DWORD(pGPIODev->mmio_vbase, 0x614, GPIOWriteValueH);
  544. }
  545. // set GPIO input / output control register to "input mode / output mode" if value = 1 / 0 (so that the output would be 1 / 0)
  546. Reg = 0x618 + (index / 32) * 4;
  547. bits = index % 32;
  548. SetMMIO_DWORD_MASK(pGPIODev->mmio_vbase, Reg, (value << bits), (0x1 << bits)); // value ==> IO mode control ==> output value
  549. // set "function selection" mux to "GPIO (set '01') "
  550. Reg = 0x600 + (index / 16) * 4;
  551. bits = (index % 16) * 2;
  552. SetMMIO_DWORD_MASK(pGPIODev->mmio_vbase, Reg, (0x1 << bits), (0x3 << bits)); // set '01' to select "GPIO"
  553. DBG_MSG1(DBGCFG_GPIO, "OpenDrainWr GPIO%d:%x\n", index, value);
  554. }
  555. }
  556. EXPORT_SYMBOL(GPIOOpenDrainWriteFun);
  557. void EnableGPIOInterrupt(UINT8 index, UINT8 mode)
  558. {
  559. UINT8* mmiobase;
  560. ULONG Reg;
  561. UINT8 bits;
  562. ULONG dwINTStatus;
  563. #if 0
  564. if (index >= SIS326_GPIO_MAXNUM) {
  565. DBG_MSG1(DBGCFG_GPIO, "EnGPIOInt ERR index %d\n", index);
  566. return;
  567. }
  568. if (mode > 3) {
  569. DBG_MSG1(DBGCFG_GPIO, "EnGPIOInt ERR mode\n");
  570. return;
  571. }
  572. #endif
  573. if (pGPIODev->callbackfuntable[index].function == 0) {
  574. DBG_MSG1(DBGCFG_GPIO, "EnGPIOInt ERR func\n");
  575. return;
  576. }
  577. #if 0
  578. // set GPIO to "input mode" (and get the input value)
  579. GPIOReadFun(index);
  580. #endif
  581. mmiobase = pGPIODev->mmio_vbase;
  582. // set GPIO (input) interrupt polarity mode (for the trigger mode)
  583. Reg = 0x630 + (index / 32) * 4;
  584. bits = index % 32;
  585. SetMMIO_DWORD_MASK(mmiobase, Reg, ((mode & 0x1) << bits), (0x1 << bits)); // set '1' to select "rising-edge or high-level" , '0' to select "falling-edge or low-level" triggered
  586. // set GPIO (input) interrupt trigger mode (level or edge triggerred)
  587. Reg = 0x638 + (index / 32) * 4;
  588. bits = index % 32;
  589. SetMMIO_DWORD_MASK(mmiobase, Reg, ((mode >> 0x1) << bits), (0x1 << bits)); // set '1' to select "edge triggered" , '0' to select "level triggered"
  590. // clear GPIO interrupt status before we enable this interrupt enable bit
  591. Reg = 0x640 + (index / 32) * 4;
  592. bits = index % 32;
  593. dwINTStatus = GetMMIO_DWORD(mmiobase, Reg);
  594. SetMMIO_DWORD(mmiobase, Reg, (dwINTStatus & (0x1 << bits))); // write-1-clear
  595. // set GPIO (input) interrupt enable bit
  596. Reg = 0x648 + (index / 32) * 4;
  597. bits = index % 32;
  598. SetMMIO_DWORD_MASK(mmiobase, Reg, (0x1 << bits), (0x1 << bits)); // set '1' to enable interrupt for this GPIO
  599. DBG_MSG1(DBGCFG_GPIO, "EnGPIOInt:%d\n", index);
  600. }
  601. EXPORT_SYMBOL(EnableGPIOInterrupt);
  602. void DisableGPIOInterrupt(UINT8 index)
  603. {
  604. UINT8* mmiobase;
  605. ULONG Reg;
  606. UINT8 bits;
  607. #if 0
  608. if (index >= SIS326_GPIO_MAXNUM)
  609. {
  610. DBG_MSG1(DBGCFG_GPIO, "DisableGPIOInt ERR index %d\n", index);
  611. return;
  612. }
  613. #endif
  614. mmiobase = pGPIODev->mmio_vbase;
  615. // disable GPIO (input) interrupt enable bit
  616. Reg = 0x648 + (index / 32) * 4;
  617. bits = index % 32;
  618. SetMMIO_DWORD_MASK(mmiobase, Reg, (0x0 << bits), (0x1 << bits)); // set '0' to disable interrupt for this GPIO
  619. #if 0
  620. // reset "function selection" mux to discard "GPIO"
  621. Reg = 0x600 + (index / 16) * 4;
  622. bits = (index % 16) * 2;
  623. SetMMIO_DWORD_MASK(mmiobase, Reg, (0x0 << bits), (0x3 << bits)); // set '00' to discard "GPIO"
  624. #endif
  625. DBG_MSG1(DBGCFG_GPIO, "DisableGPIOInt:%d\n", index);
  626. }
  627. EXPORT_SYMBOL(DisableGPIOInterrupt);
  628. void RegGPIOCallBackFun(UINT8 index,void (*function)(void))
  629. {
  630. if (index >= SIS326_GPIO_MAXNUM) {
  631. DBG_MSG1(DBGCFG_GPIO, "RegGPIOCallBack ERR index %d\n", index);
  632. return;
  633. }
  634. if (function == NULL) {
  635. DBG_MSG1(DBGCFG_GPIO, "RegGPIOCallBack ERR func\n");
  636. pGPIODev->callbackfuntable[index].function = 0;
  637. return;
  638. }
  639. pGPIODev->callbackfuntable[index].function = function;
  640. DBG_MSG1(DBGCFG_GPIO, "RegGPIOCallBack:%d\n", index);
  641. }
  642. EXPORT_SYMBOL(RegGPIOCallBackFun);
  643. #if 0
  644. void UnRegGPIOCallBackFun(UINT8 index)
  645. {
  646. if(index >= SIS326_GPIO_MAXNUM) {
  647. DBG_MSG1(DBGCFG_GPIO, "UnRegGPIOCallBack ERR index %d\n", index);
  648. return;
  649. }
  650. DisableGPIOInterrupt(index);
  651. pGPIODev->callbackfuntable[index].function = 0;
  652. DBG_MSG1(DBGCFG_GPIO, "UnRegGPIOCallBack:%d\n", index);
  653. }
  654. EXPORT_SYMBOL(UnRegGPIOCallBackFun);
  655. #endif
  656. struct semaphore sisgpio_semaphore;
  657. #if 0
  658. UINT32 ClkDetectStateFun95xx(UINT8 ClkDetectIndex)
  659. {
  660. UINT32 vco;
  661. down(&sisgpio_semaphore);
  662. switch (ClkDetectIndex) {
  663. case cpuclk:
  664. writeb(0x10,(UINT8 *)0xbe000113);
  665. writeb(0x11,(UINT8 *)0xbe000113);
  666. break;
  667. case mmioclk:
  668. writeb(0x32,(UINT8 *)0xbe000113);
  669. writeb(0x33,(UINT8 *)0xbe000113);
  670. break;
  671. case mclk:
  672. writeb(0x30,(UINT8 *)0xbe000113);
  673. writeb(0x31,(UINT8 *)0xbe000113);
  674. break;
  675. case lvdsclk:
  676. writeb(0x50,(UINT8 *)0xbe000113);
  677. writeb(0x51,(UINT8 *)0xbe000113);
  678. break;
  679. case x1clk:
  680. writeb(0x40,(UINT8 *)0xbe000113);
  681. writeb(0x41,(UINT8 *)0xbe000113);
  682. break;
  683. case mpeg2_eclk:
  684. writeb(0x20,(UINT8 *)0xbe000113);
  685. writeb(0x21,(UINT8 *)0xbe000113);
  686. break;
  687. case dvclk:
  688. writeb(0xc0,(UINT8 *)0xbe000113);
  689. writeb(0xc1,(UINT8 *)0xbe000113);
  690. break;
  691. case audioclk:
  692. writeb(0xa0,(UINT8 *)0xbe000113);
  693. writeb(0xa1,(UINT8 *)0xbe000113);
  694. break;
  695. case audio36mclk:
  696. writeb(0xd0,(UINT8 *)0xbe000113);
  697. writeb(0xd1,(UINT8 *)0xbe000113);
  698. break;
  699. case cvd2clk:
  700. writeb(0x12,(UINT8 *)0xbe000113);
  701. writeb(0x13,(UINT8 *)0xbe000113);
  702. break;
  703. case hdmiclk:
  704. writeb(0x60,(UINT8 *)0xbe000113);
  705. writeb(0x61,(UINT8 *)0xbe000113);
  706. break;
  707. case gclk:
  708. writeb(0xe0,(UINT8 *)0xbe000113);
  709. writeb(0xe1,(UINT8 *)0xbe000113);
  710. break;
  711. case tsclk:
  712. writeb(0xb0,(UINT8 *)0xbe000113);
  713. writeb(0xb1,(UINT8 *)0xbe000113);
  714. break;
  715. case usb12mclk:
  716. writeb(0x80,(UINT8 *)0xbe000113);
  717. writeb(0x81,(UINT8 *)0xbe000113);
  718. break;
  719. case usb30mclk:
  720. writeb(0x90,(UINT8 *)0xbe000113);
  721. writeb(0x91,(UINT8 *)0xbe000113);
  722. break;
  723. case usb48mclk:
  724. writeb(0x02,(UINT8 *)0xbe000113);
  725. writeb(0x03,(UINT8 *)0xbe000113);
  726. break;
  727. case spiclk:
  728. writeb(0xf0,(UINT8 *)0xbe000113);
  729. writeb(0xf1,(UINT8 *)0xbe000113);
  730. break;
  731. case ejtclk:
  732. writeb(0x70,(UINT8 *)0xbe000113);
  733. writeb(0x71,(UINT8 *)0xbe000113);
  734. break;
  735. case rosclk:
  736. writeb(0x00,(UINT8 *)0xbe000113);
  737. writeb(0x01,(UINT8 *)0xbe000113);
  738. break;
  739. case auxirdrop:
  740. writeb(0x22,(UINT8 *)0xbe000113);
  741. writeb(0x23,(UINT8 *)0xbe000113);
  742. break;
  743. case half_hsdclk:
  744. writeb(0xc2,(UINT8 *)0xbe000113);
  745. writeb(0xc3,(UINT8 *)0xbe000113);
  746. break;
  747. case vclk_h264:
  748. writeb(0x82,(UINT8 *)0xbe000113);
  749. writeb(0x83,(UINT8 *)0xbe000113);
  750. break;
  751. default:
  752. DBG_MSG1(DBGCFG_GPIO, "CLK_DET wrong type:%d\n", ClkDetectIndex);
  753. up(&sisgpio_semaphore);
  754. return 0;
  755. }
  756. mdelay(5);
  757. vco = readl((ULONG *)0xbe0001c0);
  758. DBG_MSG1(DBGCFG_GPIO, "clk index %d\trate:%d\n", ClkDetectIndex, vco);
  759. up(&sisgpio_semaphore);
  760. return vco;
  761. }
  762. EXPORT_SYMBOL(ClkDetectStateFun95xx);
  763. #endif
  764. //**********************************************************
  765. //*
  766. //* Device Opreation
  767. //*
  768. //**********************************************************
  769. #if 0
  770. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8))
  771. static long GPIOIoctlFun(struct file *pFile,UINT32 cmd, unsigned long arg)
  772. #else
  773. static INT32 GPIOIoctlFun(struct inode *inode, struct file *pFile,UINT32 cmd, unsigned long arg)
  774. #endif
  775. {
  776. INT32 retval;
  777. UINT32 data, addr;
  778. ioctl_parameter *parameter;
  779. //DBG_MSG1(DBGCFG_GPIO, "WDTIoctlFun");
  780. if (_IOC_TYPE(cmd) != SIS_IOC_MAGIC)
  781. {
  782. DBG_MSG1(DBGCFG_GPIO, "Invalid cmd");
  783. return -ENOTTY;
  784. }
  785. retval = 0;
  786. switch(cmd)
  787. {
  788. case GPIO_IOC_CLKDET:
  789. parameter = (ioctl_parameter*)arg;
  790. if ( copy_from_user(&addr,&(parameter->para1),sizeof(ULONG)) ) {
  791. DBG_MSG1(DBGCFG_GPIO,"[GPIO]cpFromUser fail\n");
  792. return -EFAULT;
  793. }
  794. data = ClkDetectStateFun95xx(addr);
  795. if ( copy_to_user(&(parameter->para2),&data,sizeof(ULONG)) ) {
  796. DBG_MSG1(DBGCFG_GPIO,"[GPIO]cpToUser fail\n");
  797. return -EFAULT;
  798. }
  799. break;
  800. default:
  801. retval = -ENOTTY;
  802. break;
  803. }
  804. return retval;
  805. }
  806. #endif
  807. static irqreturn_t GPIO_ISR(INT32 irq, void* dev_id, struct pt_regs *regs)
  808. {
  809. UINT8* mmiobase;
  810. ULONG dwINTStatus0;
  811. ULONG dwINTStatus1;
  812. ULONG dwINTEnable0;
  813. ULONG dwINTEnable1;
  814. ULONG i = 0;
  815. if(pGPIODev == NULL)
  816. {
  817. DBG_MSG1(DBGCFG_GPIO, "GPIO_ISR ERR: No pGPIODev\n");
  818. return IRQ_HANDLED;
  819. }
  820. mmiobase = pGPIODev->mmio_vbase;
  821. DBG_MSG1(DBGCFG_GPIO, "\nGPIO_ISR=>\n");
  822. dwINTStatus0 = GetMMIO_DWORD(mmiobase, 0x640);
  823. dwINTStatus1 = GetMMIO_DWORD(mmiobase, 0x644);
  824. dwINTEnable0 = GetMMIO_DWORD(mmiobase, 0x648);
  825. dwINTEnable1 = GetMMIO_DWORD(mmiobase, 0x64c);
  826. SetMMIO_DWORD(mmiobase, 0x640, dwINTStatus0); // write-1-clear
  827. SetMMIO_DWORD(mmiobase, 0x644, dwINTStatus1); // write-1-clear
  828. while(dwINTStatus0 != 0)
  829. {
  830. // check each GPIO interrupt status
  831. if((dwINTStatus0 & 0x1) && (dwINTEnable0 & 0x1))
  832. {
  833. if(pGPIODev->callbackfuntable[i].function != NULL)
  834. {
  835. pGPIODev->callbackfuntable[i].function(); // handle each GPIO interrupt
  836. }
  837. else{ //NULL function
  838. DisableGPIOInterrupt(i);
  839. }
  840. DBG_MSG1(DBGCFG_GPIO, "GPIO_ISR: GPIO%d INT triggered\n", (UINT32)i);
  841. }
  842. dwINTStatus0 >>= 1;
  843. dwINTEnable0 >>= 1;
  844. i++;
  845. }
  846. i = 32;
  847. while(dwINTStatus1 != 0)
  848. {
  849. // check each GPIO interrupt status
  850. if((dwINTStatus1 & 0x1) && (dwINTEnable1 & 0x1))
  851. {
  852. if(pGPIODev->callbackfuntable[i].function != NULL)
  853. {
  854. pGPIODev->callbackfuntable[i].function(); // handle each GPIO interrupt
  855. }
  856. else{ //NULL function
  857. DisableGPIOInterrupt(i);
  858. }
  859. DBG_MSG1(DBGCFG_GPIO, "GPIO_ISR: GPIO%d INT triggered\n", (UINT32)i);
  860. }
  861. dwINTStatus1 >>= 1;
  862. dwINTEnable1 >>= 1;
  863. i++;
  864. }
  865. DBG_MSG1(DBGCFG_GPIO, "\nGPIO_ISR<=\n");
  866. return IRQ_HANDLED;
  867. }
  868. static void mips_GPIO_dispatch(struct pt_regs *regs)
  869. {
  870. do_IRQ(IRQ_Peripheral);
  871. }
  872. static struct irqaction gpio_irqaction =
  873. {
  874. .handler = (irq_handler_t)&GPIO_ISR,
  875. .flags = IRQF_DISABLED ,
  876. .name = "gpio",
  877. };
  878. #if (CONFIG_CHIPID == 0x6710)
  879. static void mips_memout_range_dispatch(struct pt_regs *regs)
  880. {
  881. unsigned int *sp,*gp;
  882. __asm__ __volatile__("move\t%0,$28" : "=r" (gp));
  883. sp = (unsigned int *)gp[18];
  884. printk("<0>$0\t:%08x %08x %08x %08x\n",0,sp[7],sp[8],sp[9]);
  885. printk("<0>$4\t:%08x %08x %08x %08x\n",sp[10],sp[11],sp[12],sp[13]);
  886. printk("<0>$8\t:%08x %08x %08x %08x\n",sp[14],sp[15],sp[16],sp[17]);
  887. printk("<0>$12\t:%08x %08x %08x %08x\n",sp[18],sp[19],sp[20],sp[21]);
  888. printk("<0>$16\t:%08x %08x %08x %08x\n",sp[22],sp[23],sp[24],sp[25]);
  889. printk("<0>$20\t:%08x %08x %08x %08x\n",sp[26],sp[27],sp[28],sp[29]);
  890. printk("<0>$24\t:%08x %08x\n",sp[30],sp[31]);
  891. printk("<0>$28\t:%08x %08x %08x %08x\n",sp[34],sp[35],sp[36],sp[37]);
  892. printk("<0>Hi\t:%08x\n",sp[39]);
  893. printk("<0>Lo\t:%08x\n",sp[40]);
  894. printk("<0>epc\t:%08x\n",sp[43]);
  895. printk("<0>ra\t:%08x\n",sp[37]);
  896. printk("<0>Status\t:%08x\n",sp[38]);
  897. printk("<0>Cause\t:%08x\n",sp[42]);
  898. printk("Process word (pid: %d, threadinfo=%08x, task=%08x %s)\n",current->pid,(unsigned int)gp,(unsigned int)current,current->comm);
  899. *(volatile unsigned char *)0xbe010034 = *(volatile unsigned char *)0xbe010034;
  900. dump_stack();
  901. while(1);
  902. }
  903. static void enable_memout_range_irq(void)
  904. {
  905. set_vi_handler(5, (vi_handler_t)mips_memout_range_dispatch);
  906. do {
  907. *(volatile unsigned char *)0xbe010034 = *(volatile unsigned char *)0xbe010034;
  908. } while(*(volatile unsigned char *)0xbe010034&0x1);
  909. enable_irq(5);
  910. }
  911. #endif
  912. #if 0
  913. static UINT32 VGA_ON = 1; // record the VGA V-sync status
  914. static irqreturn_t VGA_ISR(INT32 irq, void* dev_id, struct pt_regs *regs)
  915. {
  916. UINT8* mmiobase;
  917. ULONG dwINTStatus0;
  918. if(pGPIODev == NULL)
  919. {
  920. DBG_MSG1(DBGCFG_GPIO, "VGA_ISR ERR: No pGPIODev\n");
  921. return IRQ_HANDLED;
  922. }
  923. mmiobase = pGPIODev->mmio_vbase;
  924. DBG_MSG1(DBGCFG_GPIO, "\nVGA_ISR=>\n");
  925. // get VGA-WakeUp/Disconnect register original value
  926. dwINTStatus0 = GetMMIO_DWORD(mmiobase, 0x700);
  927. // process the VGA-WakeUp/Disconnect interrupts and clear (w1c) the interrupt status
  928. if((dwINTStatus0 & (0x3 << 29)) == (0x3 << 29)) // 2010. gaia fixed 365 queer issue
  929. {
  930. VGA_ON = 1;
  931. noticekmf(KMF2UMF_EVID_VGA, KMF2UMF_EVTYPE_VGA_PORTSTATUS,(void *)&VGA_ON, 1);
  932. DBG_MSG1(DBGCFG_GPIO, "VGA_ISR: WakeUp INT triggered\n");
  933. // disable VGA-WakeUp interrupt,
  934. // clear VGA-WakeUp/Disconnect interrupt status once,
  935. // and enable VGA-Disconnect interrupt
  936. SetMMIO_DWORD(mmiobase, 0x700, ((dwINTStatus0 & ~(0x1 << 31)) | (0x2a << 24)));
  937. }
  938. else if((dwINTStatus0 & (0x3 << 25)) == (0x3 << 25)) // 2010. gaia fixed 365 queer issue
  939. {
  940. VGA_ON = 0;
  941. noticekmf(KMF2UMF_EVID_VGA, KMF2UMF_EVTYPE_VGA_PORTSTATUS,(void *)&VGA_ON, 1);
  942. DBG_MSG1(DBGCFG_GPIO, "VGA_ISR: Disconnect INT triggered\n");
  943. // disable VGA-Disconnect interrupt,
  944. // clear VGA-WakeUp/Disconnect interrupt status once,
  945. // and enable VGA-WakeUp interrupt
  946. SetMMIO_DWORD(mmiobase, 0x700, ((dwINTStatus0 & ~(0x1 << 27)) | (0xa2 << 24)));
  947. }
  948. // TODO: We should implement a function to tell the UMF to open or close the panel if it's needed ...
  949. // TODO: Test and check the VGA V-sync detect range settings later ...
  950. DBG_MSG1(DBGCFG_GPIO, "\nVGA_ISR<=\n");
  951. return IRQ_HANDLED;
  952. }
  953. static void mips_VGA_dispatch(struct pt_regs *regs)
  954. {
  955. do_IRQ(IRQ_VGAWakeUp);
  956. }
  957. static struct irqaction vga_irqaction =
  958. {
  959. .handler = (irq_handler_t)&VGA_ISR,
  960. .flags = IRQF_DISABLED ,
  961. .name = "vgawake",
  962. };
  963. void VGAWakeUpInit(void)
  964. {
  965. UINT8* mmiobase;
  966. ULONG W_Data;
  967. if(pGPIODev == NULL)
  968. {
  969. DBG_MSG1(DBGCFG_GPIO, "VGAWakeUpInit ERR\n");
  970. return;
  971. }
  972. mmiobase = pGPIODev->mmio_vbase;
  973. // get VGA-WakeUp/Disconnect register original value
  974. W_Data = GetMMIO_DWORD(mmiobase, 0x700);
  975. // clear (w1c) the interrupt status and enable VGA-WakeUp/Disconnect functions
  976. SetMMIO_DWORD(mmiobase, 0x700, (W_Data & 0x33ffffff)); // disable VGA-WakeUp/Disconnect functions once
  977. SetMMIO_DWORD(mmiobase, 0x700, (W_Data | (0xee << 24) | (0xff << 8))); // enable VGA-WakeUp/Disconnect functions and clear (w1c) the interrupt status, and set the VGA-WakeUp Top-Range-Number to 0xFF (work-around for SiS328 A0)
  978. #if (1)
  979. SetMMIO_DWORD_MASK(mmiobase, 0x70c, 0x10000000, 0x10000000); // set VGA interrupt selection 0x70c[28] 1: To detect vsync or hsync
  980. #endif
  981. // 2010.07.13 enable ISR after set VGA register to avoid INT trigger before Set regsister and hold the system
  982. set_vi_handler(IRQ_VGAWakeUp, (vi_handler_t)mips_VGA_dispatch);
  983. setup_irq(IRQ_VGAWakeUp, &vga_irqaction);
  984. DBG_MSG1(DBGCFG_GPIO, "VGA-WakeUp/Disconnect En\n");
  985. }
  986. void VGAWakeUpExit(void)
  987. {
  988. UINT8* mmiobase;
  989. ULONG W_Data;
  990. if(pGPIODev == NULL)
  991. {
  992. DBG_MSG1(DBGCFG_GPIO, "VGAWakeUpExit ERR\n");
  993. return;
  994. }
  995. mmiobase = pGPIODev->mmio_vbase;
  996. // get VGA-WakeUp/Disconnect register original value
  997. W_Data = GetMMIO_DWORD(mmiobase, 0x700) & 0x33ffffff;
  998. // disable VGA-WakeUp/Disconnect functions and clear (w1c) the interrupt status
  999. SetMMIO_DWORD(mmiobase, 0x700, W_Data); // disable VGA-WakeUp/Disconnect functions
  1000. SetMMIO_DWORD(mmiobase, 0x700, (W_Data | (0x22 << 24))); // clear (w1c) the interrupt status
  1001. // free the VGA-WakeUp/Disconnect IRQ and ISR
  1002. free_irq(IRQ_VGAWakeUp, pGPIODev); // TODO: Why can't we use free_irq(... , NULL) ??
  1003. DBG_MSG1(DBGCFG_GPIO, "VGA-WakeUp/Disconnect Disabled\n");
  1004. }
  1005. #endif
  1006. /* ===============================================================================
  1007. Customer Driver ocde
  1008. ================================================================================= */
  1009. #if HWEMIFunction /* EMI hw function, changed PLL to reduece EMI */
  1010. #if (CONFIG_CHIPID != 0x330)
  1011. void EMI_DRAM_SSC(UINT8 level, void *ssc_value_188, void *ssc_value_1a8, void *ssc_value_Magic_Number){
  1012. #else
  1013. void EMI_DRAM_SSC(UINT8 level){
  1014. #endif
  1015. volatile UINT32 SDM_MAX, SDM_INC, reg1a8;
  1016. volatile UINT32 reg188, sample_rate;
  1017. volatile UINT8 FEBDIV;
  1018. // SDM_MAX = ROUND(32768 * (fdev * 0.000001) * Fmain, 0)
  1019. // SDM_INC = ROUND(4*SDM_MAX*ftri/(sample rate*1000), 1)
  1020. // Fmain = (R_MEM_PLL_MUL[7:0]+1) / 2 // 0xbe0001a4[7:0]
  1021. #if (CONFIG_CHIPID == 0x6710)
  1022. volatile UINT8 i, tmp;
  1023. FEBDIV = *(volatile UINT8 *)(0xbe140053);
  1024. #else
  1025. FEBDIV = *(volatile UINT8 *)(0xbe0001a4);
  1026. #endif
  1027. #if (CONFIG_CHIPID == 0x131) || (CONFIG_CHIPID == 0x8506)|| (CONFIG_CHIPID == 0x6710)
  1028. SDM_MAX = 25000 * (FEBDIV + 1) / 2; // SDM_MAX = 25000 * Fmain
  1029. #else
  1030. SDM_MAX = 32768 * (FEBDIV + 1) / 2; // SDM_MAX = 32768 * Fmain
  1031. #endif
  1032. #if (CONFIG_CHIPID == 0x6710)
  1033. reg188 = 0;
  1034. reg1a8 = readl((ULONG *)(0xbe140058));
  1035. #else
  1036. reg188 = *(volatile ULONG *)(0xbe000188);
  1037. reg1a8 = readl((ULONG *)(0xbe0001a8));
  1038. reg188 &= 0xFFFFF800; // clear SDM_INC[10:0], reserved[11]:x
  1039. reg188 |= 0xF000; // set SDM_TYPE_SEL[15], SDM_SPREAD[14], SDM_DOWNSPREAD[13], and SDM_RSTN[12]
  1040. #endif
  1041. // SDM_MAX = 32768 * Fmain * (fdev/1000)
  1042. switch( level ) {
  1043. case 0:
  1044. reg188 &= 0xFFFF0000;
  1045. #if (CONFIG_CHIPID == 0x6710)
  1046. writew(0, (void *)0xbe14005a);
  1047. #else
  1048. writew(reg188, (void *)0xbe000188);
  1049. #endif
  1050. goto store_to_flash;
  1051. case 1:
  1052. SDM_MAX = SDM_MAX * 1; // fdev = 1000
  1053. break;
  1054. case 2:
  1055. SDM_MAX = SDM_MAX * 2; // fdev = 2000
  1056. break;
  1057. case 3:
  1058. SDM_MAX = SDM_MAX * 3; // fdev = 3000
  1059. break;
  1060. case 4:
  1061. SDM_MAX = SDM_MAX * 4; // fdev = 4000
  1062. break;
  1063. case 5:
  1064. SDM_MAX = SDM_MAX * 5; // fdev = 5000
  1065. break;
  1066. default:
  1067. #if (CONFIG_CHIPID == 0x6710)
  1068. writew(0, (void *)0xbe14005a);
  1069. #else
  1070. writew(reg188, (void *)0xbe000188);
  1071. #endif
  1072. goto store_to_flash;
  1073. }
  1074. SDM_MAX = SDM_MAX / 1000; // SDM_MAX = 32768 * Fmain * (fdev * 0.000001)
  1075. #if (CONFIG_CHIPID == 0x533) || (CONFIG_CHIPID == 0x131) || (CONFIG_CHIPID == 0x8506)
  1076. sample_rate = *(volatile UINT8 *)(0xbe0001a5) & 0x01; // 0xbe0001a4[8]
  1077. #elif (CONFIG_CHIPID == 0x6710)
  1078. sample_rate = *(volatile UINT8 *)(0xbe140054) & 0x03;
  1079. #else
  1080. sample_rate = *(volatile UINT8 *)(0xbe0001a5) & 0x1f; // 0xbe0001a4[12:8]
  1081. #endif
  1082. #if (CONFIG_CHIPID == 0x6710)
  1083. tmp = 1;
  1084. for (i=0; i < sample_rate; i++)
  1085. tmp *= 2;
  1086. sample_rate = 24000 / tmp;
  1087. #else
  1088. sample_rate = 24576 / (sample_rate + 1); // sample rate * 1000
  1089. #endif
  1090. SDM_INC = (SDM_MAX * 4 * 33 ) / sample_rate; // ftri=33.333,
  1091. reg188 |= SDM_INC;
  1092. DBG_MSG1(DBGCFG_GPIO, "SDM_MAX:%08x\tSDM_INC:%08x\treg188:%04x\n", SDM_MAX, SDM_INC, reg188);
  1093. reg1a8 &= 0xFFFE0000; // Clear SDM_MAX[16:0]
  1094. reg1a8 |= SDM_MAX;
  1095. store_to_flash:
  1096. #if (CONFIG_CHIPID != 0x330)
  1097. memcpy(ssc_value_188, (const void *)&reg188, 2);
  1098. memcpy(ssc_value_1a8, (const void *)&reg1a8, 2);
  1099. *(UINT32 *)ssc_value_Magic_Number = 0x28825252;
  1100. DBG_MSG1(DBGCFG_GPIO,"reg188:%08x\treg1a8:%08x\n", reg188, reg1a8);
  1101. #endif
  1102. #if (CONFIG_CHIPID == 0x6710)
  1103. if (reg188) {
  1104. reg1a8 = (reg1a8&0x0001FFFF) | (reg188<<17) | 0xF0000000;
  1105. writel(reg1a8, (void *)(0xbe140058));
  1106. } else {
  1107. writel(reg1a8&0x0001FFFF, (void *)(0xbe140058));
  1108. }
  1109. #else
  1110. writel(reg1a8, (void *)(0xbe0001a8));
  1111. writel(reg188, (void *)(0xbe000188));
  1112. #endif
  1113. DBG_MSG1(DBGCFG_GPIO, "reg188:%08x\treg1a8:%08x\n", readl((ULONG *)(0xbe000188)), readl((ULONG *)(0xbe0001a8)));
  1114. return;
  1115. }
  1116. EXPORT_SYMBOL(EMI_DRAM_SSC);
  1117. #endif
  1118. static INT32 GPIOOpenFun(struct inode *inode, struct file *pFile)
  1119. {
  1120. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] GPIOOpenFun ==> \n");
  1121. pFile->private_data = pGPIODev;
  1122. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] GPIOOpenFun <==\n");
  1123. return 0;
  1124. }
  1125. #if 0
  1126. static INT32 GPIOCloseFun(struct inode *inode, struct file *pFile)
  1127. {
  1128. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] GPIOCloseFun ==>\n");
  1129. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] GPIOCloseFun <==\n");
  1130. return 0;
  1131. }
  1132. #endif
  1133. GPIOMAINConfig_t *gGPIOTab = NULL;
  1134. UINT32 gTableSize = 0;
  1135. UINT8 GPIOGetValue(UINT8 TabIndex)
  1136. {
  1137. UINT8 Level;
  1138. if (TabIndex >= gTableSize)
  1139. {
  1140. DBG_MSG1(DBGCFG_GPIO,"Pin not in GPIOTab\n");
  1141. return GPIO_LEVEL_TRI;
  1142. }
  1143. if (gGPIOTab[TabIndex].Index >= GPIO_NOT_USE)
  1144. {
  1145. DBG_MSG1(DBGCFG_GPIO,"GPIOTab[%d], not use\n", TabIndex);
  1146. return GPIO_LEVEL_TRI;
  1147. }
  1148. switch(gGPIOTab[TabIndex].MainAction)
  1149. {
  1150. case GPIO_INPUT:
  1151. Level = GPIOReadFun(gGPIOTab[TabIndex].Index);
  1152. break;
  1153. default:
  1154. DBG_MSG1(DBGCFG_GPIO,"GPIOTab[%d], not input\n", TabIndex);
  1155. return GPIO_LEVEL_TRI;
  1156. }
  1157. return Level;
  1158. }
  1159. UINT8 GPIOSetValue(UINT8 TabIndex, GPIOState_t State)
  1160. {
  1161. if (TabIndex >= gTableSize)
  1162. {
  1163. DBG_MSG1(DBGCFG_GPIO,"Pin not in GPIOTab\n");
  1164. return 1;
  1165. }
  1166. if (gGPIOTab[TabIndex].Index >= GPIO_NOT_USE)
  1167. {
  1168. DBG_MSG1(DBGCFG_GPIO,"GPIOTab[%d], not use\n", TabIndex);
  1169. return 1;
  1170. }
  1171. switch(gGPIOTab[TabIndex].MainAction)
  1172. {
  1173. case GPIO_OUTPUT:
  1174. if( State == GPIO_FUNC_ONLEVEL)
  1175. {
  1176. if (gGPIOTab[TabIndex].MainLevelInvert)
  1177. {
  1178. GPIOWriteFun(gGPIOTab[TabIndex].Index, GPIO_LEVEL_LOW);
  1179. }
  1180. else
  1181. {
  1182. GPIOWriteFun(gGPIOTab[TabIndex].Index, GPIO_LEVEL_HIGH);
  1183. }
  1184. }
  1185. else if (( State == GPIO_FUNC_OFFLEVEL))
  1186. {
  1187. if (gGPIOTab[TabIndex].MainLevelInvert)
  1188. {
  1189. GPIOWriteFun(gGPIOTab[TabIndex].Index, GPIO_LEVEL_HIGH);
  1190. }
  1191. else
  1192. {
  1193. GPIOWriteFun(gGPIOTab[TabIndex].Index, GPIO_LEVEL_LOW);
  1194. }
  1195. }
  1196. else
  1197. {
  1198. DBG_MSG1(DBGCFG_GPIO, "GPIO_OUTPUT ERR GPIOTab[%d]\n", TabIndex);
  1199. return 1;
  1200. }
  1201. break;
  1202. case GPIO_OPEN_DRAIN:
  1203. if( State == GPIO_FUNC_ONLEVEL)
  1204. GPIOReadFun(gGPIOTab[TabIndex].Index);
  1205. else if ( State == GPIO_FUNC_OFFLEVEL)
  1206. GPIOWriteFun(gGPIOTab[TabIndex].Index, (UINT8)0);
  1207. else
  1208. {
  1209. DBG_MSG1(DBGCFG_GPIO, "GPIO_OPEN_DRAIN ERR GPIOTab[%d]\n", TabIndex);
  1210. return 1;
  1211. }
  1212. break;
  1213. default:
  1214. DBG_MSG1(DBGCFG_GPIO,"ERR GPIOTab[%d]\n", TabIndex);
  1215. return 1;
  1216. }
  1217. return 0;
  1218. }
  1219. UINT8 GPIOSetValueByPinNumber(UINT8 PinNum, GPIOState_t State)
  1220. {
  1221. UINT8 TabIndex = 0;
  1222. UINT8 ret = 1;
  1223. /* Find GPIO table index whick what to control */
  1224. if (gTableSize == 0)
  1225. {
  1226. DBG_MSG1(DBGCFG_GPIO,"GPIO TabSize=0\n");
  1227. }
  1228. if (PinNum >= GPIO_NOT_USE)
  1229. {
  1230. return 1;
  1231. }
  1232. for (TabIndex = 0; TabIndex < gTableSize; TabIndex++)
  1233. {
  1234. if (gGPIOTab[TabIndex].Index == PinNum)
  1235. {
  1236. break;
  1237. }
  1238. }
  1239. ret = GPIOSetValue(TabIndex, State);
  1240. return ret;
  1241. }
  1242. UINT8 GPIOSetValueByPinFunc(GPIODriverFunc_t PinFunc, GPIOState_t State)
  1243. {
  1244. UINT8 TabIndex = 0;
  1245. UINT8 ret = 1;
  1246. /* Find GPIO table index whick what to control */
  1247. for (TabIndex = 0; TabIndex < gTableSize; TabIndex++)
  1248. {
  1249. if (gGPIOTab[TabIndex].DriverFunc == PinFunc)
  1250. {
  1251. break;
  1252. }
  1253. }
  1254. if (TabIndex >= gTableSize)
  1255. {
  1256. return 1;
  1257. }
  1258. /* Check GPIO table index */
  1259. if (gGPIOTab[TabIndex].DriverFunc == GPIO_PIN_DRIVER_IGNORE )
  1260. {
  1261. DBG_MSG1(DBGCFG_GPIO, "GPIO_DRIVER_IGNORE GPIOTab[%d]\n", TabIndex);
  1262. return 0;
  1263. }
  1264. ret = GPIOSetValue(TabIndex, State);
  1265. return ret;
  1266. }
  1267. UINT8 GPIOGetValueByPinNumber(UINT8 PinNum)
  1268. {
  1269. UINT8 Level;
  1270. UINT8 TabIndex = 0;
  1271. /* Find GPIO table index whick what to control */
  1272. for (TabIndex = 0; TabIndex < gTableSize; TabIndex++)
  1273. {
  1274. if (gGPIOTab[TabIndex].Index == PinNum)
  1275. {
  1276. break;
  1277. }
  1278. }
  1279. Level = GPIOGetValue(TabIndex);
  1280. return Level;
  1281. }
  1282. UINT8 GPIOGetValueByPinFunc(GPIODriverFunc_t PinFunc)
  1283. {
  1284. UINT8 Level;
  1285. UINT8 TabIndex = 0;
  1286. /* Find GPIO table index whick what to control */
  1287. for (TabIndex = 0; TabIndex < gTableSize; TabIndex++)
  1288. {
  1289. if (gGPIOTab[TabIndex].DriverFunc == PinFunc)
  1290. {
  1291. break;
  1292. }
  1293. }
  1294. if (TabIndex >= gTableSize)
  1295. {
  1296. return GPIO_LEVEL_TRI;
  1297. }
  1298. /* Check GPIO table index */
  1299. if (gGPIOTab[TabIndex].DriverFunc == GPIO_PIN_DRIVER_IGNORE )
  1300. {
  1301. DBG_MSG1(DBGCFG_GPIO, "GPIO_DRIVER_IGNORE GPIOTab[%d]\n", TabIndex);
  1302. return GPIO_LEVEL_TRI;
  1303. }
  1304. Level = GPIOGetValue(TabIndex);
  1305. return Level;
  1306. }
  1307. UINT32 GPIOSetDefaultValue(void)
  1308. {
  1309. UINT8 TabIndex = 0;
  1310. /* Find GPIO table index whick what to control */
  1311. for (TabIndex = 0; TabIndex < gTableSize; TabIndex++)
  1312. {
  1313. if (gGPIOTab[TabIndex].MainAction == GPIO_OUTPUT)
  1314. {
  1315. GPIOWriteFun(gGPIOTab[TabIndex].Index, gGPIOTab[TabIndex].MainInitLevel);
  1316. }
  1317. }
  1318. return 0;
  1319. }
  1320. void echo_Handler(INT8 *buf, size_t size)
  1321. {
  1322. UINT8 gpioindex;
  1323. UINT8 gpiovalue;
  1324. UINT8 i;
  1325. ULONG tmp,tmp1,tmp2;
  1326. switch(buf[0])
  1327. {
  1328. case 'g':
  1329. if(buf[1]=='r'){ //echo gr00
  1330. gpioindex = (buf[2]-'0')*10+(buf[3]-'0');
  1331. if (gpioindex < S2IC_GPIO_MAXNUM) {
  1332. gpiovalue = GPIOReadFun(gpioindex);
  1333. printk(KERN_EMERG "GPIORd(%d)=%d\n",gpioindex, gpiovalue);
  1334. }
  1335. }
  1336. if(buf[1]=='p'){ //echo gp001 //push pull gpio
  1337. gpioindex = (buf[2]-'0')*10+(buf[3]-'0');
  1338. gpiovalue = (buf[4]-'0');
  1339. if (gpioindex < S2IC_GPIO_MAXNUM) {
  1340. GPIOWriteFun(gpioindex, gpiovalue);
  1341. }
  1342. printk(KERN_EMERG "GPIOWr ok\n");
  1343. //DBG_MSG1(DBGCFG_GPIO,"GPIOWriteFun(%d, %d)\n",gpioindex, gpiovalue);
  1344. }
  1345. if(buf[1]=='o'){ //echo go001 //open drain
  1346. gpioindex = (buf[2]-'0')*10+(buf[3]-'0');
  1347. gpiovalue = (buf[4]-'0');
  1348. GPIOOpenDrainWriteFun(gpioindex, gpiovalue);
  1349. printk(KERN_EMERG "GPIOOpenDrainWr ok\n");
  1350. //DBG_MSG1(DBGCFG_GPIO,"GPIOOpenDrainWriteFun(%d, %d)\n",gpioindex, gpiovalue);
  1351. }
  1352. if (buf[1]=='t') { // echo gt00 // try read
  1353. gpioindex = (buf[2]-'0')*10+(buf[3]-'0');
  1354. gpiovalue = GPIOTryRead(gpioindex);
  1355. printk(KERN_EMERG "GPIOTryRd(%d)=%d\n",gpioindex, gpiovalue);
  1356. }
  1357. break;
  1358. case 'd': //echo d
  1359. for(i=0;i<64;i++){
  1360. tmp2 = readl((ULONG *)(0xbe0f0600+(i/16)*4));
  1361. tmp = readl((ULONG *)(0xbe0f0618+(i/32)*4));
  1362. tmp1 = readl((ULONG *)(0xbe0f0610+(i/32)*4));
  1363. printk(KERN_EMERG "%2d\t%c\tI/O:%d\tVal:%d\n",(INT32)i ,( ((tmp2>>i*2) & 0x3) == 0x01 )?'Y':'N' ,(INT32)((tmp >> i)&0x1), (INT32)((tmp1 >> i)&0x1));
  1364. }
  1365. break;
  1366. case 'c':
  1367. if ( buf[1]=='u' ) { // echo cu??
  1368. gpioindex = (buf[2]-'0')*0x10+(buf[3]-'0');
  1369. CustomLedFun(gpioindex);
  1370. //DBG_MSG1(DBGCFG_GPIO,"SetCustomLed:%d\n", gpioindex);
  1371. }
  1372. break;
  1373. }
  1374. }
  1375. static INT32 EchoWriteFun(struct file *file, const INT8 __user * buf, size_t size, loff_t * ppos)
  1376. {
  1377. size_t in_sz = 0x100;
  1378. INT8 *inbuf = drv_kmalloc(sizeof(GPIO_DEV), GFP_KERNEL, MODULEID_GPIO);
  1379. if(inbuf)
  1380. {
  1381. in_sz = (size < in_sz)?size:in_sz;
  1382. if(copy_from_user(inbuf,buf,in_sz) == 0)
  1383. {
  1384. echo_Handler(inbuf,in_sz);
  1385. }
  1386. drv_kfree(inbuf, MODULEID_GPIO);
  1387. }
  1388. return size;
  1389. }
  1390. static struct file_operations GPIOFops = {
  1391. .owner = THIS_MODULE,
  1392. // .read = EchoReadFun,
  1393. .write = EchoWriteFun,
  1394. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8))
  1395. // .unlocked_ioctl = GPIOIoctlFun,
  1396. #else
  1397. // .ioctl = GPIOIoctlFun,
  1398. #endif
  1399. .open = GPIOOpenFun,
  1400. // .release = GPIOCloseFun,
  1401. };
  1402. INT32 GPIOInit(void)
  1403. {
  1404. INT32 err;
  1405. dev_t devno;
  1406. UINT8 TabIndex;
  1407. /* 2013.10 disable YPP debug for gpio 43 44 */
  1408. SetMMIO_DWORD_MASK((UINT8*)0xbe000038, 0, (1<<6), (1<<6));
  1409. sema_init(&sisgpio_semaphore, 1);
  1410. #if 1
  1411. pGPIODev = (PGPIO_DEV)kmalloc(sizeof(GPIO_DEV), GFP_KERNEL);
  1412. #else
  1413. pGPIODev = (PGPIO_DEV)drv_kmalloc(sizeof(GPIO_DEV), GFP_KERNEL, MODULEID_GPIO);
  1414. #endif
  1415. memset(pGPIODev, 0, sizeof(GPIO_DEV));
  1416. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] =>GPIOInit\n");
  1417. pGPIODev->mmio_vbase = (UINT8*)MMIOBASE_Peripheral;
  1418. pGPIODev->irq = IRQ_Peripheral;
  1419. set_vi_handler(IRQ_Peripheral, (vi_handler_t)mips_GPIO_dispatch);
  1420. setup_irq(IRQ_Peripheral, &gpio_irqaction);
  1421. #if (CONFIG_CHIPID == 0x6710)
  1422. enable_memout_range_irq();
  1423. #endif
  1424. //////////////////////////////////////////////
  1425. devno = MKDEV(SISGPIO_DEV_MAJOR, 0);
  1426. err = register_chrdev_region(devno, 1, "sisgpio");
  1427. if(err)
  1428. {
  1429. DBG_MSG1(DBGCFG_GPIO, "GPIOInit Failed\n");
  1430. return -EIO;
  1431. }
  1432. cdev_init(&pGPIODev->cdev, &GPIOFops);
  1433. pGPIODev->cdev.owner = THIS_MODULE;
  1434. err = cdev_add(&pGPIODev->cdev, devno, 1);
  1435. if(err)
  1436. {
  1437. DBG_MSG1(DBGCFG_GPIO, "GPIOInit Failed\n");
  1438. return -EIO;
  1439. }
  1440. // VGAWakeUpInit(); // enable VGA-WakeUp/Disconnect functions
  1441. // initial LED FLICK
  1442. led_flick_value = 0;
  1443. led_flick_status = 0;
  1444. led_flick_flag = 0;
  1445. pLED_FLICK_dev = &LED_FLICK_dev;
  1446. memset(pLED_FLICK_dev,0,sizeof(LED_FLICK_DEV));
  1447. INIT_DELAYED_WORK(&pLED_FLICK_dev->LED_FLICK_Work, (void *)LED_FLICK_fun);
  1448. GPIOWriteValueL = GetMMIO_DWORD(pGPIODev->mmio_vbase, 0x610);
  1449. GPIOWriteValueH = GetMMIO_DWORD(pGPIODev->mmio_vbase, 0x614);
  1450. GetCustomerData(gpiotablename, (void *)&gGPIOTab, &gTableSize);
  1451. gTableSize /= sizeof(GPIOMAINConfig_t);
  1452. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] GPIOInit <= \n");
  1453. for (TabIndex = 0; TabIndex < gTableSize; TabIndex++)
  1454. {
  1455. if (gGPIOTab[TabIndex].DriverFunc == GPIO_PIN_LED_G_PWM)
  1456. {
  1457. led_g_pwm_pin = gGPIOTab[TabIndex].Index;
  1458. continue;
  1459. }
  1460. if (gGPIOTab[TabIndex].DriverFunc == GPIO_PIN_LED_R_PWM)
  1461. {
  1462. led_r_pwm_pin = gGPIOTab[TabIndex].Index;
  1463. }
  1464. }
  1465. return 0;
  1466. }
  1467. #if 0
  1468. void GPIOExit(void)
  1469. {
  1470. dev_t devno = MKDEV(SISGPIO_DEV_MAJOR, 0);
  1471. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] =>GPIOExit\n");
  1472. VGAWakeUpExit(); // disable VGA-WakeUp/Disconnect functions
  1473. free_irq(IRQ_Peripheral, pGPIODev);
  1474. //sisgpio_exit(pGPIODev);
  1475. cdev_del(&pGPIODev->cdev);
  1476. unregister_chrdev_region(devno, 1);
  1477. #if 1
  1478. kfree(pGPIODev);
  1479. #else
  1480. drv_kfree(pGPIODev, MODULEID_GPIO);
  1481. #endif
  1482. pGPIODev = NULL;
  1483. //DBG_MSG1(DBGCFG_GPIO, "[GPIO] GPIOExit <= \n");
  1484. }
  1485. #endif
  1486. #ifndef INIT_BY_KMF
  1487. module_init (GPIOInit);
  1488. module_exit (GPIOExit);
  1489. #endif
  1490. MODULE_LICENSE("Dual BSD/GPL");