cf-enabler.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: cf-enabler.c,v 1.8 2001/07/18 12:32:21 gniibe Exp $
  2.  *
  3.  *  linux/drivers/block/cf-enabler.c
  4.  *
  5.  *  Copyright (C) 1999  Niibe Yutaka
  6.  *  Copyright (C) 2000  Toshiharu Nozawa
  7.  *  Copyright (C) 2001  A&D Co., Ltd.
  8.  *
  9.  *  Enable the CF configuration.
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/init.h>
  13. #include <asm/io.h>
  14. #include <asm/irq.h>
  15. /*
  16.  * You can connect Compact Flash directly to the bus of SuperH.
  17.  * This is the enabler for that.
  18.  *
  19.  * SIM: How generic is this really? It looks pretty board, or at
  20.  * least SH sub-type, specific to me.
  21.  * I know it doesn't work on the Overdrive!
  22.  */
  23. /*
  24.  * 0xB8000000 : Attribute
  25.  * 0xB8001000 : Common Memory
  26.  * 0xBA000000 : I/O
  27.  */
  28. #if defined(CONFIG_IDE) && defined(__SH4__)
  29. /* SH4 can't access PCMCIA interface through P2 area.
  30.  * we must remap it with appropreate attribute bit of the page set.
  31.  * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
  32. #include <linux/mm.h>
  33. #include <linux/vmalloc.h>
  34. #if defined(CONFIG_CF_AREA6)
  35. #define slot_no 0
  36. #else
  37. #define slot_no 1
  38. #endif
  39. /* defined in mm/ioremap.c */
  40. extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
  41. /* use this pointer to access to directly connected compact flash io area*/
  42. void *cf_io_base;
  43. static int __init allocate_cf_area(void)
  44. {
  45. pgprot_t prot;
  46. unsigned long paddrbase, psize;
  47. /* open I/O area window */
  48. paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
  49. psize = PAGE_SIZE;
  50. prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
  51. cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
  52. if (!cf_io_base) {
  53. printk("allocate_cf_area : can't open CF I/O window!n");
  54. return -ENOMEM;
  55. }
  56. /* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lxn",
  57.      paddrbase, psize, prot.pgprot, cf_io_base);*/
  58. /* XXX : do we need attribute and common-memory area also? */
  59. return 0;
  60. }
  61. #endif
  62. static int __init cf_init_default(void)
  63. {
  64. /* You must have enabled the card, and set the level interrupt
  65.  * before reaching this point. Possibly in boot ROM or boot loader.
  66.  */
  67. #if defined(CONFIG_IDE) && defined(__SH4__)
  68. allocate_cf_area();
  69. #endif
  70. #if defined(CONFIG_SH_UNKNOWN)
  71. /* This should be done in each board's init_xxx_irq. */
  72. make_imask_irq(14);
  73. disable_irq(14);
  74. #endif
  75. return 0;
  76. }
  77. #if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE)
  78. #include <asm/hitachi_se.h>
  79. /*
  80.  * SolutionEngine
  81.  *
  82.  * 0xB8400000 : Common Memory
  83.  * 0xB8500000 : Attribute
  84.  * 0xB8600000 : I/O
  85.  */
  86. static int __init cf_init_se(void)
  87. {
  88. if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
  89. return 0; /* Not detected */
  90. if ((ctrl_inw(MRSHPC_CSR) & 0x0080) == 0) {
  91. ctrl_outw(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
  92. } else {
  93. ctrl_outw(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
  94. }
  95. /*
  96.  *  PC-Card window open 
  97.  *  flag == COMMON/ATTRIBUTE/IO
  98.  */
  99. /* common window open */
  100. ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */
  101. if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
  102. /* common mode & bus width 16bit SWAP = 1*/
  103. ctrl_outw(0x0b00, MRSHPC_MW0CR2);
  104. else
  105. /* common mode & bus width 16bit SWAP = 0*/
  106. ctrl_outw(0x0300, MRSHPC_MW0CR2); 
  107. /* attribute window open */
  108. ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */
  109. if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
  110. /* attribute mode & bus width 16bit SWAP = 1*/
  111. ctrl_outw(0x0a00, MRSHPC_MW1CR2);
  112. else
  113. /* attribute mode & bus width 16bit SWAP = 0*/
  114. ctrl_outw(0x0200, MRSHPC_MW1CR2);
  115. /* I/O window open */
  116. ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */
  117. ctrl_outw(0x0008, MRSHPC_CDCR);  /* I/O card mode */
  118. if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
  119. ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
  120. else
  121. ctrl_outw(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
  122. ctrl_outw(0x2000, MRSHPC_ICR);
  123. ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
  124. ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
  125. return 0;
  126. }
  127. #endif
  128. int __init cf_init(void)
  129. {
  130. #if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE)
  131. if (MACH_SE)
  132. return cf_init_se();
  133. #endif
  134. return cf_init_default();
  135. }
  136. __initcall (cf_init);