1 /*
2  * Copyright (C) 2021 Alibaba Group Holding Limited
3  */
4 
5 #include <errno.h>
6 #include <stdbool.h>
7 #include <aos/adc_core.h>
8 #include <aos/adc_csi.h>
9 
adc_csi_unregister(aos_adc_t * adc)10 static void adc_csi_unregister(aos_adc_t *adc)
11 {
12     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
13 
14     csi_adc_uninit(&(aos_csi_adc->csi_adc));
15 }
16 
adc_csi_startup(aos_adc_t * adc)17 static aos_status_t adc_csi_startup(aos_adc_t *adc)
18 {
19     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
20 
21     return csi_adc_start(&(aos_csi_adc->csi_adc));
22 }
23 
adc_csi_shutdown(aos_adc_t * adc)24 static void adc_csi_shutdown(aos_adc_t *adc)
25 {
26     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
27 
28     (void)csi_adc_stop(&(aos_csi_adc->csi_adc));
29 }
30 
adc_csi_read(aos_adc_t * adc,int32_t channel,int32_t * data)31 static aos_status_t adc_csi_read(aos_adc_t *adc, int32_t channel, int32_t *data)
32 {
33     aos_status_t ret;
34     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
35 
36     ret = csi_adc_channel_enable(&(aos_csi_adc->csi_adc), (uint8_t)channel, true);
37     if (ret < 0)
38         return -EIO;
39 
40     ret = csi_adc_start(&(aos_csi_adc->csi_adc));
41     if (ret != CSI_OK)
42         return -EIO;
43     *data = csi_adc_read(&(aos_csi_adc->csi_adc));
44     (void)csi_adc_stop(&(aos_csi_adc->csi_adc));
45 
46     return 0;
47 }
48 
adc_csi_read_voltage(aos_adc_t * adc,int32_t channel,int32_t * data)49 static aos_status_t adc_csi_read_voltage(aos_adc_t *adc, int32_t channel, int32_t *data)
50 {
51     aos_status_t ret;
52     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
53 
54     ret = csi_adc_channel_enable(&(aos_csi_adc->csi_adc), (uint8_t)channel, true);
55     if (ret < 0)
56         return -EIO;
57 
58     ret = csi_adc_start(&(aos_csi_adc->csi_adc));
59     if (ret != CSI_OK)
60         return -EIO;
61     *data = csi_adc_read_voltage(&(aos_csi_adc->csi_adc));
62     (void)csi_adc_stop(&(aos_csi_adc->csi_adc));
63 
64     return 0;
65 }
66 
adc_csi_set_channel(aos_adc_t * adc,int32_t channel,bool enable)67 static aos_status_t adc_csi_set_channel(aos_adc_t *adc, int32_t channel, bool enable)
68 {
69     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
70 
71     return csi_adc_channel_enable(&(aos_csi_adc->csi_adc), (uint8_t)channel, enable);
72 }
73 
adc_csi_set_sample_time(aos_adc_t * adc,int32_t channel,uint32_t clock)74 static aos_status_t adc_csi_set_sample_time(aos_adc_t *adc, int32_t channel, uint32_t clock)
75 {
76     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
77 
78     return csi_adc_channel_sampling_time(&(aos_csi_adc->csi_adc), (uint8_t)channel, (uint16_t)clock);
79 }
80 
adc_csi_set_mode(aos_adc_t * adc,aos_adc_mode_t mode)81 static aos_status_t adc_csi_set_mode(aos_adc_t *adc, aos_adc_mode_t mode)
82 {
83     bool enable = (mode == AOS_ADC_MODE_CONTINUE);
84     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
85 
86     return csi_adc_continue_mode(&(aos_csi_adc->csi_adc), enable);
87 }
88 
adc_csi_get_range(aos_adc_t * adc,int32_t channel,uint32_t * range)89 static aos_status_t adc_csi_get_range(aos_adc_t *adc, int32_t channel, uint32_t *range)
90 {
91     aos_adc_csi_t *aos_csi_adc = aos_container_of(adc, aos_adc_csi_t, aos_adc);
92 
93     return csi_adc_get_range(&(aos_csi_adc->csi_adc), (uint8_t)channel, range);
94 }
95 
96 static const aos_adc_ops_t adc_csi_ops = {
97     .unregister      = adc_csi_unregister,
98     .startup         = adc_csi_startup,
99     .shutdown        = adc_csi_shutdown,
100     .read            = adc_csi_read,
101     .read_voltage    = adc_csi_read_voltage,
102     .set_channel     = adc_csi_set_channel,
103     .set_sample_time = adc_csi_set_sample_time,
104     .set_mode        = adc_csi_set_mode,
105     .get_range       = adc_csi_get_range,
106 };
107 
aos_adc_csi_register(aos_adc_csi_t * adc_csi)108 aos_status_t aos_adc_csi_register(aos_adc_csi_t *adc_csi)
109 {
110     if (!adc_csi)
111         return -EINVAL;
112 
113     adc_csi->aos_adc.ops = &adc_csi_ops;
114 
115     return aos_adc_register(&adc_csi->aos_adc);
116 }
117 
aos_adc_csi_unregister(uint32_t id)118 aos_status_t aos_adc_csi_unregister(uint32_t id)
119 {
120     return aos_adc_unregister(id);
121 }
122