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