• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# MIPI CSI
2
3
4## Overview
5
6Defined by the Mobile Industry Processor Interface (MIPI) Alliance, the Camera Serial Interface (CSI) is a specification that allows data to be transmitted from the camera to the host processor on mobile platforms. As the second release, the MIPI CSI-2 consists of the application layer, protocol layer, and physical layer. It supports a maximum of four-lane data transmission and a single-lane transmission rate of 1 Gbit/s.
7
8The physical layer supports the high speed (HS) and low speed (LS) modes. Using low-voltage differential signaling (LVDS), the HS mode delivers 80 Mbit/s to 1 Gbit/s transmission speed but high power consumption. The unidirectional LS mode provides lower power consumption but lower transmission speed (< 10 Mbit/s). The blend of the two modes ensures high-speed transmission of massive data (such as images) and minimized power consumption when less data is transmitted.
9
10The figure below shows a simplified CSI. The D-PHY transmits data by using one pair of source-synchronized differential clocks and one to four pairs of differential data lanes. Data is transmitted in Double Data Rate (DDR) mode, that is, data is transmitted on both the rising and falling edges of the clock.
11
12  **Figure 1** CSI TX and RX interfaces
13  ![](figures/CSI_TX-RX_interface.png)
14
15### ComboDevAttr Structure
16
17**Table 1** ComboDevAttr structure
18
19<a name="table1_MIPI_CSIDes"></a>
20
21| Name     | Description                                                 |
22| --------- | ----------------------------------------------------- |
23| devno     | Device number.                                               |
24| inputMode | Input mode, which can be MIPI, LVDS, sub-LVDS, HiSPI, or DC.                |
25| dataRate  | Input rate of the MIPI RX scalable low voltage signaling (SLVS).                                |
26| imgRect   | Crop area of the MIPI RX device (same as the size of the input image of the sensor).|
27| MIPIAttr  | Attributes of the MIPI device.                                         |
28| lvdsAttr  | Attributes of the LVDS, sub-LVDS, or HiSPi device.                           |
29
30### ExtDataType Structure
31
32**Table 2** ExtDataType structure
33
34<a name="table2_MIPI_CSIDes"></a>
35
36| Name           | Description                           |
37| --------------- | ------------------------------- |
38| devno           | Device number.                         |
39| num             | Sensor number.                       |
40| extDataBitWidth | Bit depth of an image.                     |
41| extDataType     | Pointer to the YUV, raw data format, and bit depth.|
42
43### Available APIs
44
45**Table 3** MIPI CSI APIs
46
47<a name="table3_MIPI_CSIDes"></a>
48
49| Category| API|
50| -------- | -------- |
51| Opening or closing the MIPI CSI controller operation handle| **MipiCsiOpen**: opens the MIPI CSI controller operation handle.<br>**MipiCsiClose**: closes the MIPI CSI controller operation handle.|
52| Setting MIPI CSI attributes | **MipiCsiSetComboDevAttr**: sets attributes of the MIPI, CMOS, or LVDS camera to the controller. The attributes include the working mode, image area, image depth, data rate, and physical channel.<br>**MipiCsiSetExtDataType** (optional): sets the YUV and RAW data formats and bit depths.<br>**MipiCsiSetHsMode**: sets the MIPI RX lane distribution. Set the mode based on the hardware connection.<br>**MipiCsiSetPhyCmvmode**: sets the common-mode voltage (CMV) mode. |
53| Resetting a sensor or deasserting the reset of a sensor| **MipiCsiResetSensor**: resets a sensor.<br>**MipiCsiUnresetSensor**: deasserts the reset of a sensor.|
54| Resetting the MIPI RX or deasserting the reset of the MIPI RX| **MipiCsiResetRx**: resets the MIPI&amp;nbsp;RX. The value of **enSnsType** varies depending on the value of **s32WorkingViNum**.<br>**MipiCsiUnresetRx**: deasserts the reset on the MIPI&amp;nbsp;RX.|
55| Enabling or disabling the MIPI clock| **MipiCsiEnableClock**: enables the MIPI clock. The **enSnsType** passed by the upper-layer function during electrophoresis determines whether MIPI or LVDS is used.<br>**MipiCsiDisableClock**: disables the MIPI clock.|
56| Enabling or disabling the MIPI sensor clock| **MipiCsiEnableSensorClock**: enables the MIPI sensor clock.<br>**MipiCsiDisableSensorClock**: disables the MIPI sensor clock.|
57
58
59## Usage Guidelines
60
61### How to Use
62
63The figure below illustrates the general development process.
64
65**Figure 2** Using MIPI CSI driver APIs
66
67
68![](figures/using-MIPI-CSI-process.png)
69
70### Opening a MIPI CSI Controller Operation Handle
71
72Before starting MIPI CSI communication, call **MipiCsiOpen** to open the MIPI CSI device handle. This function returns the MIPI CSI device handle with the specified lane ID.
73
74```c
75DevHandle MipiCsiOpen(uint8_t id);
76```
77
78**Table 4** Description of MipiCsiOpen
79
80<a name="table4_MIPI_CSIDes"></a>
81
82| Parameter      | Description                                       |
83| ---------- | ----------------------------------------------- |
84| id         | MIPI CSI lane ID.                                 |
85| **Return Value**| **Description**                                 |
86| NULL       | The operation failed.                                       |
87| Device handle  | The operation is successful. The MIPI CSI device handle with the specified lane ID is returned. The data type is **DevHandle**. |
88
89For example, open the controller operation handle of MIPI CSI lane 0:
90
91```c
92DevHandle mipiCsiHandle = NULL;  /* Device handle */
93id = 0; /* MIPI CSI lane ID */
94
95/* Open the controller operation handle. */
96MipiCsiHandle = MipiCsiOpen(id);
97if (MipiCsiHandle == NULL) {
98    HDF_LOGE("MipiCsiOpen: failed\n");
99    return;
100}
101```
102
103### Setting MIPI CSI Attributes
104
105-   Set MIPI CSI attributes.
106
107    ```c
108    int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
109    ```
110
111    **Table 5** Description of MipiCsiSetComboDevAttr
112
113    <a name="table5_MIPI_CSIDes"></a>
114
115    | Parameter      | Description                  |
116    | ---------- | -------------------------- |
117    | handle     | Controller operation handle.            |
118    | pAttr      | Pointer to the MIPI CSI structure.|
119    | **Return Value**| **Description**            |
120    | 0          | The operation is successful.                  |
121    | Negative value      | The operation failed.                  |
122
123    ```c
124    int32_t ret;
125    struct ComboDevAttr attr;
126
127    /* The current configuration is as follows: */
128    (void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
129    attr.devno = 0; /* Device 0 */
130    attr.inputMode = INPUT_MODE_MIPI; /* The input mode is MIPI. */
131    attr.dataRate = MIPI_DATA_RATE_X1; /* The data rate is 1 pixel per clock cycle. */
132    attr.imgRect.x = 0; /* The value 0 indicates the upper left position of the image sensor. */
133    attr.imgRect.y = 0; /* The value 0 indicates the upper right position of the image sensor. */
134    attr.imgRect.width = 2592; /* The width of the image sensor is 2592. */
135    attr.imgRect.height = 1944; /* The height of the image sensor is 1944. */
136    /* Write the MIPI CSI configuration. */
137    ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr);
138    if (ret != 0) {
139        HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret);
140        return -1;
141    }
142    ```
143
144-   Set the YUV, RAW data format, and bit depth.
145
146    ```c
147    int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType);
148    ```
149
150    **Table 6** Description of MipiCsiSetExtDataType
151
152    <a name="table6_MIPI_CSIDes"></a>
153
154    | Parameter      | Description                       |
155    | ---------- | ------------------------------- |
156    | handle     | Controller operation handle.                 |
157    | dataType   | Pointer to the YUV, raw data format, and bit depth.|
158    | **Return Value**| **Description**                 |
159    | 0          | The operation is successful.                       |
160    | Negative value      | The operation failed.                       |
161
162    ```c
163    int32_t ret;
164    struct ExtDataType dataType;
165
166    /* Set the YUV, raw data format, and bit depth. */
167    dataType.devno = 0; /* Device 0 */
168    dataType.num = 0;   /* sensor 0 */
169    dataType.extDataBitWidth[0] = 12; /* Bit depth array element 0 */
170    dataType.extDataBitWidth[1] = 12; /* Bit depth array element 1 */
171    dataType.extDataBitWidth[2] = 12; /* Bit depth array element 2 */
172
173    dataType.extDataType[0] = 0x39; /* Define YUV, raw data format, and bit depth element 0. */
174    dataType.extDataType[1] = 0x39; /* Define YUV, raw data format, and bit depth element 1. */
175    dataType.extDataType[2] = 0x39; /* Define YUV, raw data format, and bit depth element 2. */
176    /* Set the YUV, raw data format, and bit depth. */
177    ret = MipiCsiSetExtDataType(MipiCsiHandle, &dataType);
178    if (ret != 0) {
179        HDF_LOGE("%s: MipiCsiSetExtDataType fail! ret=%d\n", __func__, ret);
180        return -1;
181    }
182    ```
183
184-   Set the MIPI RX lane distribution.
185
186    ```c
187    int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode);
188    ```
189
190    **Table 7** Description of MipiCsiSetHsMode
191
192    <a name="table7_MIPI_CSIDes"></a>
193
194    | Parameter          | Description      |
195    | -------------- | -------------- |
196    | handle         | Controller operation handle.|
197    | laneDivideMode | Lane mode.  |
198    | **Return Value**    | **Description**|
199    | 0              | The operation is successful.      |
200    | Negative value          | The operation failed.      |
201
202    ```c
203    int32_t ret;
204    enum LaneDivideMode mode;
205
206    /* Set the lane mode to 0. */
207    mode = LANE_DIVIDE_MODE_0;
208    /* Set the MIPI RX lane distribution. */
209    ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
210    if (ret != 0) {
211        HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
212        return -1;
213    }
214    ```
215
216-   Set the CMV mode.
217
218    ```c
219    int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode);
220    ```
221
222    **Table 8** Description of MipiCsiSetPhyCmvmode
223
224    <a name="table8_MIPI_CSIDes"></a>
225
226    | Parameter      | Description        |
227    | ---------- | ---------------- |
228    | handle     | Controller operation handle.  |
229    | cmvMode    | CMV mode.|
230    | devno      | Device number.        |
231    | **Return Value**| **Description**  |
232    | 0          | The operation is successful.        |
233    | Negative value      | The operation failed.        |
234
235    ```c
236    int32_t ret;
237    enum PhyCmvMode mode;
238    uint8_t devno;
239
240    /* Set the CMV mode to 0. */
241    mode = PHY_CMV_GE1200MV;
242    /* The device number is 0. */
243    devno = 0;
244    /* Set the CMV mode. */
245    ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode);
246    if (ret != 0) {
247        HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret);
248        return -1;
249    }
250    ```
251
252### Resetting a Sensor or Deasserting the Reset of a Sensor
253
254-   Reset a sensor.
255
256    ```c
257    int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource);
258    ```
259
260    **Table 9** Description of MipiCsiResetSensor
261
262    <a name="table9_MIPI_CSIDes"></a>
263
264    | Parameter          | Description                                        |
265    | -------------- | ------------------------------------------------ |
266    | handle         | Controller operation handle.                                  |
267    | snsResetSource | Sensor's reset signal cable number, which is called "sensor reset source" in software. |
268    | **Return Value**    | **Description**                                  |
269    | 0              | The operation is successful.                                        |
270    | Negative value          | The operation failed.                                        |
271
272    ```c
273    int32_t ret;
274    uint8_t snsResetSource;
275
276    /* The sensor's reset signal cable number is 0. */
277    snsResetSource = 0;
278    /* Reset the sensor. */
279    ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource);
280    if (ret != 0) {
281        HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret);
282        return -1;
283    }
284    ```
285
286-   Deassert the reset of a sensor.
287
288    ```c
289    int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource);
290    ```
291
292    **Table 10** Description of MipiCsiUnresetSensor
293
294    <a name="table10_MIPI_CSIDes"></a>
295
296    | Parameter          | Description                                        |
297    | -------------- | ------------------------------------------------ |
298    | handle         | Controller operation handle.                                  |
299    | snsResetSource | Sensor's reset signal cable number, which is called "sensor reset source" in software. |
300    | **Return Value**    | **Description**                                  |
301    | 0              | The operation is successful.                                    |
302    | Negative value          | The operation failed.                                    |
303
304    ```c
305    int32_t ret;
306    uint8_t snsResetSource;
307
308    /* The sensor's reset signal cable number is 0. */
309    snsResetSource = 0;
310    /* Deassert the reset of the sensor. */
311    ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource);
312    if (ret != 0) {
313        HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret);
314        return -1;
315    }
316    ```
317
318### Resetting the MIPI RX or Deasserting the Reset of the MIPI RX
319
320-   Reset the MIPI RX.
321
322    ```c
323    int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev);
324    ```
325
326    **Table 11** Description of MipiCsiResetRx
327
328    <a name="table11_MIPI_CSIDes"></a>
329
330    | Parameter      | Description             |
331    | ---------- | --------------------- |
332    | handle     | Controller operation handle.       |
333    | comboDev   | MIPI RX or LVDS channel number.|
334    | **Return Value**| **Description**       |
335    | 0          | The operation is successful.             |
336    | Negative value      | The operation failed.             |
337
338    ```c
339    int32_t ret;
340    uint8_t comboDev;
341
342    /* The channel number is 0.*/
343    comboDev = 0;
344    /* Reset the MIPI RX. */
345    ret = MipiCsiResetRx(MipiCsiHandle, comboDev);
346    if (ret != 0) {
347        HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret);
348        return -1;
349    }
350    ```
351
352-   Deassert the reset of the MIPI RX.
353
354    ```c
355    int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev);
356    ```
357
358    **Table 12** Description of MipiCsiUnresetRx
359
360    <a name="table12_MIPI_CSIDes"></a>
361
362    | Parameter      | Description             |
363    | ---------- | --------------------- |
364    | handle     | Controller operation handle.       |
365    | comboDev   | MIPI RX or LVDS channel number.|
366    | **Return Value**| **Description**       |
367    | 0          | The operation is successful.         |
368    | Negative value      | The operation failed.         |
369
370    ```c
371    int32_t ret;
372    uint8_t comboDev;
373
374    /* The channel number is 0.*/
375    comboDev = 0;
376    /* Deassert the reset of the MIPI RX. */
377    ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev);
378    if (ret != 0) {
379        HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret);
380        return -1;
381    }
382    ```
383
384### Enabling or Disabling the MIPI Clock
385
386-   Enable the MIPI clock.
387
388    ```c
389    int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev);
390    ```
391
392    **Table 13** Description of MipiCsiEnableClock
393
394    <a name="table13_MIPI_CSIDes"></a>
395
396    | Parameter      | Description      |
397    | ---------- | -------------- |
398    | handle     | Controller operation handle.|
399    | comboDev   | Channel number.      |
400    | **Return Value**| **Description**|
401    | 0          | The operation is successful.      |
402    | Negative value      | The operation failed.      |
403
404    ```c
405    int32_t ret;
406    uint8_t comboDev;
407
408    /* The channel number is 0.*/
409    comboDev = 0;
410    /* Enable the MIPI clock. */
411    ret = MipiCsiEnableClock(MipiCsiHandle, comboDev);
412    if (ret != 0) {
413        HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret);
414        return -1;
415    }
416    ```
417
418-   Disable the MIPI clock.
419
420    ```c
421    int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev);
422    ```
423
424    **Table 14** Description of MipiCsiDisableClock
425
426    <a name="table14_MIPI_CSIDes"></a>
427
428    | Parameter      | Description      |
429    | ---------- | -------------- |
430    | handle     | Controller operation handle.|
431    | comboDev   | Channel number.      |
432    | **Return Value**| **Description**|
433    | 0          | The operation is successful.      |
434    | Negative value      | The operation failed.      |
435
436    ```c
437    int32_t ret;
438    uint8_t comboDev;
439
440    /* The channel number is 0.*/
441    comboDev = 0;
442    /* Disable the MIPI clock. */
443    ret = MipiCsiDisableClock(MipiCsiHandle, comboDev);
444    if (ret != 0) {
445        HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret);
446        return -1;
447    }
448    ```
449
450### Enabling or Disabling the MIPI Sensor Clock
451
452-   Enable the MIPI sensor clock.
453
454    ```c
455    int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource);
456    ```
457
458    **Table 15** Description of MipiCsiEnableSensorClock
459
460    <a name="table15_MIPI_CSIDes"></a>
461
462    | Parameter        | Description                                        |
463    | ------------ | ------------------------------------------------ |
464    | handle       | Controller operation handle.                                  |
465    | snsClkSource | Sensor's clock signal cable number, which is called clock source of the sensor in software.|
466    | **Return Value**  | **Description**                                  |
467    | 0            | The operation is successful.                                        |
468    | Negative value        | The operation failed.                                        |
469
470    ```c
471    int32_t ret;
472    uint8_t snsClkSource;
473
474    /* The sensor's clock signal cable number is 0. */
475    snsClkSource = 0;
476    /* Enable the MIPI sensor clock. */
477    ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource);
478    if (ret != 0) {
479        HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret);
480        return -1;
481    }
482    ```
483
484-   Disable the MIPI sensor clock.
485
486    ```c
487    int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource);
488    ```
489
490    **Table 16** Description of MipiCsiDisableSensorClock
491
492    <a name="table16_MIPI_CSIDes"></a>
493
494    | Parameter        | Description                                        |
495    | ------------ | ------------------------------------------------ |
496    | handle       | Controller operation handle.                                  |
497    | snsClkSource | Sensor's clock signal cable number, which is called clock source of the sensor in software.|
498    | **Return Value**  | **Description**                                  |
499    | 0            | The operation is successful.                                        |
500    | Negative value        | The operation failed.                                        |
501
502    ```c
503    int32_t ret;
504    uint8_t snsClkSource;
505
506    /* The sensor's clock signal cable number is 0. */
507    snsClkSource = 0;
508    /* Disable the MIPI sensor clock. */
509    ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource);
510    if (ret != 0) {
511        HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret);
512        return -1;
513    }
514    ```
515
516### Closing a MIPI CSI Controller Operation Handle
517
518Call **MipiCsiClose()** to close the MIPI CSI controller handle after the MIPI CSI communication is complete.
519
520```c
521void MipiCsiClose(DevHandle handle);
522```
523
524This function releases the resources requested by **MipiCsiOpen**.
525
526**Table 17** Description of MipiCsiClose
527
528<a name="table17_MIPI_CSIDes"></a>
529
530 | Parameter        | Description                                        |
531 | ------------ | ------------------------------------------------ |
532 | handle       | MIPI CSI controller operation handle.                                 |
533
534```c
535MipiCsiClose(MIPIHandle); /* Close the operation handle of the MIPI CSI controller. */
536```
537
538## Example
539
540The sample code is as follows:
541
542```c
543#include "hdf.h"
544#include "MIPI_csi_if.h"
545
546void PalMipiCsiTestSample(void)
547{
548    uint8_t id;
549    int32_t ret;
550    uint8_t comboDev;
551    uint8_t snsClkSource;
552    uint8_t devno;
553    enum LaneDivideMode mode;
554    enum PhyCmvMode mode;
555    struct ComboDevAttr attr;
556    struct ExtDataType dataType;
557    DevHandle MipiCsiHandle = NULL;
558
559    /* Controller ID */
560    id = 0;
561    /* Open the controller operation handle. */
562    MipiCsiHandle = MipiCsiOpen(id);
563    if (MipiCsiHandle == NULL) {
564        HDF_LOGE("MipiCsiOpen: failed!\n");
565        return;
566    }
567
568    /* Set the lane mode to 0. */
569    mode = LANE_DIVIDE_MODE_0;
570    /* Set the MIPI RX lane distribution. */
571    ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
572    if (ret != 0) {
573        HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
574        return;
575    }
576
577    /* The channel number is 0.*/
578    comboDev = 0;
579    /* Enable the MIPI clock. */
580    ret = MipiCsiEnableClock(MipiCsiHandle, comboDev);
581    if (ret != 0) {
582        HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret);
583        return;
584    }
585
586    /* Reset the MIPI RX. */
587    ret = MipiCsiResetRx(MipiCsiHandle, comboDev);
588    if (ret != 0) {
589        HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret);
590        return;
591    }
592
593    /* The sensor's clock signal cable number is 0. */
594    snsClkSource = 0;
595    /* Enable the MIPI sensor clock. */
596    ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource);
597    if (ret != 0) {
598        HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret);
599        return;
600    }
601
602    /* Reset the sensor. */
603    ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource);
604    if (ret != 0) {
605        HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret);
606        return;
607    }
608
609    /* Set MIPI parameters. */
610    (void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
611    attr.devno = 0; /* Device 0 */
612    attr.inputMode = INPUT_MODE_MIPI; /* The input mode is MIPI. */
613    attr.dataRate = MIPI_DATA_RATE_X1; /* The data rate is 1 pixel per clock cycle. */
614    attr.imgRect.x = 0; /* The value 0 indicates the upper left position of the image sensor. */
615    attr.imgRect.y = 0; /* The value 0 indicates the upper right position of the image sensor. */
616    attr.imgRect.width = 2592; /* The width of the image sensor is 2592. */
617    attr.imgRect.height = 1944; /* The height of the image sensor is 1944. */
618    /* Write the MIPI CSI configuration. */
619    ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr);
620    if (ret != 0) {
621        HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret);
622        return;
623    }
624
625    /* Set the CMV mode to 0. */
626    mode = PHY_CMV_GE1200MV;
627    /* The device number is 0. */
628    devno = 0;
629    /* Set the CMV mode. */
630    ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode);
631    if (ret != 0) {
632        HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret);
633        return;
634    }
635
636    /* The channel number is 0.*/
637    comboDev = 0;
638    /* Deassert the reset of the MIPI RX. */
639    ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev);
640    if (ret != 0) {
641        HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret);
642        return;
643    }
644
645    /* Disable the MIPI clock. */
646    ret = MipiCsiDisableClock(MipiCsiHandle, comboDev);
647    if (ret != 0) {
648        HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret);
649        return;
650    }
651
652    /* The sensor's reset signal cable number is 0. */
653    snsResetSource = 0;
654    /* Deassert the reset of the sensor. */
655    ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource);
656    if (ret != 0) {
657        HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret);
658        return;
659    }
660
661    /* Disable the MIPI sensor clock. */
662    ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource);
663    if (ret != 0) {
664        HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret);
665        return;
666    }
667
668    /* Close the MIPI CSI device handle. */
669    MipiCsiClose(MipiCsiHandle);
670}
671```
672