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