Go to the documentation of this file.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
00070 #include <cfg/clock.h>
00071
00072 #include <sys/event.h>
00073
00074 #include <dev/twif.h>
00075 #include <dev/npl.h>
00076 #include <dev/mmcard.h>
00077 #include <dev/cy2239x.h>
00078 #include <dev/nplmmc.h>
00079
00080 #if !defined(NPL_MMC_CLOCK) || (NPL_MMC_CLOCK < 1000)
00081 #undef NPL_MMC_CLOCK
00082 #define NPL_MMC_CLOCK 12500000
00083 #endif
00084
00085 #if 0
00086
00087 #define NUTDEBUG
00088 #include <stdio.h>
00089 #endif
00090
00095
00096 #ifndef I2C_SLA_PLL
00097 #define I2C_SLA_PLL 0x69
00098 #endif
00099
00103 typedef struct _MMCDCB {
00104 int dcb_avail;
00105 int dcb_changed;
00106 } MMCDCB;
00107
00108 static MMCDCB mmc0_dcb;
00109
00115 static int NplMmCard0Init(void)
00116 {
00117 mmc0_dcb.dcb_changed = 0;
00118 if (mmc0_dcb.dcb_avail) {
00119 return 0;
00120 }
00121 return -1;
00122 }
00123
00132 static int NplMmCard0Select(int on)
00133 {
00134 int rc = (inb(NPL_XER) & NPL_MMCS) == NPL_MMCS;
00135
00136 if (on == 1) {
00138 outb(NPL_XER, inb(NPL_XER) & ~NPL_MMCS);
00139 } else if (on == 0) {
00141 outb(NPL_XER, inb(NPL_XER) | NPL_MMCS);
00142 }
00143 return rc;
00144 }
00145
00153 static uint8_t NplMmCard0Io(uint8_t val)
00154 {
00155 uint8_t rc;
00156 unsigned int tmo = 255;
00157
00158 while ((inb(NPL_SLR) & NPL_MMCREADY) == 0) {
00159 if (--tmo == 0) {
00160 break;
00161 }
00162 }
00163
00164 _NOP(); _NOP(); _NOP(); _NOP();
00165 rc = inb(NPL_MMCDR);
00166 _NOP(); _NOP(); _NOP(); _NOP();
00167 outb(NPL_MMCDR, val);
00168 _NOP(); _NOP(); _NOP(); _NOP();
00169
00170 #ifdef NUTDEBUG
00171 putchar('[');
00172 if (rc != 0xFF) {
00173 printf("r%02X", rc);
00174 } else if (val != 0xFF) {
00175 printf("s%02X", val);
00176 }
00177 putchar(']');
00178 #endif
00179
00180 return rc;
00181 }
00182
00193 int NplMmCard0Avail(void)
00194 {
00195 if (mmc0_dcb.dcb_avail) {
00196 if (mmc0_dcb.dcb_changed) {
00197 return 2;
00198 }
00199 return 1;
00200 }
00201 return 0;
00202 }
00203
00211 int NplMmCard0WrProt(void)
00212 {
00213 return 0;
00214 }
00215
00223 static void NplMmCard0InsIrq(void *arg)
00224 {
00225 NplIrqDisable(&sig_MMCD);
00226 mmc0_dcb.dcb_avail = 1;
00227 mmc0_dcb.dcb_changed = 1;
00228 NplIrqEnable(&sig_NMMCD);
00229 }
00230
00238 static void NplMmCard0RemIrq(void *arg)
00239 {
00240 NplIrqDisable(&sig_NMMCD);
00241 mmc0_dcb.dcb_avail = 0;
00242 NplIrqEnable(&sig_MMCD);
00243 }
00244
00257 static int NplMmcIfcInit(NUTDEVICE * dev)
00258 {
00259 int rc;
00260
00261
00262 NplMmCard0Select(0);
00263
00264 #if defined(NUT_PLL_NPLCLK1)
00265 {
00266 uint32_t val;
00267
00268
00269 val = Cy2239xGetPll(NUT_PLL_NPLCLK1);
00270
00271 val = Cy2239xPllGetFreq((int)val, 7);
00272
00273 val = (val + NPL_MMC_CLOCK - 10) / NPL_MMC_CLOCK;
00274
00275
00276
00277
00278
00279 if (Cy2239xSetDivider(NUT_PLL_NPLCLK1, 1, (int)val)) {
00280 return -1;
00281 }
00282 if (Cy2239xSetDivider(NUT_PLL_NPLCLK1, 0, (int)val)) {
00283 return -1;
00284 }
00285 }
00286 #endif
00287
00288
00289 inb(NPL_MMCDR);
00290 outb(NPL_MMCDR, 0xFF);
00291
00292
00293 if ((rc = NplRegisterIrqHandler(&sig_MMCD, NplMmCard0InsIrq, 0)) == 0) {
00294 rc = NplRegisterIrqHandler(&sig_NMMCD, NplMmCard0RemIrq, 0);
00295 }
00296 NplIrqEnable(&sig_MMCD);
00297
00298 return MmCardDevInit(dev);
00299 }
00300
00301 static MMCIFC mmc0_ifc = {
00302 NplMmCard0Init,
00303 NplMmCard0Io,
00304 NplMmCard0Select,
00305 NplMmCard0Avail,
00306 NplMmCard0WrProt
00307 };
00308
00321 NUTDEVICE devNplMmc0 = {
00322 0,
00323 {'M', 'M', 'C', '0', 0, 0, 0, 0, 0}
00324 ,
00325 0,
00326 0,
00327 0,
00328 &mmc0_ifc,
00329 &mmc0_dcb,
00330 NplMmcIfcInit,
00331 MmCardIOCtl,
00332 MmCardBlockRead,
00333 MmCardBlockWrite,
00334 #ifdef __HARVARD_ARCH__
00335 MmCardBlockWrite_P,
00336 #endif
00337 MmCardMount,
00338 MmCardUnmount,
00339 0
00340 };
00341