aboutsummaryrefslogtreecommitdiff
path: root/module/sensor/src/mod_sensor.c
blob: 7687f6b624c7b0002904b22aba369a8e1a471af9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
 * Arm SCP/MCP Software
 * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdbool.h>
#include <fwk_assert.h>
#include <fwk_errno.h>
#include <fwk_id.h>
#include <fwk_mm.h>
#include <fwk_module.h>
#include <fwk_module_idx.h>
#include <mod_sensor.h>

struct sensor_dev_ctx {
    struct mod_sensor_dev_config *config;
    struct mod_sensor_driver_api *driver_api;
};

static struct sensor_dev_ctx *ctx_table;

static int get_ctx_if_valid_call(fwk_id_t id,
                                 void *data,
                                 struct sensor_dev_ctx **ctx)
{
    int status;

    fwk_assert(fwk_module_is_valid_element_id(id));
    fwk_assert(ctx != NULL);

    if (!fwk_expect(data != NULL))
        return FWK_E_PARAM;

    status = fwk_module_check_call(id);
    if (status != FWK_SUCCESS)
        return status;

    *ctx = ctx_table + fwk_id_get_element_idx(id);

    return FWK_SUCCESS;
}

/*
 * Module API
 */
static int get_value(fwk_id_t id, uint64_t *value)
{
    int status;
    struct sensor_dev_ctx *ctx;

    status = get_ctx_if_valid_call(id, value, &ctx);
    if (status != FWK_SUCCESS)
        return status;

    status = ctx->driver_api->get_value(ctx->config->driver_id, value);
    if (!fwk_expect(status == FWK_SUCCESS))
        return FWK_E_DEVICE;

    return FWK_SUCCESS;
}

static int get_info(fwk_id_t id, struct mod_sensor_info *info)
{
    int status;
    struct sensor_dev_ctx *ctx;

    status = get_ctx_if_valid_call(id, info, &ctx);
    if (status != FWK_SUCCESS)
        return status;

    *info = *ctx->config->info;

    return FWK_SUCCESS;
}

static struct mod_sensor_api sensor_api = {
    .get_value = get_value,
    .get_info  = get_info,
};

/*
 * Framework handlers
 */
static int sensor_init(fwk_id_t module_id,
                       unsigned int element_count,
                       const void *unused)
{
    ctx_table = fwk_mm_alloc(element_count, sizeof(ctx_table[0]));

    if (ctx_table == NULL)
        return FWK_E_NOMEM;

    return FWK_SUCCESS;
}

static int sensor_dev_init(fwk_id_t element_id,
                           unsigned int unused,
                           const void *data)
{
    struct sensor_dev_ctx *ctx;
    struct mod_sensor_dev_config *config;

    ctx = ctx_table + fwk_id_get_element_idx(element_id);
    config = (struct mod_sensor_dev_config*)data;

    /* Validate device */
    if ((config->info == NULL) ||
       (config->info->type >= MOD_SENSOR_TYPE_COUNT))
        return FWK_E_DATA;

    ctx->config = config;

    return FWK_SUCCESS;
}

static int sensor_bind(fwk_id_t id, unsigned int round)
{
    struct sensor_dev_ctx *ctx;
    int status;
    struct mod_sensor_driver_api *driver = NULL;

    if ((round > 0) || fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) {
        /*
         * Only bind in first round of calls
         * Nothing to do for module
         */
        return FWK_SUCCESS;
    }

    ctx = ctx_table + fwk_id_get_element_idx(id);

    /* Bind to driver */
    status = fwk_module_bind(ctx->config->driver_id,
        FWK_ID_API(fwk_id_get_module_idx(ctx->config->driver_id), 0),
        &driver);
    if (status != FWK_SUCCESS)
        return status;

    /* Validate driver API */
    if ((driver == NULL) || (driver->get_value == NULL))
        return FWK_E_DATA;

    ctx->driver_api = driver;

    return FWK_SUCCESS;
}

static int sensor_process_bind_request(fwk_id_t source_id,
                                       fwk_id_t target_id,
                                       fwk_id_t api_type,
                                       const void **api)
{
    *api = &sensor_api;
    return FWK_SUCCESS;
}

const struct fwk_module module_sensor = {
    .name = "SENSOR",
    .api_count = 1,
    .event_count = 0,
    .type = FWK_MODULE_TYPE_HAL,
    .init = sensor_init,
    .element_init = sensor_dev_init,
    .bind = sensor_bind,
    .process_bind_request = sensor_process_bind_request,
};