gpio.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. Linux PINMUX.C
  3. */
  4. #include <linux/module.h>
  5. #include <stdarg.h>
  6. #include <linux/spinlock.h>
  7. #include <mach/am_regs.h>
  8. #include <mach/gpio.h>
  9. #include <mach/gpio_data.h>
  10. #include <plat/regops.h>
  11. #include "gpio_data.c"
  12. #ifndef DEBUG_PINMUX
  13. #define debug(a...)
  14. #else
  15. #define debug(a...) printk(KERN_INFO a)
  16. #endif
  17. #define set_pin_mux_reg(a,b) if(b!=NOT_EXIST){ a[(b>>5)&0xf]|=(1<<(b&0x1f)) ;}
  18. static int32_t single_pin_pad(uint32_t reg_en[P_PIN_MUX_REG_NUM], uint32_t reg_dis[P_PIN_MUX_REG_NUM],uint32_t pad, uint32_t sig)
  19. {
  20. uint32_t enable,disable;
  21. int32_t ret=-1;
  22. foreach_pad_sig_start(pad,sig)
  23. case_pad_equal(enable,disable);
  24. set_pin_mux_reg(reg_dis,enable);
  25. set_pin_mux_reg(reg_en,disable);
  26. case_end;
  27. case_sig_equal(enable,disable);
  28. set_pin_mux_reg(reg_dis,enable);
  29. set_pin_mux_reg(reg_en,disable);
  30. case_end;
  31. case_both_equal(enable,disable);
  32. set_pin_mux_reg(reg_en,enable);
  33. set_pin_mux_reg(reg_dis,disable);
  34. ret=0;
  35. case_end;
  36. foreach_pad_sig_end;
  37. if(ret==-1&&sig!=SIG_GPIOIN&&sig!=SIG_GPIOOUT)
  38. return -1;
  39. return 0;
  40. }
  41. #if 0
  42. static uint32_t caculate_pinmux_set_size(uint32_t reg_en[P_PIN_MUX_REG_NUM], uint32_t reg_dis[P_PIN_MUX_REG_NUM])
  43. {
  44. uint32_t ret=0;
  45. int i;
  46. for(i=0;i<P_PIN_MUX_REG_NUM;i++)
  47. {
  48. if(reg_en[i]||reg_dis[i])
  49. ret++;
  50. }
  51. return ret;
  52. }
  53. #endif
  54. static int32_t caculate_single_pinmux_set(pinmux_item_t pinmux[P_PIN_MUX_REG_NUM+1],uint32_t pad,uint32_t sig)
  55. {
  56. uint32_t reg_en[P_PIN_MUX_REG_NUM];
  57. uint32_t reg_dis[P_PIN_MUX_REG_NUM];
  58. int32_t i,j;
  59. pinmux_item_t end=PINMUX_END_ITEM;
  60. memset(reg_en,0,sizeof(reg_en));
  61. memset(reg_dis,0,sizeof(reg_dis));
  62. if(single_pin_pad(reg_en,reg_dis,pad,sig)<0)
  63. return -1;
  64. for(j=0,i=0;i<P_PIN_MUX_REG_NUM;i++)
  65. {
  66. if(reg_en[i]==0&&reg_dis[i]==0)
  67. continue;
  68. pinmux[j].setmask=reg_en[i];
  69. pinmux[j].clrmask=reg_dis[i];
  70. pinmux[j].reg=i;
  71. j++;
  72. }
  73. pinmux[j]=end;
  74. return 0;
  75. }
  76. /**
  77. * UTIL interface
  78. * these function can be implement in a tools
  79. */
  80. /**
  81. * @return NULL is fail
  82. * errno NOTAVAILABLE ,
  83. * SOMEPIN IS LOCKED
  84. */
  85. static DEFINE_SPINLOCK(lock);
  86. static uint32_t pimux_locktable[P_PIN_MUX_REG_NUM];
  87. pinmux_set_t* pinmux_cacl_str(char * pad,char * sig ,...)
  88. {
  89. printk(" %s , NOT IMPLENMENT\n",__func__);
  90. BUG();
  91. /**
  92. * @todo NOT implement;
  93. */
  94. return NULL;
  95. }
  96. EXPORT_SYMBOL(pinmux_cacl_str);
  97. pinmux_set_t* pinmux_cacl_int(uint32_t pad,uint32_t sig ,...)
  98. {
  99. #if 0
  100. va_list ap;
  101. int d;
  102. char c, *s;
  103. va_start(ap, fmt);
  104. while (*fmt)
  105. switch (*fmt++) {
  106. case 's': /* string */
  107. s = va_arg(ap, char *);
  108. printf("string %s\n", s);
  109. break;
  110. case 'd': /* int */
  111. d = va_arg(ap, int);
  112. printf("int %d\n", d);
  113. break;
  114. case 'c': /* char */
  115. /* need a cast here since va_arg only
  116. takes fully promoted types */
  117. c = (char) va_arg(ap, int);
  118. printf("char %c\n", c);
  119. break;
  120. }
  121. va_end(ap);
  122. #endif
  123. printk(" %s , NOT IMPLENMENT\n",__func__);
  124. BUG();
  125. /**
  126. * @todo NOT implement;
  127. */
  128. return NULL;
  129. }
  130. EXPORT_SYMBOL(pinmux_cacl_int);
  131. pinmux_set_t* pinmux_cacl(char * str)///formate is "pad=sig pad=sig "
  132. {
  133. printk(" %s , NOT IMPLENMENT\n",__func__);
  134. BUG();
  135. /**
  136. * @todo NOT implement;
  137. */
  138. return NULL;
  139. }
  140. EXPORT_SYMBOL(pinmux_cacl);
  141. char ** pin_get_list(void)
  142. {
  143. return (char **)&pad_name[0];
  144. }
  145. EXPORT_SYMBOL(pin_get_list);
  146. char ** sig_get_list(void)
  147. {
  148. return (char **)&sig_name[0];
  149. }
  150. EXPORT_SYMBOL(sig_get_list);
  151. char * pin_getname(uint32_t pin)
  152. {
  153. printk(" %s , NOT IMPLENMENT\n",__func__);
  154. BUG();
  155. /**
  156. * @todo NOT implement;
  157. */
  158. return NULL;
  159. }
  160. EXPORT_SYMBOL(pin_getname);
  161. char * sig_getname(uint32_t sig)
  162. {
  163. printk(" %s , NOT IMPLENMENT\n",__func__);
  164. BUG();
  165. /**
  166. * @todo NOT implement;
  167. */
  168. return NULL;
  169. }
  170. EXPORT_SYMBOL(sig_getname);
  171. uint32_t pins_num(void)
  172. {
  173. return PAD_MAX_PADS;
  174. }
  175. EXPORT_SYMBOL(pins_num);
  176. /**
  177. * Util Get status function
  178. */
  179. uint32_t pin_sig(uint32_t pin)
  180. {
  181. return SIG_MAX_SIGS;
  182. }
  183. EXPORT_SYMBOL(pin_sig);
  184. uint32_t sig_pin(uint32_t sig)
  185. {
  186. printk(" %s , NOT IMPLENMENT\n",__func__);
  187. BUG();
  188. /**
  189. * @todo NOT implement;
  190. */
  191. return 0-1;
  192. }
  193. EXPORT_SYMBOL(sig_pin);
  194. /**
  195. * pinmux set function
  196. * @return 0, success ,
  197. * SOMEPIN IS LOCKED, some pin is locked to the specail feature . You can not change it
  198. * NOTAVAILABLE, not available .
  199. */
  200. int32_t pinmux_set(pinmux_set_t* pinmux )
  201. {
  202. uint32_t locallock[P_PIN_MUX_REG_NUM];
  203. uint32_t reg,value,conflict,dest_value;
  204. ulong flags;
  205. int i;
  206. if(pinmux==NULL)
  207. return -4;
  208. debug( " pinmux addr %p \n",(pinmux->pinmux));
  209. memset(locallock,0,sizeof(locallock));
  210. ///check lock table
  211. for(i=0;pinmux->pinmux[i].reg!=0xffffffff;i++)
  212. {
  213. reg=pinmux->pinmux[i].reg;
  214. locallock[reg]=pinmux->pinmux[i].clrmask|pinmux->pinmux[i].setmask;
  215. dest_value=pinmux->pinmux[i].setmask;
  216. conflict=locallock[reg]&pimux_locktable[reg];
  217. if(conflict)
  218. {
  219. value=readl(p_pin_mux_reg_addr[reg])&conflict;
  220. dest_value&=conflict;
  221. if(value!=dest_value)
  222. {
  223. printk("set fail , detect locktable conflict");
  224. return -1;///lock fail some pin is locked by others
  225. }
  226. }
  227. }
  228. if(pinmux->chip_select!=NULL )
  229. {
  230. if(pinmux->chip_select(true)==false){
  231. debug("error return -3");
  232. return -3;///@select chip fail;
  233. }
  234. }
  235. spin_lock_irqsave(&lock, flags);
  236. for(i=0;pinmux->pinmux[i].reg!=0xffffffff;i++)
  237. {
  238. debug( "clrsetbits %08x %08x %08x \n",p_pin_mux_reg_addr[pinmux->pinmux[i].reg],pinmux->pinmux[i].clrmask,pinmux->pinmux[i].setmask);
  239. pimux_locktable[pinmux->pinmux[i].reg]|=locallock[pinmux->pinmux[i].reg];
  240. clrsetbits_le32(p_pin_mux_reg_addr[pinmux->pinmux[i].reg],pinmux->pinmux[i].clrmask,pinmux->pinmux[i].setmask);
  241. }
  242. spin_unlock_irqrestore(&lock, flags);
  243. return 0;
  244. }
  245. EXPORT_SYMBOL(pinmux_set);
  246. int32_t pinmux_clr(pinmux_set_t* pinmux)
  247. {
  248. ulong flags;
  249. int i;
  250. if(pinmux==NULL)
  251. return -4;
  252. if(pinmux->chip_select==NULL)///non share device , we should put the pins in same status always
  253. return 0;
  254. pinmux->chip_select(false);
  255. debug("pinmux_clr : %p" ,pinmux->pinmux);
  256. spin_lock_irqsave(&lock, flags);
  257. for(i=0;pinmux->pinmux[i].reg!=0xffffffff;i++)
  258. {
  259. pimux_locktable[pinmux->pinmux[i].reg]&=~(pinmux->pinmux[i].clrmask|pinmux->pinmux[i].setmask);
  260. }
  261. for(i=0;pinmux->pinmux[i].reg!=0xffffffff;i++)
  262. {
  263. debug("clrsetbits %x %x %x",p_pin_mux_reg_addr[pinmux->pinmux[i].reg],pinmux->pinmux[i].setmask|pinmux->pinmux[i].clrmask,pinmux->pinmux[i].clrmask);
  264. clrsetbits_le32(p_pin_mux_reg_addr[pinmux->pinmux[i].reg],pinmux->pinmux[i].setmask|pinmux->pinmux[i].clrmask,pinmux->pinmux[i].clrmask);
  265. }
  266. spin_unlock_irqrestore(&lock, flags);
  267. return 0;
  268. }
  269. EXPORT_SYMBOL(pinmux_clr);
  270. int32_t pinmux_set_locktable(pinmux_set_t* pinmux )
  271. {
  272. ulong flags;
  273. int i;
  274. if(pinmux==NULL)
  275. return -4;
  276. spin_lock_irqsave(&lock, flags);
  277. for(i=0;pinmux->pinmux[i].reg!=0xffffffff;i++)
  278. {
  279. pimux_locktable[pinmux->pinmux[i].reg]|=pinmux->pinmux[i].clrmask|pinmux->pinmux[i].setmask;
  280. clrsetbits_le32(p_pin_mux_reg_addr[pinmux->pinmux[i].reg],pinmux->pinmux[i].clrmask,pinmux->pinmux[i].setmask);
  281. }
  282. spin_unlock_irqrestore(&lock, flags);
  283. return 0;
  284. }
  285. EXPORT_SYMBOL(pinmux_set_locktable);
  286. /**
  287. * @return 0, success ,
  288. * SOMEPIN IS LOCKED, some pin is locked to the specail feature . You can not change it
  289. * NOTAVAILABLE, not available .
  290. */
  291. static int32_t pad_to_gpio(uint32_t pad)
  292. {
  293. pinmux_item_t pinmux[P_PIN_MUX_REG_NUM];
  294. pinmux_set_t dummy;
  295. memset(&dummy,0,sizeof(dummy));
  296. if(caculate_single_pinmux_set(pinmux,pad,SIG_GPIOIN)<0)
  297. return -1;
  298. dummy.pinmux=&pinmux[0];
  299. return pinmux_set(&dummy);
  300. }
  301. int32_t gpio_set_status(uint32_t pin,bool gpio_in)
  302. {
  303. unsigned bit,reg;
  304. if(pad_to_gpio(pin)<0)
  305. return -1;
  306. reg=(pad_gpio_bit[pin]>>5)&0xf;
  307. bit=(pad_gpio_bit[pin])&0x1f;
  308. clrsetbits_le32(p_gpio_oen_addr[reg],1<<bit,gpio_in<<bit);
  309. return 0;
  310. }
  311. EXPORT_SYMBOL(gpio_set_status);
  312. bool gpio_get_status(uint32_t pin)
  313. {
  314. unsigned bit,reg;
  315. bool bret;
  316. reg=(pad_gpio_bit[pin]>>5)&0xf;
  317. bit=(pad_gpio_bit[pin])&0x1f;
  318. return ((aml_get_reg32_bits(p_gpio_oen_addr[reg],bit, 1))?(gpio_status_in):(gpio_status_out));
  319. }
  320. EXPORT_SYMBOL(gpio_get_status);
  321. int32_t gpio_get_val(uint32_t pin)
  322. {
  323. unsigned bit,reg;
  324. reg=(pad_gpio_bit[pin]>>5)&0xf;
  325. bit=(pad_gpio_bit[pin])&0x1f;
  326. return aml_get_reg32_bits(p_gpio_in_addr[reg],bit, 1);
  327. }
  328. EXPORT_SYMBOL(gpio_get_val);
  329. /**
  330. * GPIO out function
  331. */
  332. int32_t gpio_out(uint32_t pin,bool high)
  333. {
  334. unsigned bit,reg;
  335. if(gpio_set_status(pin,false)==0)
  336. {
  337. reg=(pad_gpio_bit[pin]>>5)&0xf;
  338. bit=(pad_gpio_bit[pin])&0x1f;
  339. if((p_gpio_out_addr[reg]&3)==2)
  340. {
  341. reg=p_gpio_out_addr[reg]&(~3);
  342. bit+=16;
  343. }else{
  344. reg=p_gpio_out_addr[reg];
  345. }
  346. clrsetbits_le32(reg,1<<bit,high<<bit);
  347. return 0;
  348. };
  349. return -1;
  350. }
  351. EXPORT_SYMBOL(gpio_out);
  352. /**
  353. * GPIO in function .ls
  354. */
  355. int32_t gpio_in_get(uint32_t pin)
  356. {
  357. unsigned bit,reg;
  358. if(gpio_set_status(pin,true)<0)
  359. {
  360. printk(" %s , Set gpio to input fail\n",__func__);
  361. BUG();
  362. }
  363. reg=(pad_gpio_bit[pin]>>5)&0xf;
  364. bit=(pad_gpio_bit[pin])&0x1f;
  365. return (readl(p_gpio_in_addr[reg])>>bit)&1;
  366. }
  367. EXPORT_SYMBOL(gpio_in_get);
  368. /**
  369. * Multi pin operation
  370. * @return 0, success ,
  371. * SOMEPIN IS LOCKED, some pin is locked to the specail feature . You can not change it
  372. * NOTAVAILABLE, not available .
  373. *
  374. */
  375. gpio_set_t * gpio_out_group_cacl(uint32_t pin,uint32_t bits, ... )
  376. {
  377. printk(" %s , NOT IMPLENMENT\n",__func__);
  378. BUG();
  379. /**
  380. * @todo NOT implement;
  381. */
  382. return NULL;
  383. }
  384. EXPORT_SYMBOL(gpio_out_group_cacl);
  385. int32_t gpio_out_group_set(gpio_set_t * set,uint32_t high_low )
  386. {
  387. printk(" %s , NOT IMPLENMENT\n",__func__);
  388. BUG();
  389. /**
  390. * @todo NOT implement;
  391. */
  392. return -1;
  393. }
  394. EXPORT_SYMBOL(gpio_out_group_set);
  395. /**
  396. * Multi pin operation
  397. */
  398. /**
  399. * Multi pin operation
  400. * @return 0, success ,
  401. * SOMEPIN IS LOCKED, some pin is locked to the specail feature . You can not change it
  402. * NOTAVAILABLE, not available .
  403. *
  404. */
  405. gpio_set_t * gpio_in_group_cacl(uint32_t pin,uint32_t bits, ... )
  406. {
  407. printk(" %s , NOT IMPLENMENT\n",__func__);
  408. BUG();
  409. /**
  410. * @todo NOT implement;
  411. */
  412. return NULL;
  413. }
  414. EXPORT_SYMBOL(gpio_in_group_cacl);
  415. gpio_in_t gpio_in_group(gpio_in_set_t *grp)
  416. {
  417. printk(" %s , NOT IMPLENMENT\n",__func__);
  418. BUG();
  419. /**
  420. * @todo NOT implement;
  421. */
  422. return 0;
  423. }
  424. EXPORT_SYMBOL(gpio_in_group);
  425. //~ typedef struct gpio_irq_s{
  426. //~ int8_t filter;
  427. //~ uint8_t irq;///
  428. //~ uint16_t pad;
  429. //~ }gpio_irq_t;
  430. static gpio_irq_t gpio_irqs[8]={
  431. };
  432. int32_t gpio_irq_set_lock(int32_t pad, uint32_t irq/*GPIO_IRQ(irq,type)*/,int32_t filter,bool lock)
  433. {
  434. if(pad>=PAD_TEST_N)
  435. return -1;
  436. gpio_irqs[(irq>>2)].irq=irq&3;
  437. gpio_irqs[(irq>>2)].pad=pad;
  438. gpio_irqs[(irq>>2)].filter=filter;
  439. return 0;
  440. }
  441. EXPORT_SYMBOL(gpio_irq_set_lock);
  442. void gpio_irq_enable(uint32_t irq)
  443. {
  444. int idx=(irq>>2)&7;
  445. unsigned reg,start_bit;
  446. unsigned type[]={0x0, ///high
  447. 0x1, ///rising
  448. 0x10000, ///low
  449. 0x10001 ///faling
  450. };
  451. debug("write reg %p clr=%x set=%x",P_GPIO_INTR_EDGE_POL,0x10001<<idx,type[gpio_irqs[idx].irq]<<idx);
  452. /// set trigger type
  453. clrsetbits_le32(P_GPIO_INTR_EDGE_POL,0x10001<<idx,type[gpio_irqs[idx].irq]<<idx);
  454. ///select pad
  455. reg=idx<4?P_GPIO_INTR_GPIO_SEL0:P_GPIO_INTR_GPIO_SEL1;
  456. start_bit=(idx&3)*8;
  457. clrsetbits_le32(reg,0xff<<start_bit,gpio_irqs[idx].pad<<start_bit);
  458. debug("write reg %p clr=%x set=%x",reg,0xff<<start_bit,gpio_irqs[idx].pad<<start_bit);
  459. ///set filter
  460. start_bit=(idx)*4;
  461. clrsetbits_le32(P_GPIO_INTR_FILTER_SEL0,0x7<<start_bit,gpio_irqs[idx].filter<<start_bit);
  462. debug("write reg %p clr=%x set=%x",P_GPIO_INTR_FILTER_SEL0,0x7<<start_bit,gpio_irqs[idx].filter<<start_bit);
  463. }
  464. EXPORT_SYMBOL(gpio_irq_enable);