blob: 2a0048f1074e6c0eae739e8046686f081c05267e [file] [log] [blame]
Will Drewryd4ae5282017-01-03 22:06:26 -06001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Will Drewryde2cad72017-03-10 15:53:34 -060017#include "include/ese/ese.h"
18#include "include/ese/log.h"
Will Drewryd4ae5282017-01-03 22:06:26 -060019
20#include "ese_private.h"
21
22static const char kUnknownHw[] = "unknown hw";
23static const char kNullEse[] = "NULL EseInterface";
24static const char *kEseErrorMessages[] = {
25 "Hardware supplied no transceive implementation.",
26 "Timed out polling for value.",
27};
28#define ESE_MESSAGES(x) (sizeof(x) / sizeof((x)[0]))
29
Will Drewryde2cad72017-03-10 15:53:34 -060030API const char *ese_name(const struct EseInterface *ese) {
31 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060032 return kNullEse;
Will Drewryde2cad72017-03-10 15:53:34 -060033 }
34 if (ese->ops->name) {
Will Drewryd4ae5282017-01-03 22:06:26 -060035 return ese->ops->name;
Will Drewryde2cad72017-03-10 15:53:34 -060036 }
Will Drewryd4ae5282017-01-03 22:06:26 -060037 return kUnknownHw;
38}
39
40API int ese_open(struct EseInterface *ese, void *hw_opts) {
Will Drewryde2cad72017-03-10 15:53:34 -060041 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060042 return -1;
Will Drewryde2cad72017-03-10 15:53:34 -060043 }
Will Drewryd4ae5282017-01-03 22:06:26 -060044 ALOGV("opening interface '%s'", ese_name(ese));
Will Drewryde2cad72017-03-10 15:53:34 -060045 if (ese->ops->open) {
Will Drewryd4ae5282017-01-03 22:06:26 -060046 return ese->ops->open(ese, hw_opts);
Will Drewryde2cad72017-03-10 15:53:34 -060047 }
Will Drewryd4ae5282017-01-03 22:06:26 -060048 return 0;
49}
50
Will Drewryde2cad72017-03-10 15:53:34 -060051API const char *ese_error_message(const struct EseInterface *ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060052 return ese->error.message;
53}
54
Will Drewryde2cad72017-03-10 15:53:34 -060055API int ese_error_code(const struct EseInterface *ese) {
56 return ese->error.code;
57}
Will Drewryd4ae5282017-01-03 22:06:26 -060058
Will Drewryde2cad72017-03-10 15:53:34 -060059API bool ese_error(const struct EseInterface *ese) { return ese->error.is_err; }
Will Drewryd4ae5282017-01-03 22:06:26 -060060
61API void ese_set_error(struct EseInterface *ese, int code) {
Will Drewryde2cad72017-03-10 15:53:34 -060062 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060063 return;
Will Drewryde2cad72017-03-10 15:53:34 -060064 }
Will Drewryd4ae5282017-01-03 22:06:26 -060065 /* Negative values are reserved for API wide messages. */
66 ese->error.code = code;
Will Drewryde2cad72017-03-10 15:53:34 -060067 ese->error.is_err = true;
Will Drewryd4ae5282017-01-03 22:06:26 -060068 if (code < 0) {
69 code = -(code + 1); /* Start at 0. */
Will Drewryde2cad72017-03-10 15:53:34 -060070 if ((uint32_t)(code) >= ESE_MESSAGES(kEseErrorMessages)) {
Will Drewryd4ae5282017-01-03 22:06:26 -060071 LOG_ALWAYS_FATAL("Unknown global error code passed to ese_set_error(%d)",
72 code);
73 }
74 ese->error.message = kEseErrorMessages[code];
75 return;
76 }
Will Drewryde2cad72017-03-10 15:53:34 -060077 if ((uint32_t)(code) >= ese->ops->errors_count) {
Will Drewryd4ae5282017-01-03 22:06:26 -060078 LOG_ALWAYS_FATAL("Unknown hw error code passed to ese_set_error(%d)", code);
79 }
Will Drewryde2cad72017-03-10 15:53:34 -060080 ese->error.message = ese->ops->errors[code];
Will Drewryd4ae5282017-01-03 22:06:26 -060081}
82
83/* Blocking. */
Will Drewryde2cad72017-03-10 15:53:34 -060084API int ese_transceive(struct EseInterface *ese, const uint8_t *tx_buf,
85 uint32_t tx_len, uint8_t *rx_buf, uint32_t rx_max) {
86 uint32_t recvd = 0;
87 if (!ese) {
Will Drewryd4ae5282017-01-03 22:06:26 -060088 return -1;
Will Drewryed4a7a72017-03-10 11:03:59 -060089 }
Will Drewryde2cad72017-03-10 15:53:34 -060090
91 if (ese->ops->transceive) {
92 recvd = ese->ops->transceive(ese, tx_buf, tx_len, rx_buf, rx_max);
93 return ese_error(ese) ? -1 : recvd;
94 }
95
96 if (ese->ops->hw_transmit && ese->ops->hw_receive) {
97 ese->ops->hw_transmit(ese, tx_buf, tx_len, 1);
98 if (!ese_error(ese)) {
99 recvd = ese->ops->hw_receive(ese, rx_buf, rx_max, 1);
100 }
101 return ese_error(ese) ? -1 : recvd;
102 }
103
104 ese_set_error(ese, kEseGlobalErrorNoTransceive);
105 return -1;
Will Drewryd4ae5282017-01-03 22:06:26 -0600106}
107
Will Drewryde2cad72017-03-10 15:53:34 -0600108API void ese_close(struct EseInterface *ese) {
109 if (!ese) {
110 return;
111 }
Will Drewryd4ae5282017-01-03 22:06:26 -0600112 ALOGV("closing interface '%s'", ese_name(ese));
Will Drewryde2cad72017-03-10 15:53:34 -0600113 if (!ese->ops->close) {
114 return;
115 }
116 ese->ops->close(ese);
Will Drewryd4ae5282017-01-03 22:06:26 -0600117}