fadc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fadc.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-02-18 08:28:45
  17. * Description:  This files is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. */
  23. #include <string.h>
  24. #include "fgeneric_timer.h"
  25. #include "fkernel.h"
  26. #include "ftypes.h"
  27. #include "ferror_code.h"
  28. #include "fdebug.h"
  29. #include "fadc.h"
  30. #include "fadc_hw.h"
  31. #include "fparameters.h"
  32. #include "fassert.h"
  33. #include "fsleep.h"
  34. #define FADC_DEBUG_TAG "FT_ADC"
  35. #define FADC_DEBUG(format, ...) FT_DEBUG_PRINT_D(FADC_DEBUG_TAG, format, ##__VA_ARGS__)
  36. #define FADC_INFO(format, ...) FT_DEBUG_PRINT_I(FADC_DEBUG_TAG, format, ##__VA_ARGS__)
  37. #define FADC_WARN(format, ...) FT_DEBUG_PRINT_W(FADC_DEBUG_TAG, format, ##__VA_ARGS__)
  38. #define FADC_ERROR(format, ...) FT_DEBUG_PRINT_E(FADC_DEBUG_TAG, format, ##__VA_ARGS__)
  39. #define FADC_MAX_CLOCK_PRESC 16
  40. #define FADC_MAX_THRESHOLD 0x400
  41. /**
  42. * @name: FAdcPowerDownControl
  43. * @msg: Set power down signal
  44. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  45. * the configuration information for the specified adc module.
  46. * @param {u8} power_state, this parameter must be enable or disable.
  47. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  48. */
  49. static FError FAdcPowerDownControl(FAdcCtrl *pctrl, u8 power_state)
  50. {
  51. FASSERT(pctrl != NULL);
  52. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  53. u32 reg_val = 0;
  54. uintptr base_addr = pctrl->config.base_addr;
  55. reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  56. if (power_state == FADC_CTRL_PD_ENABLE)
  57. {
  58. reg_val |= FADC_CTRL_REG_PD_EN;
  59. }
  60. else
  61. {
  62. reg_val &= ~(FADC_CTRL_REG_PD_EN);
  63. }
  64. FADC_WRITE_REG32(base_addr, FADC_CTRL_REG_OFFSET, reg_val);
  65. return FADC_SUCCESS;
  66. }
  67. /**
  68. * @name: FAdcChannelEnable
  69. * @msg: enable channel, corresponding to fix channel mode or multi channel mode.
  70. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  71. * the configuration information for the specified adc module.
  72. * @param {FAdcChannel} channel, adc channel number.
  73. * @param {boolean} state, TRUE-enable, FALSE-disable
  74. * @return void
  75. */
  76. void FAdcChannelEnable(FAdcCtrl *pctrl, FAdcChannel channel, boolean state)
  77. {
  78. FASSERT(pctrl != NULL);
  79. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  80. FASSERT(channel < FADC_CHANNEL_NUM);
  81. u32 reg_val = 0;
  82. uintptr base_addr = pctrl->config.base_addr;
  83. reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  84. if (state == TRUE)
  85. {
  86. if (reg_val & FADC_CTRL_REG_FIX_CHANNEL)
  87. {
  88. reg_val &= ~(FADC_CTRL_REG_FIX_CHANNEL_NUM_MASK);
  89. reg_val |= FADC_CTRL_REG_FIX_CHANNEL_NUM(channel);
  90. }
  91. else
  92. {
  93. reg_val |= FADC_CTRL_REG_CHANNEL_EN(channel);
  94. }
  95. }
  96. else
  97. {
  98. /* fix channel mode, disable means stop convert */
  99. if (reg_val & FADC_CTRL_REG_FIX_CHANNEL)
  100. {
  101. reg_val &= ~(FADC_CTRL_REG_SOC_EN);
  102. }
  103. else
  104. {
  105. reg_val &= ~(FADC_CTRL_REG_CHANNEL_EN(channel));
  106. }
  107. }
  108. FADC_WRITE_REG32(base_addr, FADC_CTRL_REG_OFFSET, reg_val);
  109. }
  110. /**
  111. * @name: FAdcChannelThresholdSet
  112. * @msg: Set adc channel high_threshold and low_threshold.
  113. * you need use this function after FAdcConvertSet. If you want to use this function to
  114. * add other channel enable when the adc conversion is started, you need to restart the
  115. * adc convert start signal(adc_soc_en) after use to make the operation valid.
  116. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  117. * the configuration information for the specified adc module.
  118. * @param {FAdcChannel} channel, adc channel number.
  119. * @param {FAdcThresholdConfig} *threshold_config, pointer to adc channel threshold value struct.
  120. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  121. */
  122. FError FAdcChannelThresholdSet(FAdcCtrl *pctrl, FAdcChannel channel, FAdcThresholdConfig *threshold_config)
  123. {
  124. FASSERT(pctrl != NULL);
  125. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  126. FASSERT(channel < FADC_CHANNEL_NUM);
  127. u16 low_threshold = threshold_config->low_threshold;
  128. u16 high_threshold = threshold_config->high_threshold;
  129. FASSERT(high_threshold < FADC_MAX_THRESHOLD);
  130. FASSERT(low_threshold < high_threshold);
  131. uintptr base_addr = pctrl->config.base_addr;
  132. u32 threshold = (FADC_LEVEL_REG_HIGH_LEVEL(high_threshold)) |
  133. (FADC_LEVEL_REG_LOW_LEVEL(low_threshold));
  134. FADC_WRITE_REG32(base_addr, (FADC_LEVEL_REG_OFFSET(channel)), threshold);
  135. return FADC_SUCCESS;
  136. }
  137. /**
  138. * @name: FAdcConvertSet
  139. * @msg: config adc convert parameters.
  140. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  141. * the configuration information for the specified adc module.
  142. * @param {FAdcConvertConfig} *convert_config, include convert mode,channel mode,
  143. * clock divider and convert_interval.
  144. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  145. */
  146. FError FAdcConvertSet(FAdcCtrl *pctrl, FAdcConvertConfig *convert_config)
  147. {
  148. FASSERT(pctrl != NULL);
  149. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  150. u32 reg_val = 0;
  151. uintptr base_addr = pctrl->config.base_addr;
  152. reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  153. /* clk_div config */
  154. u32 clk_div = convert_config->clk_div;
  155. FASSERT(clk_div < FADC_MAX_CLOCK_PRESC);
  156. if (clk_div % 2 == 1)
  157. {
  158. FADC_ERROR("clk_div is not even.");
  159. return FADC_ERR_INVAL_PARM;
  160. }
  161. reg_val &= (~FADC_CTRL_REG_CLK_DIV_MASK);
  162. reg_val |= FADC_CTRL_REG_CLK_DIV(clk_div);
  163. /* config convert mode */
  164. FAdcConvertMode convert_mode = convert_config->convert_mode;
  165. FASSERT(convert_mode < FADC_CONVERT_MODE_NUM);
  166. if (convert_mode == FADC_SINGLE_CONVERT)
  167. {
  168. reg_val |= FADC_CTRL_REG_SINGLE_CONVERT;
  169. }
  170. else
  171. {
  172. reg_val &= ~(FADC_CTRL_REG_SINGLE_CONVERT);
  173. }
  174. /* config channel mode */
  175. FAdcChannelMode channel_mode = convert_config->channel_mode;
  176. FASSERT(channel_mode < FADC_CHANNEL_MODE_NUM);
  177. if (channel_mode == FADC_FIXED_CHANNEL)
  178. {
  179. reg_val |= FADC_CTRL_REG_FIX_CHANNEL;
  180. }
  181. else
  182. {
  183. reg_val &= ~(FADC_CTRL_REG_FIX_CHANNEL);
  184. }
  185. FADC_WRITE_REG32(base_addr, FADC_CTRL_REG_OFFSET, reg_val);
  186. /* config time interval between two converts */
  187. FADC_WRITE_REG32(base_addr, FADC_INTER_REG_OFFSET, convert_config->convert_interval);
  188. return FADC_SUCCESS;
  189. }
  190. /**
  191. * @name: FAdcInterruptEnable
  192. * @msg: enable channel interrupt.
  193. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  194. * the configuration information for the specified adc module.
  195. * @param {FAdcChannel} channel, adc channel number.
  196. * @param {FAdcIntrEvtType} event_type, interrupt event type
  197. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  198. */
  199. FError FAdcInterruptEnable(FAdcCtrl *pctrl, FAdcChannel channel, FAdcIntrEventType event_type)
  200. {
  201. FASSERT(pctrl != NULL);
  202. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  203. uintptr base_addr = pctrl->config.base_addr;
  204. u32 reg_val = 0;
  205. reg_val = FADC_READ_REG32(base_addr, FADC_INTRMASK_REG_OFFSET);
  206. switch (event_type)
  207. {
  208. case FADC_INTR_EVENT_COVFIN: /* enable channel convert complete irq */
  209. reg_val &= ~(FADC_INTRMASK_REG_COVFIN_MASK(channel));
  210. break;
  211. case FADC_INTR_EVENT_DLIMIT:
  212. reg_val &= ~(FADC_INTRMASK_REG_DLIMIT_MASK(channel));
  213. break;
  214. case FADC_INTR_EVENT_ULIMIT:
  215. reg_val &= ~(FADC_INTRMASK_REG_ULIMIT_MASK(channel));
  216. break;
  217. case FADC_INTR_EVENT_ERROR:
  218. reg_val &= ~(FADC_INTRMASK_REG_ERR_MASK);
  219. break;
  220. default:
  221. break;
  222. }
  223. FADC_WRITE_REG32(base_addr, FADC_INTRMASK_REG_OFFSET, reg_val);
  224. return FADC_SUCCESS;
  225. }
  226. /**
  227. * @name: FAdcInterruptDisable
  228. * @msg: disable channel interrupt.
  229. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  230. * the configuration information for the specified adc module.
  231. * @param {FAdcChannel} channel, adc channel number.
  232. * @param {FAdcIntrEvtType} event_type, interrupt event type
  233. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  234. */
  235. FError FAdcInterruptDisable(FAdcCtrl *pctrl, FAdcChannel channel, FAdcIntrEventType event_type)
  236. {
  237. FASSERT(pctrl != NULL);
  238. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  239. FASSERT(channel < FADC_CHANNEL_NUM);
  240. uintptr base_addr = pctrl->config.base_addr;
  241. u32 reg_val = 0;
  242. reg_val = FADC_READ_REG32(base_addr, FADC_INTRMASK_REG_OFFSET);
  243. switch (event_type)
  244. {
  245. case FADC_INTR_EVENT_COVFIN: /* enable channel convert complete irq */
  246. reg_val |= (FADC_INTRMASK_REG_COVFIN_MASK(channel));
  247. break;
  248. case FADC_INTR_EVENT_DLIMIT:
  249. reg_val |= (FADC_INTRMASK_REG_DLIMIT_MASK(channel));
  250. break;
  251. case FADC_INTR_EVENT_ULIMIT:
  252. reg_val |= (FADC_INTRMASK_REG_ULIMIT_MASK(channel));
  253. break;
  254. case FADC_INTR_EVENT_ERROR:
  255. reg_val |= (FADC_INTRMASK_REG_ERR_MASK);
  256. break;
  257. default:
  258. break;
  259. }
  260. FADC_WRITE_REG32(base_addr, FADC_INTRMASK_REG_OFFSET, reg_val);
  261. return FADC_SUCCESS;
  262. }
  263. /**
  264. * @name: FAdcConvertStart
  265. * @msg: Start adc convert.
  266. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  267. * the configuration information for the specified adc module.
  268. * @return
  269. */
  270. void FAdcConvertStart(FAdcCtrl *pctrl)
  271. {
  272. FASSERT(pctrl != NULL);
  273. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  274. u32 reg_val = 0;
  275. uintptr base_addr = pctrl->config.base_addr;
  276. reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  277. reg_val |= FADC_CTRL_REG_SOC_EN;
  278. FADC_WRITE_REG32(base_addr, FADC_CTRL_REG_OFFSET, reg_val);
  279. }
  280. /**
  281. * @name: FAdcConvertStop
  282. * @msg: Stop adc convert.
  283. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  284. * the configuration information for the specified adc module.
  285. * @return
  286. */
  287. void FAdcConvertStop(FAdcCtrl *pctrl)
  288. {
  289. FASSERT(pctrl != NULL);
  290. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  291. u32 reg_val = 0;
  292. uintptr base_addr = pctrl->config.base_addr;
  293. reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  294. reg_val &= (~FADC_CTRL_REG_SOC_EN);
  295. FADC_WRITE_REG32(base_addr, FADC_CTRL_REG_OFFSET, reg_val);
  296. }
  297. /**
  298. * @name: FAdcInit
  299. * @msg: init adc variable configuration.
  300. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  301. * the configuration information for the specified adc module.
  302. * @param {FAdcConvertConfig} *convert_config, pointer to adc convert configuration
  303. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  304. */
  305. FError FAdcVariableConfig(FAdcCtrl *pctrl, FAdcConvertConfig *convert_config)
  306. {
  307. FASSERT(pctrl != NULL);
  308. FASSERT(convert_config != NULL);
  309. FError ret = FADC_SUCCESS;
  310. /* disable power down signal */
  311. ret = FAdcPowerDownControl(pctrl, FADC_CTRL_PD_DISABLE);
  312. if (ret != FADC_SUCCESS)
  313. {
  314. FADC_ERROR("FAdcPowerDownControl failed.");
  315. return FADC_ERR_CMD_FAILED;
  316. }
  317. /* set time interval between two converts */
  318. ret = FAdcConvertSet(pctrl, convert_config);
  319. if (ret != FADC_SUCCESS)
  320. {
  321. FADC_ERROR("FAdcConvertSet failed.");
  322. return FADC_ERR_CMD_FAILED;
  323. }
  324. return ret;
  325. }
  326. /**
  327. * @name: FAdcSingleConvertEnable
  328. * @msg: Enable single convert signal, when convert mode is set to single conversion.
  329. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  330. * the configuration information for the specified adc module.
  331. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  332. */
  333. static FError FAdcSingleConvertEnable(FAdcCtrl *pctrl)
  334. {
  335. FASSERT(pctrl != NULL);
  336. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  337. u32 reg_val = 0;
  338. uintptr base_addr = pctrl->config.base_addr;
  339. reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  340. reg_val |= FADC_CTRL_REG_SINGLE_CONVERT_EN;
  341. FADC_WRITE_REG32(base_addr, FADC_CTRL_REG_OFFSET, reg_val);
  342. return FADC_SUCCESS;
  343. }
  344. /**
  345. * @name: FAdcReadConvertResult
  346. * @msg: read adc channel convert result value.
  347. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  348. * the configuration information for the specified adc module.
  349. * @param {FAdcChannel} channel, adc channel number.
  350. * @param {u16} *val, pointer to adc convert result value.
  351. * @return err code information, FADC_SUCCESS indicates success,others indicates failed.
  352. */
  353. FError FAdcReadConvertResult(FAdcCtrl *pctrl, FAdcChannel channel, u16 *val)
  354. {
  355. FASSERT(pctrl != NULL);
  356. FASSERT(channel < FADC_CHANNEL_NUM);
  357. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  358. int timeout = FADC_READ_DELAY;
  359. uintptr base_addr = pctrl->config.base_addr;
  360. u32 reg_val = FADC_READ_REG32(base_addr, FADC_CTRL_REG_OFFSET);
  361. /* single conversion */
  362. if (reg_val & FADC_CTRL_REG_SINGLE_CONVERT)
  363. {
  364. FAdcSingleConvertEnable(pctrl);
  365. }
  366. do
  367. {
  368. fsleep_millisec(10);
  369. }
  370. while ((!pctrl->convert_complete[channel]) && (0 <= --timeout));
  371. if (0 >= timeout)
  372. {
  373. FADC_ERROR("timeout when read adc data, convert is not completed.");
  374. *val = 0;
  375. return FADC_ERR_TIMEOUT;
  376. }
  377. FADC_CONVERT_UNCOMPLETE(pctrl->convert_complete[channel]);
  378. *val = pctrl->value[channel];
  379. return FADC_SUCCESS;
  380. }
  381. /**
  382. * @name: FAdcReadFinishCnt
  383. * @msg: read adc channel convert finish count.
  384. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  385. * the configuration information for the specified adc module.
  386. * @param {FAdcChannel} channel, adc channel number.
  387. * @param {u32} *count, pointer to adc convert finish count.
  388. * @return err code information, FADC_SUCCESS indicates success,others indicates failed.
  389. */
  390. FError FAdcReadFinishCnt(FAdcCtrl *pctrl, FAdcChannel channel, u32 *count)
  391. {
  392. FASSERT(pctrl != NULL);
  393. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  394. uintptr base_addr = pctrl->config.base_addr;
  395. *count = FADC_READ_REG32(base_addr, FADC_FINISH_CNT_REG_OFFSET(channel));
  396. return FADC_SUCCESS;
  397. }
  398. /**
  399. * @name: FAdcReadHisLimit
  400. * @msg: read adc channel history limit value, include upper limit and lower limit.
  401. * @param {FAdcCtrl} *pctrl, pointer to a FAdcCtrl structure that contains
  402. * the configuration information for the specified adc module.
  403. * @param {FAdcChannel} channel, adc channel number.
  404. * @param {u16} *u_his_limit, pointer to adc convert history upper limit value.
  405. * @param {u16} *d_his_limit, pointer to adc convert history lower limit value.
  406. * @return err code information, FADC_SUCCESS indicates success,others indicates failed.
  407. */
  408. FError FAdcReadHisLimit(FAdcCtrl *pctrl, FAdcChannel channel, u16 *u_his_limit, u16 *d_his_limit)
  409. {
  410. FASSERT(pctrl != NULL);
  411. FASSERT(FT_COMPONENT_IS_READY == pctrl->is_ready);
  412. u32 reg_val = 0;
  413. uintptr base_addr = pctrl->config.base_addr;
  414. reg_val = FADC_READ_REG32(base_addr, FADC_HIS_LIMIT_REG_OFFSET(channel));
  415. *u_his_limit = (reg_val & FADC_HIS_LIMIT_REG_UMASK) >> 16;
  416. *d_his_limit = (reg_val & FADC_HIS_LIMIT_REG_DMASK) ;
  417. return FADC_SUCCESS;
  418. }
  419. /**
  420. * @name: FAdcDeInitialize
  421. * @msg: DeInitialization function for the device instance
  422. * @param {FAdcCtrl} *pctrl, instance of FADC controller
  423. * @return {*}
  424. */
  425. void FAdcDeInitialize(FAdcCtrl *pctrl)
  426. {
  427. FASSERT(pctrl);
  428. pctrl->is_ready = 0;
  429. memset(pctrl, 0, sizeof(*pctrl));
  430. return;
  431. }
  432. /**
  433. * @name: FAdcCfgInitialize
  434. * @msg: Initializes a specific instance such that it is ready to be used.
  435. * @param {FAdcCtrl} *pctrl, instance of FADC controller
  436. * @param {FAdcConfig} *input_config_p, Default configuration parameters of FADC
  437. * @return err code information, FADC_SUCCESS indicates success,others indicates failed
  438. */
  439. FError FAdcCfgInitialize(FAdcCtrl *pctrl, const FAdcConfig *input_config_p)
  440. {
  441. FASSERT(pctrl && input_config_p);
  442. FError ret = FADC_SUCCESS;
  443. /*
  444. * If the device is started, disallow the initialize and return a Status
  445. * indicating it is started. This allows the user to de-initialize the device
  446. * and reinitialize, but prevents a user from inadvertently
  447. * initializing.
  448. */
  449. if (FT_COMPONENT_IS_READY == pctrl->is_ready)
  450. {
  451. FADC_WARN("device is already initialized!!!");
  452. }
  453. /*Set default values and configuration data */
  454. FAdcDeInitialize(pctrl);
  455. pctrl->config = *input_config_p;
  456. pctrl->is_ready = FT_COMPONENT_IS_READY;
  457. return ret;
  458. }