1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Description:
8 * Juno ADC Driver
9 */
10
11 #include "juno_adc.h"
12 #include "v2m_sys_regs.h"
13
14 #include <mod_juno_adc.h>
15 #include <mod_sensor.h>
16
17 #include <fwk_assert.h>
18 #include <fwk_id.h>
19 #include <fwk_module.h>
20 #include <fwk_module_idx.h>
21 #include <fwk_status.h>
22
23 #include <stddef.h>
24 #include <stdint.h>
25
26 /*
27 * ADC driver API functions.
28 */
29
get_value(fwk_id_t id,mod_sensor_value_t * value)30 static int get_value(fwk_id_t id, mod_sensor_value_t *value)
31 {
32 #ifdef BUILD_HAS_SENSOR_SIGNED_VALUE
33 return FWK_E_SUPPORT;
34 #else
35 uint32_t adc_value;
36 uint64_t adc_quantity;
37 enum juno_adc_dev_type dev_type;
38
39 dev_type = (enum juno_adc_dev_type)fwk_id_get_sub_element_idx(id);
40
41 switch ((enum juno_adc_sensor_type)fwk_id_get_element_idx(id)) {
42 case ADC_TYPE_CURRENT:
43 adc_value =
44 V2M_SYS_REGS->ADC_CURRENT[dev_type] & JUNO_ADC_SYS_REG_AMPS_MASK;
45
46 adc_quantity = ((uint64_t)adc_value) * JUNO_ADC_AMPS_MULTIPLIER;
47
48 if ((dev_type == ADC_DEV_BIG) || (dev_type == ADC_DEV_GPU)) {
49 adc_quantity /= ADC_CURRENT_CONST1;
50 } else {
51 adc_quantity /= ADC_CURRENT_CONST2;
52 }
53
54 *value = adc_quantity;
55
56 return FWK_SUCCESS;
57
58 case ADC_TYPE_VOLT:
59 adc_value =
60 V2M_SYS_REGS->ADC_VOLT[dev_type] & JUNO_ADC_SYS_REG_VOLT_MASK;
61
62 adc_quantity =
63 (((uint64_t)adc_value) * JUNO_ADC_VOLT_MULTIPLIER) / ADC_VOLT_CONST;
64
65 *value = adc_quantity;
66
67 return FWK_SUCCESS;
68
69 case ADC_TYPE_POWER:
70 adc_value =
71 V2M_SYS_REGS->ADC_POWER[dev_type] & JUNO_ADC_SYS_REG_POWER_MASK;
72
73 adc_quantity = ((uint64_t)adc_value) * JUNO_ADC_WATTS_MULTIPLIER;
74
75 if ((dev_type == ADC_DEV_BIG) || (dev_type == ADC_DEV_GPU)) {
76 adc_quantity /= ADC_POWER_CONST1;
77 } else {
78 adc_quantity /= ADC_POWER_CONST2;
79 }
80
81 *value = adc_quantity;
82
83 return FWK_SUCCESS;
84
85 case ADC_TYPE_ENERGY:
86 adc_quantity =
87 V2M_SYS_REGS->ADC_ENERGY[dev_type] * JUNO_ADC_JOULE_MULTIPLIER;
88
89 if ((dev_type == ADC_DEV_BIG) || (dev_type == ADC_DEV_GPU)) {
90 adc_quantity /= ADC_ENERGY_CONST1;
91 } else {
92 adc_quantity /= ADC_ENERGY_CONST2;
93 }
94
95 *value = adc_quantity;
96
97 return FWK_SUCCESS;
98
99 default:
100 return FWK_E_PARAM;
101 }
102 #endif
103 }
104
get_info(fwk_id_t id,struct mod_sensor_info * info)105 static int get_info(fwk_id_t id, struct mod_sensor_info *info)
106 {
107 const struct mod_juno_adc_dev_config *config;
108
109 config = fwk_module_get_data(id);
110
111 if (!fwk_expect(config->info != NULL)) {
112 return FWK_E_DATA;
113 }
114
115 *info = *(config->info);
116
117 return FWK_SUCCESS;
118 }
119
120 static const struct mod_sensor_driver_api adc_sensor_api = {
121 .get_value = get_value,
122 .get_info = get_info,
123 };
124
125 /*
126 * Framework handlers.
127 */
juno_adc_init(fwk_id_t module_id,unsigned int element_count,const void * data)128 static int juno_adc_init(fwk_id_t module_id,
129 unsigned int element_count,
130 const void *data)
131 {
132 if (!fwk_expect(element_count > 0)) {
133 return FWK_E_DATA;
134 }
135
136 return FWK_SUCCESS;
137 }
138
juno_adc_element_init(fwk_id_t element_id,unsigned int sub_element_count,const void * data)139 static int juno_adc_element_init(fwk_id_t element_id,
140 unsigned int sub_element_count,
141 const void *data)
142 {
143 return FWK_SUCCESS;
144 }
145
juno_adc_process_bind_request(fwk_id_t source_id,fwk_id_t target_id,fwk_id_t api_id,const void ** api)146 static int juno_adc_process_bind_request(fwk_id_t source_id,
147 fwk_id_t target_id,
148 fwk_id_t api_id,
149 const void **api)
150 {
151 if (!fwk_module_is_valid_sub_element_id(target_id)) {
152 return FWK_E_ACCESS;
153 }
154
155 if (fwk_id_get_module_idx(source_id) !=
156 fwk_id_get_module_idx(fwk_module_id_sensor)) {
157 return FWK_E_ACCESS;
158 }
159
160 if (!fwk_id_is_equal(api_id, mod_juno_adc_api_id_driver)) {
161 return FWK_E_ACCESS;
162 }
163
164 *api = &adc_sensor_api;
165
166 return FWK_SUCCESS;
167 }
168
169 const struct fwk_module module_juno_adc = {
170 .type = FWK_MODULE_TYPE_DRIVER,
171 .api_count = (unsigned int)MOD_JUNO_ADC_API_IDX_COUNT,
172 .init = juno_adc_init,
173 .element_init = juno_adc_element_init,
174 .process_bind_request = juno_adc_process_bind_request
175 };
176