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
00033
00061 #include <sys/event.h>
00062 #include <dev/twif.h>
00063 #include <dev/cy2239x.h>
00064
00069
00073 #ifndef I2C_SLA_PLL
00074 #define I2C_SLA_PLL 0x69
00075 #endif
00076
00082 #ifndef NUT_PLL_FREF
00083 #define NUT_PLL_FREF 25000000UL
00084 #endif
00085
00093 static uint32_t PllFreq(uint8_t * reg)
00094 {
00095 uint32_t p;
00096 uint32_t pt;
00097 uint32_t qt;
00098
00099
00100 p = (uint32_t) (reg[2] & 0x03) << 8 | reg[1];
00101
00102 pt = 2 * (p + 3) + ((reg[2] >> 2) & 1);
00103
00104 qt = reg[0] + 2;
00105
00106 return (((NUT_PLL_FREF * 10UL + 5UL) / qt) * pt) / 10UL;
00107 }
00108
00124 int Cy2239xGetPll(int clk)
00125 {
00126 int rc = -1;
00127 uint8_t loc = 0x0E;
00128 uint8_t reg;
00129
00130
00131 if (clk == CY2239X_CLKE) {
00132 rc = 1;
00133 }
00134
00135 else if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, ®, 1, NUT_WAIT_INFINITE) == 1) {
00136 rc = (reg >> (2 * clk)) & 0x03;
00137 }
00138 return rc;
00139 }
00140
00159 int Cy2239xSetPll(int clk, int pll)
00160 {
00161 uint8_t reg[2];
00162 uint8_t msk = 0x03;
00163
00164
00165 if (clk >= CY2239X_CLKE) {
00166 if (pll != CY2239X_PLL1) {
00167 return -1;
00168 }
00169 return 0;
00170 }
00171
00172 if ((pll | msk) == msk) {
00173
00174
00175 reg[0] = 0x0E;
00176 if (TwMasterTransact(I2C_SLA_PLL, reg, 1, ®[1], 1, NUT_WAIT_INFINITE) == 1) {
00177 clk <<= 1;
00178 reg[1] &= ~(msk << clk);
00179 reg[1] |= pll << clk;
00180 TwMasterTransact(I2C_SLA_PLL, reg, 2, 0, 0, NUT_WAIT_INFINITE);
00181 return 0;
00182 }
00183 }
00184 return -1;
00185 }
00186
00199 int Cy2239xGetDivider(int clk, int fctrl)
00200 {
00201 int rc = -1;
00202 int idx;
00203 uint8_t loc;
00204 uint8_t reg;
00205
00206
00207
00208
00209 if (clk == CY2239X_CLKE) {
00210
00211 loc = 0x0F;
00212 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, ®, 1, NUT_WAIT_INFINITE) == 1) {
00213 rc = reg & 3;
00214 if (rc == 1) {
00215 rc = 4;
00216 }
00217 }
00218 }
00219 else {
00220
00221
00222
00223
00224 if (clk <= CY2239X_CLKB) {
00225
00226 loc = 0x42 + fctrl * 3;
00227 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, ®, 1, NUT_WAIT_INFINITE) != 1) {
00228 return -1;
00229 }
00230 idx = clk * 2 + (reg >> 7);
00231 }
00232 else {
00233 idx = clk + 2;
00234 }
00235 loc = 0x08 + idx;
00236 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, ®, 1, NUT_WAIT_INFINITE) == 1) {
00237 rc = reg & 0x7F;
00238 }
00239 }
00240 return rc;
00241 }
00242
00262 int Cy2239xSetDivider(int clk, int sel, int val)
00263 {
00264 uint8_t reg[2];
00265
00266
00267 if (clk == CY2239X_CLKE) {
00268 if (val == 0 || (val >= 2 && val <= 4)) {
00269 if (val == 4) {
00270 val = 1;
00271 }
00272
00273 reg[0] = 0x0F;
00274 if (TwMasterTransact(I2C_SLA_PLL, reg, 1, ®[1], 1, NUT_WAIT_INFINITE) == 1) {
00275 reg[1] &= ~0x03;
00276 reg[1] |= (uint8_t) val;
00277 TwMasterTransact(I2C_SLA_PLL, reg, 2, 0, 0, NUT_WAIT_INFINITE);
00278 return 0;
00279 }
00280 }
00281 return -1;
00282 }
00283
00284 if (val > 0 && val < 128) {
00285
00286 if (clk <= CY2239X_CLKB) {
00287 reg[0] = 0x08 + clk * 2 + sel;
00288 }
00289 else {
00290 reg[0] = 0x08 + clk + 2;
00291 }
00292 if (TwMasterTransact(I2C_SLA_PLL, reg, 1, ®[1], 1, NUT_WAIT_INFINITE) == 1) {
00293 reg[1] &= ~0x7F;
00294 reg[1] |= (uint8_t) val;
00295 TwMasterTransact(I2C_SLA_PLL, reg, 2, 0, 0, NUT_WAIT_INFINITE);
00296 return 0;
00297 }
00298 }
00299 return -1;
00300 }
00301
00328 int Cy2239xPllEnable(int pll, int fctrl, int ena)
00329 {
00330 int rc = -1;
00331 uint8_t reg[2];
00332
00333 if (pll) {
00334 if (pll == CY2239X_PLL1) {
00335
00336 reg[0] = 0x42 + fctrl * 3;
00337 }
00338 else if (pll == CY2239X_PLL2) {
00339 reg[0] = 0x13;
00340 }
00341 else if (pll == CY2239X_PLL3) {
00342 reg[0] = 0x16;
00343 }
00344
00345
00346 if (TwMasterTransact(I2C_SLA_PLL, reg, 1, ®[1], 1, NUT_WAIT_INFINITE) == 1) {
00347 rc = (reg[1] & 0x40) != 0;
00348 if (ena == 1) {
00349 reg[1] |= 0x40;
00350 }
00351 else if (ena == 0) {
00352 reg[1] &= ~0x40;
00353 }
00354 else {
00355 return rc;
00356 }
00357 TwMasterTransact(I2C_SLA_PLL, reg, 2, 0, 0, NUT_WAIT_INFINITE);
00358 }
00359 }
00360 return rc;
00361 }
00362
00383 uint32_t Cy2239xPllGetFreq(int pll, int fctrl)
00384 {
00385 uint32_t rc = NUT_PLL_FREF;
00386 uint8_t loc;
00387 uint8_t reg[3];
00388
00389 if (pll) {
00390 if (pll == CY2239X_PLL1) {
00391
00392 loc = 0x40 + fctrl * 3;
00393 }
00394 else if (pll == CY2239X_PLL2) {
00395 loc = 0x11;
00396 }
00397 else if (pll == CY2239X_PLL3) {
00398 loc = 0x14;
00399 }
00400
00401 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, reg, 3, NUT_WAIT_INFINITE) != 3) {
00402 rc = 0;
00403 }
00404 else {
00405 rc = PllFreq(reg);
00406 }
00407 }
00408 return rc;
00409 }
00410
00440 int Cy2239xPllSetFreq(int pll, int fctrl, unsigned int pval, unsigned int poff, unsigned int qval, unsigned int fval)
00441 {
00442 uint8_t reg[4];
00443 int ena;
00444
00445 if (pll) {
00446
00447 if (pll == CY2239X_PLL1) {
00448 reg[0] = 0x40 + fctrl * 3;
00449 }
00450 else if (pll == CY2239X_PLL2) {
00451 reg[0] = 0x11;
00452 }
00453 else if (pll == CY2239X_PLL3) {
00454 reg[0] = 0x14;
00455 }
00456
00457
00458 if (TwMasterTransact(I2C_SLA_PLL, reg, 1, ®[1], 3, NUT_WAIT_INFINITE) == 3) {
00459
00460
00461 if ((ena = Cy2239xPllEnable(pll, fctrl, 0)) >= 0) {
00462 reg[1] = (uint8_t) qval;
00463 reg[2] = (uint8_t) pval;
00464 reg[3] &= 0x80;
00465 reg[3] |= (uint8_t)(pval >> 8) & 0x03;
00466 reg[3] |= (poff & 1) << 2;
00467 reg[3] |= (fval & 7) << 3;
00468 TwMasterTransact(I2C_SLA_PLL, reg, 4, 0, 0, NUT_WAIT_INFINITE);
00469 Cy2239xPllEnable(pll, fctrl, ena);
00470 }
00471 return 0;
00472 }
00473 }
00474 return -1;
00475 }
00476
00506 uint32_t Cy2239xGetFreq(int clk, int fctrl)
00507 {
00508 uint32_t rc;
00509 uint32_t d;
00510 uint8_t loc;
00511 uint8_t reg;
00512 uint8_t clk_reg[8];
00513 uint8_t pll_reg[3];
00514 int pll;
00515
00516
00517 loc = 0x08;
00518 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, clk_reg, 8, NUT_WAIT_INFINITE) != 8) {
00519 return 0;
00520 }
00521
00522
00523
00524
00525
00526
00527 if (clk == CY2239X_CLKE) {
00528
00529 pll = CY2239X_PLL1;
00530 } else {
00531
00532 pll = (clk_reg[6] >> (2 * clk)) & 0x03;
00533 }
00534
00535
00536
00537
00538 if (pll == CY2239X_REF) {
00539
00540 rc = NUT_PLL_FREF;
00541 } else {
00542 if (pll == CY2239X_PLL1) {
00543
00544 loc = 0x40 + fctrl * 3;
00545 }
00546 else if (pll == CY2239X_PLL2) {
00547 loc = 0x11;
00548 }
00549 else if (pll == CY2239X_PLL3) {
00550 loc = 0x14;
00551 }
00552
00553 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, pll_reg, 3, NUT_WAIT_INFINITE) != 3) {
00554 return 0;
00555 }
00556 rc = PllFreq(pll_reg);
00557 }
00558
00559
00560
00561
00562
00563 if (clk <= CY2239X_CLKB) {
00564
00565
00566 if (pll == CY2239X_PLL1) {
00567
00568 reg = pll_reg[2];
00569 }
00570 else {
00571
00572 loc = 0x42 + fctrl * 3;
00573 if (TwMasterTransact(I2C_SLA_PLL, &loc, 1, ®, 1, NUT_WAIT_INFINITE) != 1) {
00574 return 0;
00575 }
00576 }
00577 d = clk_reg[clk * 2 + (reg >> 7)] & 0x7F;
00578 }
00579 else if (clk == CY2239X_CLKE) {
00580
00581 d = clk_reg[7] & 3;
00582 if (d == 1) {
00583 d = 4;
00584 }
00585 }
00586 else {
00587
00588 d = clk_reg[clk + 2] & 0x7F;
00589 }
00590
00591
00592
00593
00594
00595 if (d) {
00596 rc /= d;
00597 } else {
00598 rc = 0;
00599 }
00600 return rc;
00601 }
00602