00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00063 #include <cfg/clock.h>
00064
00065 #include <sys/event.h>
00066
00067 #include <dev/twif.h>
00068 #include <dev/npl.h>
00069 #include <dev/mmcard.h>
00070 #include <dev/cy2239x.h>
00071 #include <dev/nplmmc.h>
00072
00073 #if !defined(NPL_MMC_CLOCK) || (NPL_MMC_CLOCK < 1000)
00074 #undef NPL_MMC_CLOCK
00075 #define NPL_MMC_CLOCK 12500000
00076 #endif
00077
00078 #if 0
00079
00080 #define NUTDEBUG
00081 #include <stdio.h>
00082 #endif
00083
00088
00089 #ifndef I2C_SLA_PLL
00090 #define I2C_SLA_PLL 0x69
00091 #endif
00092
00096 typedef struct _MMCDCB {
00097 int dcb_avail;
00098 int dcb_changed;
00099 } MMCDCB;
00100
00101 static MMCDCB mmc0_dcb;
00102
00108 static int NplMmCard0Init(void)
00109 {
00110 mmc0_dcb.dcb_changed = 0;
00111 if (mmc0_dcb.dcb_avail) {
00112 return 0;
00113 }
00114 return -1;
00115 }
00116
00125 static int NplMmCard0Select(int on)
00126 {
00127 int rc = (inb(NPL_XER) & NPL_MMCS) == NPL_MMCS;
00128
00129 if (on == 1) {
00131 outb(NPL_XER, inb(NPL_XER) & ~NPL_MMCS);
00132 } else if (on == 0) {
00134 outb(NPL_XER, inb(NPL_XER) | NPL_MMCS);
00135 }
00136 return rc;
00137 }
00138
00146 static u_char NplMmCard0Io(u_char val)
00147 {
00148 u_char rc;
00149 u_int tmo = 255;
00150
00151 while ((inb(NPL_SLR) & NPL_MMCREADY) == 0) {
00152 if (--tmo == 0) {
00153 break;
00154 }
00155 }
00156
00157 _NOP(); _NOP(); _NOP(); _NOP();
00158 rc = inb(NPL_MMCDR);
00159 _NOP(); _NOP(); _NOP(); _NOP();
00160 outb(NPL_MMCDR, val);
00161 _NOP(); _NOP(); _NOP(); _NOP();
00162
00163 #ifdef NUTDEBUG
00164 putchar('[');
00165 if (rc != 0xFF) {
00166 printf("r%02X", rc);
00167 } else if (val != 0xFF) {
00168 printf("s%02X", val);
00169 }
00170 putchar(']');
00171 #endif
00172
00173 return rc;
00174 }
00175
00186 int NplMmCard0Avail(void)
00187 {
00188 if (mmc0_dcb.dcb_avail) {
00189 if (mmc0_dcb.dcb_changed) {
00190 return 2;
00191 }
00192 return 1;
00193 }
00194 return 0;
00195 }
00196
00204 int NplMmCard0WrProt(void)
00205 {
00206 return 0;
00207 }
00208
00216 static void NplMmCard0InsIrq(void *arg)
00217 {
00218 NplIrqDisable(&sig_MMCD);
00219 mmc0_dcb.dcb_avail = 1;
00220 mmc0_dcb.dcb_changed = 1;
00221 NplIrqEnable(&sig_NMMCD);
00222 }
00223
00231 static void NplMmCard0RemIrq(void *arg)
00232 {
00233 NplIrqDisable(&sig_NMMCD);
00234 mmc0_dcb.dcb_avail = 0;
00235 NplIrqEnable(&sig_MMCD);
00236 }
00237
00250 static int NplMmcIfcInit(NUTDEVICE * dev)
00251 {
00252 int rc;
00253
00254
00255 NplMmCard0Select(0);
00256
00257 #if defined(NUT_PLL_NPLCLK1)
00258 {
00259 u_long val;
00260
00261
00262 val = Cy2239xGetPll(NUT_PLL_NPLCLK1);
00263
00264 val = Cy2239xPllGetFreq((int)val, 7);
00265
00266 val = (val + NPL_MMC_CLOCK - 10) / NPL_MMC_CLOCK;
00267
00268
00269
00270
00271
00272 if (Cy2239xSetDivider(NUT_PLL_NPLCLK1, 1, (int)val)) {
00273 return -1;
00274 }
00275 if (Cy2239xSetDivider(NUT_PLL_NPLCLK1, 0, (int)val)) {
00276 return -1;
00277 }
00278 }
00279 #endif
00280
00281
00282 inb(NPL_MMCDR);
00283 outb(NPL_MMCDR, 0xFF);
00284
00285
00286 if ((rc = NplRegisterIrqHandler(&sig_MMCD, NplMmCard0InsIrq, 0)) == 0) {
00287 rc = NplRegisterIrqHandler(&sig_NMMCD, NplMmCard0RemIrq, 0);
00288 }
00289 NplIrqEnable(&sig_MMCD);
00290
00291 return MmCardDevInit(dev);
00292 }
00293
00294 static MMCIFC mmc0_ifc = {
00295 NplMmCard0Init,
00296 NplMmCard0Io,
00297 NplMmCard0Select,
00298 NplMmCard0Avail,
00299 NplMmCard0WrProt
00300 };
00301
00314 NUTDEVICE devNplMmc0 = {
00315 0,
00316 {'M', 'M', 'C', '0', 0, 0, 0, 0, 0}
00317 ,
00318 0,
00319 0,
00320 0,
00321 &mmc0_ifc,
00322 &mmc0_dcb,
00323 NplMmcIfcInit,
00324 MmCardIOCtl,
00325 MmCardBlockRead,
00326 MmCardBlockWrite,
00327 #ifdef __HARVARD_ARCH__
00328 MmCardBlockWrite_P,
00329 #endif
00330 MmCardMount,
00331 MmCardUnmount,
00332 0
00333 };
00334