cs2100-cp.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. /****************************************************************************
  2. * drivers/timers/cs2100-cp.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <sys/types.h>
  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <assert.h>
  28. #include <errno.h>
  29. #include <debug.h>
  30. #include <nuttx/i2c/i2c_master.h>
  31. #include <nuttx/timers/cs2100-cp.h>
  32. #ifdef CONFIG_TIMERS_CS2100CP
  33. /****************************************************************************
  34. * Pre-processor Definitions
  35. ****************************************************************************/
  36. /* Driver Definitions *******************************************************/
  37. #define MAX_REFCLK_FREQ 75000000
  38. #define MAX_REFCLK_XTAL 50000000
  39. #define MAX_SYSCLK 18750000
  40. #define MAX_SKIP_FREQ 80000000
  41. /* Debug ********************************************************************/
  42. #undef cserr
  43. #ifdef CONFIG_CS2100CP_DEBUG
  44. # define cserr _err
  45. #else
  46. # define cserr _none
  47. #endif
  48. #undef reginfo
  49. #ifdef CONFIG_CS2100CP_REGDEBUG
  50. # define reginfo _err
  51. #else
  52. # define reginfo _none
  53. #endif
  54. /****************************************************************************
  55. * Private Functions
  56. ****************************************************************************/
  57. /****************************************************************************
  58. * Name: cs2100_write_reg
  59. *
  60. * Description:
  61. * Write an 8 bit value to a CS2100 8-bit register.
  62. *
  63. * Input Parameters:
  64. * config - CS2100-CP configuration
  65. * regaddr - CS2100 register address
  66. * regval - CS2100 register value to write
  67. *
  68. * Returned Value:
  69. * Zero (OK) on success; a negated errno value on failure.
  70. *
  71. ****************************************************************************/
  72. static int cs2100_write_reg(FAR const struct cs2100_config_s *config,
  73. uint8_t regaddr, uint8_t regval)
  74. {
  75. struct i2c_msg_s msgs[2];
  76. int ret;
  77. reginfo("%02x<-%02x\n", regaddr, regval);
  78. DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);
  79. /* Construct the I2C message (write N+1 bytes with no restart) */
  80. msga[0].frequency = config->i2cfreq;
  81. msgs[0].addr = config->i2caddr;
  82. msgs[0].flags = 0;
  83. msgs[0].buffer = &regaddr;
  84. msgs[0].length = 1;
  85. msga[1].frequency = config->i2cfreq;
  86. msgs[1].addr = config->i2caddr;
  87. msgs[1].flags = I2C_M_NOSTART;
  88. msgs[1].buffer = &regval;
  89. msgs[1].length = 1;
  90. /* Send the message */
  91. ret = I2C_TRANSFER(config->i2c, msgs, 2);
  92. return (ret >= 0) ? OK : ret;
  93. }
  94. /****************************************************************************
  95. * Name: cs2100_read_reg
  96. *
  97. * Description:
  98. * Read an 8 bit value from a CS2100 8-bit register.
  99. *
  100. * Input Parameters:
  101. * config - CS2100-CP configuration
  102. * regaddr - CS2100 register address
  103. * regval - Location to return the CS2100 register value
  104. *
  105. * Returned Value:
  106. * Zero (OK) on success; a negated errno value on failure.
  107. *
  108. ****************************************************************************/
  109. #ifdef CONFIG_CS2100CP_DEBUG
  110. static int cs2100_read_reg(FAR const struct cs2100_config_s *config,
  111. uint8_t regaddr, uint8_t *regval)
  112. {
  113. struct i2c_msg_s msg;
  114. int ret;
  115. DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);
  116. /* Construct the I2C message (write 1 bytes, restart, read N bytes) */
  117. msg.frequency = config->i2cfreq;
  118. msg.addr = config->i2caddr;
  119. msg.flags = 0;
  120. msg.buffer = &regaddr;
  121. msg.length = 1;
  122. /* Send the address followed by a STOP */
  123. ret = I2C_TRANSFER(config->i2c, &msg, 1);
  124. if (ret >= 0)
  125. {
  126. msg.frequency = config->i2cfreq;
  127. msg.addr = config->i2caddr;
  128. msg.flags = I2C_M_READ;
  129. msg.buffer = regval;
  130. msg.length = 1;
  131. /* Read the register beginning with another START */
  132. ret = I2C_TRANSFER(config->i2c, &msg, 1);
  133. if (ret >= 0)
  134. {
  135. reginfo("%02x->%02x\n", regaddr, *regval);
  136. }
  137. }
  138. return (ret >= 0) ? OK : ret;
  139. }
  140. #endif
  141. /****************************************************************************
  142. * Name: cs2100_write_reg
  143. *
  144. * Description:
  145. * Write the 32-bit ratio value to CS2100 Ratio registers.
  146. *
  147. * Input Parameters:
  148. * config - CS2100-CP configuration
  149. * ratio - CS2100 ratio value to write
  150. *
  151. * Returned Value:
  152. * Zero (OK) on success; a negated errno value on failure.
  153. *
  154. ****************************************************************************/
  155. static int cs2100_write_ratio(FAR const struct cs2100_config_s *config,
  156. uint32_t ratio)
  157. {
  158. struct i2c_msg_s msg;
  159. uint8_t buffer[5];
  160. int ret;
  161. reginfo("%02x<-%04l\n", CS2100_RATIO0, (unsigned long)ratio);
  162. DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);
  163. /* Construct the I2C message (write N+1 bytes with no restart) */
  164. buffer[0] = CS2100_RATIO0;
  165. buffer[1] = (uint8_t)(ratio >> 24);
  166. buffer[2] = (uint8_t)((ratio >> 16) & 0xff);
  167. buffer[3] = (uint8_t)((ratio >> 8) & 0xff);
  168. buffer[4] = (uint8_t)(ratio & 0xff);
  169. msg.frequency = config->i2cfreq;
  170. msg.addr = config->i2caddr;
  171. msg.flags = 0;
  172. msg.buffer = buffer;
  173. msg.length = 5;
  174. /* Send the message */
  175. ret = I2C_TRANSFER(config->i2c, &msg, 1);
  176. return (ret >= 0) ? OK : ret;
  177. }
  178. /****************************************************************************
  179. * Name: cs2100_read_ratio
  180. *
  181. * Description:
  182. * Read the 32-bit ratio value from the CS2100 Ratio registers.
  183. *
  184. * Input Parameters:
  185. * config - CS2100-CP configuration
  186. * ratio - Location to return the CS2100 ratio
  187. *
  188. * Returned Value:
  189. * Zero (OK) on success; a negated errno value on failure.
  190. *
  191. ****************************************************************************/
  192. #ifdef CONFIG_CS2100CP_DEBUG
  193. static int cs2100_read_ratio(FAR const struct cs2100_config_s *config,
  194. uint32_t *ratio)
  195. {
  196. struct i2c_msg_s msg;
  197. uint8_t buffer[4];
  198. int ret;
  199. DEBUGASSERT(config->i2c->ops && config->i2c->ops->transfer);
  200. /* Construct the I2C message (write N+1 bytes with no restart) */
  201. buffer[0] = CS2100_RATIO0;
  202. msg.frequency = config->i2cfreq;
  203. msg.addr = config->i2caddr;
  204. msg.flags = 0;
  205. msg.buffer = buffer;
  206. msg.length = 1;
  207. /* Send the address followed by a STOP */
  208. ret = I2C_TRANSFER(config->i2c, &msg, 1);
  209. if (ret >= 0)
  210. {
  211. msg.frequency = config->i2cfreq;
  212. msg.addr = config->i2caddr;
  213. msg.flags = I2C_M_READ;
  214. msg.buffer = buffer;
  215. msg.length = 4;
  216. /* Read the ratio registers beginning with another START */
  217. ret = I2C_TRANSFER(config->i2c, &msg, 1);
  218. /* Return the ratio */
  219. if (ret >= 0)
  220. {
  221. *ratio = ((uint32_t)buffer[0] << 24) |
  222. ((uint32_t)buffer[1] << 16) |
  223. ((uint32_t)buffer[2] << 8) |
  224. (uint32_t)buffer[0];
  225. reginfo("%02x->%04l\n", CS2100_RATIO0, (unsigned long)*ratio);
  226. }
  227. }
  228. return (ret >= 0) ? OK : ret;
  229. }
  230. #endif
  231. /****************************************************************************
  232. * Name: cs2100_refclk
  233. *
  234. * Description:
  235. * Set the reference clock divider value.
  236. *
  237. * Input Parameters:
  238. * config - CS2100-CP configuration
  239. *
  240. * Returned Value:
  241. * Zero (OK) on success; a negated errno value on failure.
  242. *
  243. ****************************************************************************/
  244. static int cs2100_refclk(FAR const struct cs2100_config_s *config)
  245. {
  246. uint8_t regval;
  247. int ret;
  248. DEBUGASSERT((config->xtal && config->refclk <= MAX_REFCLK_XTAL) ||
  249. (!config->xtal && config->refclk <= MAX_REFCLK_FREQ));
  250. /* Calculate and set the RefClk the divider */
  251. if (config->refclk <= MAX_SYSCLK)
  252. {
  253. regval = CS2100_FNCCFG1_REFCLKDIV_NONE;
  254. }
  255. else if (config->refclk <= (MAX_SYSCLK / 2))
  256. {
  257. regval = CS2100_FNCCFG1_REFCLKDIV_DIV2;
  258. }
  259. else if (config->refclk <= (MAX_SYSCLK / 4))
  260. {
  261. regval = CS2100_FNCCFG1_REFCLKDIV_DIV4;
  262. }
  263. else
  264. {
  265. cserr("ERROR: reflck too large: %ul\n", (unsigned long)config->refclk);
  266. return -EINVAL;
  267. }
  268. /* Enable CLK_IN skipping mode? */
  269. if (config->refclk <= MAX_SKIP_FREQ)
  270. {
  271. regval |= CS2100_FNCCFG1_CLKSKIPEN;
  272. }
  273. ret = cs2100_write_reg(config, CS2100_FNCCFG1, regval);
  274. if (ret < 0)
  275. {
  276. cserr("ERROR: Failed to set CS2100_FNCCFG1: %d\n", ret);
  277. return ret;
  278. }
  279. /* Set the minimum loop bandwidth */
  280. DEBUGASSERT(config->loopbw >= 1 && config->loopbw <= 128);
  281. if (config->loopbw < 2)
  282. {
  283. regval = CS2100_FNCCFG3_CLKINBW_1HZ;
  284. }
  285. else if (config->loopbw < 3)
  286. {
  287. regval = CS2100_FNCCFG3_CLKINBW_2HZ;
  288. }
  289. else if (config->loopbw < 6)
  290. {
  291. regval = CS2100_FNCCFG3_CLKINBW_4HZ;
  292. }
  293. else if (config->loopbw < 12)
  294. {
  295. regval = CS2100_FNCCFG3_CLKINBW_8HZ;
  296. }
  297. else if (config->loopbw < 24)
  298. {
  299. regval = CS2100_FNCCFG3_CLKINBW_16HZ;
  300. }
  301. else if (config->loopbw < 48)
  302. {
  303. regval = CS2100_FNCCFG3_CLKINBW_32HZ;
  304. }
  305. else if (config->loopbw < 96)
  306. {
  307. regval = CS2100_FNCCFG3_CLKINBW_64HZ;
  308. }
  309. else /* if (config->loopbw <= 128) */
  310. {
  311. regval = CS2100_FNCCFG3_CLKINBW_128HZ;
  312. }
  313. ret = cs2100_write_reg(config, CS2100_FNCCFG3, regval);
  314. if (ret < 0)
  315. {
  316. cserr("ERROR: Failed to set CS2100_FNCCFG3: %d\n", ret);
  317. return ret;
  318. }
  319. /* Configure so that CLK_OUT will be enabled when the registers are
  320. * unlocked (also clears other settings).
  321. * NOTE: This implicitly sets High Multiplier mode for the Rud.
  322. */
  323. ret = cs2100_write_reg(config, CS2100_FNCCFG2, CS2100_FNCCFG2_CLKOUTUNL);
  324. if (ret < 0)
  325. {
  326. cserr("ERROR: Failed to set CS2100_FNCCFG2: %d\n", ret);
  327. }
  328. return ret;
  329. }
  330. /****************************************************************************
  331. * Name: cs2100_ratio
  332. *
  333. * Description:
  334. * Calculate the effective input-to-output ratio
  335. *
  336. * Input Parameters:
  337. * config - CS2100-CP configuration
  338. *
  339. * Returned Value:
  340. * Zero (OK) on success; a negated errno value on failure.
  341. *
  342. ****************************************************************************/
  343. static int cs2100_ratio(FAR const struct cs2100_config_s *config)
  344. {
  345. uint64_t rudb24;
  346. uint32_t rud;
  347. uint8_t regval;
  348. bool highmul;
  349. int rmod;
  350. int ret;
  351. DEBUGASSERT(config->clkin > 0 && config->clkout > 0);
  352. /* Calculate a 64-bit RUD value:
  353. *
  354. * R-Mod * clkout / clkin
  355. *
  356. * Initial calculation has 24-bits of accuracy (b24)
  357. */
  358. rudb24 = ((uint64_t)config->clkout << 24) / config->clkin;
  359. /* If the b23 rudb24 is less than (1 << 39), then it can be represented as
  360. * a high-precision (b20) value.
  361. */
  362. if (rudb24 < (1ull << (32 + 7)))
  363. {
  364. highmul = false;
  365. /* Brute force! */
  366. if (rudb24 >= (1ull << (32 + 6)))
  367. {
  368. rud = (uint32_t)rudb24 >> 7; /* RUD = RUDb20 / 8 */
  369. rmod = 3; /* Reff = 8 * RUD */
  370. }
  371. else if (rudb24 >= (1ull << (32 + 5)))
  372. {
  373. rud = (uint32_t)rudb24 >> 6; /* RUD = RUDb20 / 4 */
  374. rmod = 3; /* Reff = 4 * RUD */
  375. }
  376. else if (rudb24 >= (1ull << (32 + 4)))
  377. {
  378. rud = (uint32_t)rudb24 >> 5; /* RUD = RUDb20 / 2 */
  379. rmod = 1; /* Reff = 2 * RUD */
  380. }
  381. else if (rudb24 >= (1ull << (32 + 3)))
  382. {
  383. rud = (uint32_t)rudb24 >> 4; /* RUD = RUDb20 */
  384. rmod = 0; /* Reff = RUD */
  385. }
  386. else if (rudb24 >= (1ull << (32 + 2)))
  387. {
  388. rud = (uint32_t)rudb24 >> 3; /* RUD -> 2*RUDb20 */
  389. rmod = 4; /* Reff = RUD / 2 */
  390. }
  391. else if (rudb24 >= (1ull << (32 + 1)))
  392. {
  393. rud = (uint32_t)rudb24 >> 2; /* RUD -> 4*RUDb20 */
  394. rmod = 5; /* Reff = RUD / 4 */
  395. }
  396. else if (rudb24 >= (1ull << 32))
  397. {
  398. rud = (uint32_t)rudb24 >> 1; /* RUD -> 8*RUDb20 */
  399. rmod = 6; /* Reff = RUD / 8 */
  400. }
  401. else
  402. {
  403. rud = (uint32_t)rudb24; /* RUD -> 16*RUDb20 */
  404. rmod = 7; /* Reff = RUD / 16 */
  405. }
  406. }
  407. /* If the b23 rudb24 is less than (1 << 47), then it can be represented as
  408. * a high-multiplication (b12) value.
  409. */
  410. else if (rudb24 < (1ull << (32 + 12)))
  411. {
  412. highmul = true;
  413. if (rudb24 >= (1ull << (32 + 11)))
  414. {
  415. rud = (uint32_t)rudb24 >> 12; /* RUD = RUDb12 */
  416. rmod = 0; /* Reff = RUD */
  417. }
  418. else if (rudb24 >= (1ull << (32 + 10)))
  419. {
  420. rud = (uint32_t)rudb24 >> 11; /* RUD = 2*RUDb12 */
  421. rmod = 4; /* Reff = RUD / 2 */
  422. }
  423. else if (rudb24 >= (1ull << (32 + 9)))
  424. {
  425. rud = (uint32_t)rudb24 >> 10; /* RUD = 4*RUDb12 */
  426. rmod = 5; /* Reff = RUD / 4 */
  427. }
  428. else if (rudb24 >= (1ull << (32 + 8)))
  429. {
  430. rud = (uint32_t)rudb24 >> 9; /* RUD = 8*RUDb12 */
  431. rmod = 6; /* Reff = RUD / 8 */
  432. }
  433. else /* if (rudb24 >= (1ull << (32 + 7))) */
  434. {
  435. rud = (uint32_t)rudb24 >> 8; /* RUD = 16*RUDb12 */
  436. rmod = 7; /* Reff = RUD / 16 */
  437. }
  438. }
  439. else
  440. {
  441. cserr("ERROR: Ratio too large: %08llx\n", rudb24);
  442. return -E2BIG;
  443. }
  444. /* Save the ratio */
  445. ret = cs2100_write_ratio(config, rud);
  446. if (ret < 0)
  447. {
  448. cserr("ERROR: Failed to set ratio: %d\n", ret);
  449. return ret;
  450. }
  451. /* Save the R-Mod value and EnDevCfg1. The device won't be fully enabled
  452. * until EnDevCfg2 is setand registers are unfrozen and unlocked.
  453. * REVISIT: Also sets AuxOutSrc to RefClk.
  454. */
  455. regval = (rmod << CS2100_DEVCFG1_RMODSEL_SHIFT) | CS2100_DEVCFG1_ENDEVCFG1;
  456. ret = cs2100_write_reg(config, CS2100_DEVCFG1, regval);
  457. if (ret < 0)
  458. {
  459. cserr("ERROR: Failed to set CS2100_DEVCFG1: %d\n", ret);
  460. return ret;
  461. }
  462. /* Set High Resolution mode if needed. NOTE: this depends on the fact
  463. * that High Multiplier mode was previously selected.
  464. */
  465. if (!highmul)
  466. {
  467. /* Preserve the ClkOutUnl bit */
  468. regval = CS2100_FNCCFG2_CLKOUTUNL | CS2100_FNCCFG2_LFRATIOCFG;
  469. ret = cs2100_write_reg(config, CS2100_FNCCFG2, regval);
  470. }
  471. return ret;
  472. }
  473. /****************************************************************************
  474. * Public Functions
  475. ****************************************************************************/
  476. /****************************************************************************
  477. * Name: cs2100_enable
  478. *
  479. * Description:
  480. * Enable CS2100 CLK_OUT using the provide parameters
  481. *
  482. * Input Parameters:
  483. * config - CS2100-CP configuration
  484. *
  485. * Returned Value:
  486. * Zero (OK) on success; a negated errno value on failure.
  487. *
  488. ****************************************************************************/
  489. int cs2100_enable(FAR const struct cs2100_config_s *config)
  490. {
  491. uint8_t regval;
  492. int ret;
  493. DEBUGASSERT(config && config->i2c);
  494. /* Lock the CS2100 and disable CLK_OUT and AUX_OUT. Subsequent settings
  495. * will not take effect until the registers are unlocked.
  496. */
  497. regval = CS2100_DEVCTL_AUXOUTDIS | CS2100_DEVCTL_CLKOUTDIS;
  498. ret = cs2100_write_reg(config, CS2100_DEVCTL, regval);
  499. if (ret < 0)
  500. {
  501. cserr("ERROR: Failed to set CS2100_DEVCTL: %d\n", ret);
  502. return ret;
  503. }
  504. /* Set the internal timing reference clock divider */
  505. ret = cs2100_refclk(config);
  506. if (ret < 0)
  507. {
  508. cserr("ERROR: cs2100_refclk failed: %d\n", ret);
  509. return ret;
  510. }
  511. /* Freeze device control registers. This allows modifications to r0-r4
  512. * but the modifications will not take effect until the registers are
  513. * unfrozen.
  514. */
  515. ret = cs2100_write_reg(config, CS2100_GBLCFG, CS2100_GBLCFG_FREEZE);
  516. if (ret < 0)
  517. {
  518. cserr("ERROR: Failed to set CS2100_GBLCFG: %d\n", ret);
  519. return ret;
  520. }
  521. /* Calculate the effective ratio */
  522. ret = cs2100_ratio(config);
  523. if (ret < 0)
  524. {
  525. cserr("ERROR: cs2100_ratio failed: %d\n", ret);
  526. return ret;
  527. }
  528. /* Unfreeze the r0-r4 and set EnDevCfg2 */
  529. ret = cs2100_write_reg(config, CS2100_GBLCFG, CS2100_GBLCFG_ENDEVCFG2);
  530. if (ret < 0)
  531. {
  532. cserr("ERROR: Failed to set CS2100_GBLCFG: %d\n", ret);
  533. return ret;
  534. }
  535. /* Unlock and enable the CS2100 and CLK_OUT */
  536. regval = CS2100_DEVCTL_UNLOCK | CS2100_DEVCTL_AUXOUTDIS;
  537. ret = cs2100_write_reg(config, CS2100_DEVCTL, regval);
  538. if (ret < 0)
  539. {
  540. cserr("ERROR: Failed to set CS2100_DEVCTL: %d\n", ret);
  541. }
  542. return ret;
  543. }
  544. /****************************************************************************
  545. * Name: cs2100_disable
  546. *
  547. * Description:
  548. * Disable CS2100 CLK_OUT
  549. *
  550. * Input Parameters:
  551. * config - CS2100-CP configuration
  552. *
  553. * Returned Value:
  554. * Zero (OK) on success; a negated errno value on failure.
  555. *
  556. ****************************************************************************/
  557. int cs2100_disable(FAR const struct cs2100_config_s *config)
  558. {
  559. uint8_t regval;
  560. int ret;
  561. /* Unlock and disable AUX_OUT and CLK_OUT */
  562. regval = CS2100_DEVCTL_UNLOCK | CS2100_DEVCTL_AUXOUTDIS |
  563. CS2100_DEVCTL_CLKOUTDIS;
  564. ret = cs2100_write_reg(config, CS2100_DEVCTL, regval);
  565. if (ret < 0)
  566. {
  567. cserr("ERROR: Failed to set CS2100_DEVCTL: %d\n", ret);
  568. return ret;
  569. }
  570. /* Clear EndDevCfg2 and unfreeze R0-R4 */
  571. ret = cs2100_write_reg(config, CS2100_GBLCFG, 0);
  572. if (ret < 0)
  573. {
  574. cserr("ERROR: Failed to set CS2100_GBLCFG: %d\n", ret);
  575. return ret;
  576. }
  577. /* Clear EndDevCfg1 */
  578. ret = cs2100_write_reg(config, CS2100_DEVCFG1, 0);
  579. if (ret < 0)
  580. {
  581. cserr("ERROR: Failed to set CS2100_DEVCFG1: %d\n", ret);
  582. return ret;
  583. }
  584. /* Lock the CS2100 */
  585. regval = CS2100_DEVCTL_AUXOUTDIS | CS2100_DEVCTL_CLKOUTDIS;
  586. ret = cs2100_write_reg(config, CS2100_DEVCTL, regval);
  587. if (ret < 0)
  588. {
  589. cserr("ERROR: Failed to set CS2100_DEVCTL: %d\n", ret);
  590. }
  591. return ret;
  592. }
  593. /****************************************************************************
  594. * Name: cs2100_dump
  595. *
  596. * Description:
  597. * Dump CS2100-CP registers to the SysLog
  598. *
  599. * Input Parameters:
  600. * config - CS2100-CP configuration (Needed only for I2C access: i2c and
  601. * i2caddr)
  602. *
  603. * Returned Value:
  604. * Zero (OK) on success; a negated errno value on failure.
  605. *
  606. ****************************************************************************/
  607. #ifdef CONFIG_CS2100CP_DEBUG
  608. int cs2100_dump(FAR const struct cs2100_config_s *config)
  609. {
  610. uint32_t ratio;
  611. uint8_t regval;
  612. int ret;
  613. csinfo("CS200-CP Registers:\n");
  614. ret = cs2100_read_reg(config, CS2100_DEVID, &regval);
  615. if (ret < 0)
  616. {
  617. cserr("ERROR: Failed to read CS2100_DEVID: %d\n", ret);
  618. return ret;
  619. }
  620. csinfo(" Devid: %02x\n", regval);
  621. ret = cs2100_read_reg(config, CS2100_DEVCTL, &regval);
  622. if (ret < 0)
  623. {
  624. cserr("ERROR: Failed to read CS2100_DEVCTL: %d\n", ret);
  625. return ret;
  626. }
  627. csinfo(" DevCtl: %02x\n", regval);
  628. ret = cs2100_read_reg(config, CS2100_DEVCFG1, &regval);
  629. if (ret < 0)
  630. {
  631. cserr("ERROR: Failed to read CS2100_DEVCFG1: %d\n", ret);
  632. return ret;
  633. }
  634. csinfo(" DevCfg1: %02x\n", regval);
  635. ret = cs2100_read_reg(config, CS2100_GBLCFG, &regval);
  636. if (ret < 0)
  637. {
  638. cserr("ERROR: Failed to read CS2100_GBLCFG: %d\n", ret);
  639. return ret;
  640. }
  641. csinfo(" GblCfg: %02x\n", regval);
  642. ret = cs2100_read_ratio(config, &ratio);
  643. if (ret < 0)
  644. {
  645. cserr("ERROR: cs2100_read_ratio failed: %d\n", ret);
  646. return ret;
  647. }
  648. csinfo(" Ratio: %04lx\n", (unsigned long)ratio);
  649. ret = cs2100_read_reg(config, CS2100_FNCCFG1, &regval);
  650. if (ret < 0)
  651. {
  652. cserr("ERROR: Failed to read CS2100_FNCCFG1: %d\n", ret);
  653. return ret;
  654. }
  655. csinfo(" FuncCfg1: %02x\n", regval);
  656. ret = cs2100_read_reg(config, CS2100_FNCCFG2, &regval);
  657. if (ret < 0)
  658. {
  659. cserr("ERROR: Failed to read CS2100_FNCCFG2: %d\n", ret);
  660. return ret;
  661. }
  662. csinfo(" FuncCfg2: %02x\n", regval);
  663. ret = cs2100_read_reg(config, CS2100_FNCCFG3, &regval);
  664. if (ret < 0)
  665. {
  666. cserr("ERROR: Failed to read CS2100_FNCCFG3: %d\n", ret);
  667. return ret;
  668. }
  669. csinfo(" FuncCfg3: %02x\n", regval);
  670. return OK;
  671. }
  672. #endif /* CONFIG_CS2100CP_DEBUG */
  673. #endif /* CONFIG_TIMERS_CS2100CP */