1 /*
2  * Copyright (C) 2021 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 #pragma once
17 
18 #include <algorithm>
19 #include <cmath>
20 
21 #include "HardwareBase.h"
22 #include "Vibrator.h"
23 
24 #define PROC_SND_PCM "/proc/asound/pcm"
25 #define HAPTIC_PCM_DEVICE_SYMBOL "haptic nohost playback"
26 
27 static struct pcm_config haptic_nohost_config = {
28         .channels = 1,
29         .rate = 48000,
30         .period_size = 80,
31         .period_count = 2,
32         .format = PCM_FORMAT_S16_LE,
33 };
34 
35 enum WaveformIndex : uint16_t {
36     /* Physical waveform */
37     WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
38     WAVEFORM_RESERVED_INDEX_1 = 1,
39     WAVEFORM_CLICK_INDEX = 2,
40     WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
41     WAVEFORM_THUD_INDEX = 4,
42     WAVEFORM_SPIN_INDEX = 5,
43     WAVEFORM_QUICK_RISE_INDEX = 6,
44     WAVEFORM_SLOW_RISE_INDEX = 7,
45     WAVEFORM_QUICK_FALL_INDEX = 8,
46     WAVEFORM_LIGHT_TICK_INDEX = 9,
47     WAVEFORM_LOW_TICK_INDEX = 10,
48     WAVEFORM_RESERVED_MFG_1,
49     WAVEFORM_RESERVED_MFG_2,
50     WAVEFORM_RESERVED_MFG_3,
51     WAVEFORM_MAX_PHYSICAL_INDEX,
52     /* OWT waveform */
53     WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
54     WAVEFORM_PWLE,
55     /*
56      * Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
57      * #define FF_GAIN          0x60  // 96 in decimal
58      * #define FF_MAX_EFFECTS   FF_GAIN
59      */
60     WAVEFORM_MAX_INDEX,
61 };
62 
63 namespace aidl {
64 namespace android {
65 namespace hardware {
66 namespace vibrator {
67 
68 class HwApi : public Vibrator::HwApi, private HwApiBase {
69   public:
Create()70     static std::unique_ptr<HwApi> Create() {
71         auto hwapi = std::unique_ptr<HwApi>(new HwApi());
72         return hwapi;
73     }
HwApi()74     HwApi() {
75         open("calibration/f0_stored", &mF0);
76         open("default/f0_offset", &mF0Offset);
77         open("calibration/redc_stored", &mRedc);
78         open("calibration/q_stored", &mQ);
79         open("default/vibe_state", &mVibeState);
80         open("default/num_waves", &mEffectCount);
81         open("default/braking_time_bank", &mEffectBrakingTimeBank);
82         open("default/braking_time_index", &mEffectBrakingTimeIndex);
83         open("default/braking_time_ms", &mEffectBrakingTimeMs);
84         open("default/owt_free_space", &mOwtFreeSpace);
85         open("default/f0_comp_enable", &mF0CompEnable);
86         open("default/redc_comp_enable", &mRedcCompEnable);
87         open("default/delay_before_stop_playback_us", &mMinOnOffInterval);
88     }
89 
setF0(std::string value)90     bool setF0(std::string value) override { return set(value, &mF0); }
setF0Offset(uint32_t value)91     bool setF0Offset(uint32_t value) override { return set(value, &mF0Offset); }
setRedc(std::string value)92     bool setRedc(std::string value) override { return set(value, &mRedc); }
setQ(std::string value)93     bool setQ(std::string value) override { return set(value, &mQ); }
getEffectCount(uint32_t * value)94     bool getEffectCount(uint32_t *value) override { return get(value, &mEffectCount); }
hasEffectBrakingTimeBank()95     bool hasEffectBrakingTimeBank() override { return has(mEffectBrakingTimeBank); }
setEffectBrakingTimeBank(uint32_t value)96     bool setEffectBrakingTimeBank(uint32_t value) override {
97         return set(value, &mEffectBrakingTimeBank);
98     }
setEffectBrakingTimeIndex(uint32_t value)99     bool setEffectBrakingTimeIndex(uint32_t value) override {
100         return set(value, &mEffectBrakingTimeIndex);
101     }
getEffectBrakingTimeMs(uint32_t * value)102     bool getEffectBrakingTimeMs(uint32_t *value) override {
103         return get(value, &mEffectBrakingTimeMs);
104     }
pollVibeState(uint32_t value,int32_t timeoutMs)105     bool pollVibeState(uint32_t value, int32_t timeoutMs) override {
106         return poll(value, &mVibeState, timeoutMs);
107     }
hasOwtFreeSpace()108     bool hasOwtFreeSpace() override { return has(mOwtFreeSpace); }
getOwtFreeSpace(uint32_t * value)109     bool getOwtFreeSpace(uint32_t *value) override { return get(value, &mOwtFreeSpace); }
setF0CompEnable(bool value)110     bool setF0CompEnable(bool value) override { return set(value, &mF0CompEnable); }
setRedcCompEnable(bool value)111     bool setRedcCompEnable(bool value) override { return set(value, &mRedcCompEnable); }
setMinOnOffInterval(uint32_t value)112     bool setMinOnOffInterval(uint32_t value) override { return set(value, &mMinOnOffInterval); }
113     // TODO(b/234338136): Need to add the force feedback HW API test cases
setFFGain(int fd,uint16_t value)114     bool setFFGain(int fd, uint16_t value) override {
115         struct input_event gain = {
116                 .type = EV_FF,
117                 .code = FF_GAIN,
118                 .value = value,
119         };
120         if (value > 100) {
121             ALOGE("Invalid gain");
122             return false;
123         }
124         if (write(fd, (const void *)&gain, sizeof(gain)) != sizeof(gain)) {
125             return false;
126         }
127         return true;
128     }
setFFEffect(int fd,struct ff_effect * effect,uint16_t timeoutMs)129     bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) override {
130         if (effect == nullptr) {
131             ALOGE("Invalid ff_effect");
132             return false;
133         }
134         if (ioctl(fd, EVIOCSFF, effect) < 0) {
135             ALOGE("setFFEffect fail");
136             return false;
137         }
138         return true;
139     }
setFFPlay(int fd,int8_t index,bool value)140     bool setFFPlay(int fd, int8_t index, bool value) override {
141         struct input_event play = {
142                 .type = EV_FF,
143                 .code = static_cast<uint16_t>(index),
144                 .value = value,
145         };
146         if (write(fd, (const void *)&play, sizeof(play)) != sizeof(play)) {
147             return false;
148         } else {
149             return true;
150         }
151     }
getHapticAlsaDevice(int * card,int * device)152     bool getHapticAlsaDevice(int *card, int *device) override {
153         std::string line;
154         std::ifstream myfile(PROC_SND_PCM);
155         if (myfile.is_open()) {
156             while (getline(myfile, line)) {
157                 if (line.find(HAPTIC_PCM_DEVICE_SYMBOL) != std::string::npos) {
158                     std::stringstream ss(line);
159                     std::string currentToken;
160                     std::getline(ss, currentToken, ':');
161                     sscanf(currentToken.c_str(), "%d-%d", card, device);
162                     return true;
163                 }
164             }
165             myfile.close();
166         } else {
167             ALOGE("Failed to read file: %s", PROC_SND_PCM);
168         }
169         return false;
170     }
setHapticPcmAmp(struct pcm ** haptic_pcm,bool enable,int card,int device)171     bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device) override {
172         int ret = 0;
173 
174         if (enable) {
175             *haptic_pcm = pcm_open(card, device, PCM_OUT, &haptic_nohost_config);
176             if (!pcm_is_ready(*haptic_pcm)) {
177                 ALOGE("cannot open pcm_out driver: %s", pcm_get_error(*haptic_pcm));
178                 goto fail;
179             }
180 
181             ret = pcm_prepare(*haptic_pcm);
182             if (ret < 0) {
183                 ALOGE("cannot prepare haptic_pcm: %s", pcm_get_error(*haptic_pcm));
184                 goto fail;
185             }
186 
187             ret = pcm_start(*haptic_pcm);
188             if (ret < 0) {
189                 ALOGE("cannot start haptic_pcm: %s", pcm_get_error(*haptic_pcm));
190                 goto fail;
191             }
192 
193             return true;
194         } else {
195             if (*haptic_pcm) {
196                 pcm_close(*haptic_pcm);
197                 *haptic_pcm = NULL;
198             }
199             return true;
200         }
201 
202     fail:
203         pcm_close(*haptic_pcm);
204         *haptic_pcm = NULL;
205         return false;
206     }
uploadOwtEffect(int fd,const uint8_t * owtData,const uint32_t numBytes,struct ff_effect * effect,uint32_t * outEffectIndex,int * status)207     bool uploadOwtEffect(int fd, const uint8_t *owtData, const uint32_t numBytes, struct ff_effect *effect,
208                          uint32_t *outEffectIndex, int *status) override {
209         if (owtData == nullptr || effect == nullptr || outEffectIndex == nullptr) {
210             ALOGE("Invalid argument owtData, ff_effect or outEffectIndex");
211             *status = EX_NULL_POINTER;
212             return false;
213         }
214         if (status == nullptr) {
215             ALOGE("Invalid argument status");
216             return false;
217         }
218 
219         (*effect).u.periodic.custom_len = numBytes / sizeof(uint16_t);
220         memcpy((*effect).u.periodic.custom_data, owtData, numBytes);
221 
222         if ((*effect).id != -1) {
223             ALOGE("(*effect).id != -1");
224         }
225 
226         /* Create a new OWT waveform to update the PWLE or composite effect. */
227         (*effect).id = -1;
228         if (ioctl(fd, EVIOCSFF, effect) < 0) {
229             ALOGE("Failed to upload effect %d (%d): %s", *outEffectIndex, errno, strerror(errno));
230             *status = EX_ILLEGAL_STATE;
231             return false;
232         }
233 
234         if ((*effect).id >= FF_MAX_EFFECTS || (*effect).id < 0) {
235             ALOGE("Invalid waveform index after upload OWT effect: %d", (*effect).id);
236             *status = EX_ILLEGAL_ARGUMENT;
237             return false;
238         }
239         *outEffectIndex = (*effect).id;
240         *status = 0;
241         return true;
242     }
eraseOwtEffect(int fd,int8_t effectIndex,std::vector<ff_effect> * effect)243     bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) override {
244         uint32_t effectCountBefore, effectCountAfter, i, successFlush = 0;
245 
246         if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
247             ALOGE("Invalid waveform index for OWT erase: %d", effectIndex);
248             return false;
249         }
250         if (effect == nullptr || (*effect).empty()) {
251             ALOGE("Invalid argument effect");
252             return false;
253         }
254         // Turn off the waiting time for SVC init phase to complete since chip
255         // should already under STOP state
256         setMinOnOffInterval(0);
257         // Do erase flow
258         if (effectIndex < WAVEFORM_MAX_INDEX) {
259             /* Normal situation. Only erase the effect which we just played. */
260             if (ioctl(fd, EVIOCRMFF, effectIndex) < 0) {
261                 ALOGE("Failed to erase effect %d (%d): %s", effectIndex, errno, strerror(errno));
262             }
263             for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < WAVEFORM_MAX_INDEX; i++) {
264                 if ((*effect)[i].id == effectIndex) {
265                     (*effect)[i].id = -1;
266                     break;
267                 }
268             }
269         } else {
270             /* Flush all non-prestored effects of ff-core and driver. */
271             getEffectCount(&effectCountBefore);
272             for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < FF_MAX_EFFECTS; i++) {
273                 if (ioctl(fd, EVIOCRMFF, i) >= 0) {
274                     successFlush++;
275                 }
276             }
277             getEffectCount(&effectCountAfter);
278             ALOGW("Flushed effects: ff: %d; driver: %d -> %d; success: %d", effectIndex,
279                   effectCountBefore, effectCountAfter, successFlush);
280             /* Reset all OWT effect index of HAL. */
281             for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < WAVEFORM_MAX_INDEX; i++) {
282                 (*effect)[i].id = -1;
283             }
284         }
285         // Turn on the waiting time for SVC init phase to complete
286         setMinOnOffInterval(Vibrator::MIN_ON_OFF_INTERVAL_US);
287         return true;
288     }
289 
debug(int fd)290     void debug(int fd) override { HwApiBase::debug(fd); }
291 
292   private:
293     std::ofstream mF0;
294     std::ofstream mF0Offset;
295     std::ofstream mRedc;
296     std::ofstream mQ;
297     std::ifstream mEffectCount;
298     std::ofstream mEffectBrakingTimeBank;
299     std::ofstream mEffectBrakingTimeIndex;
300     std::ifstream mEffectBrakingTimeMs;
301     std::ifstream mVibeState;
302     std::ifstream mOwtFreeSpace;
303     std::ofstream mF0CompEnable;
304     std::ofstream mRedcCompEnable;
305     std::ofstream mMinOnOffInterval;
306 };
307 
308 class HwCal : public Vibrator::HwCal, private HwCalBase {
309   private:
310     static constexpr char VERSION[] = "version";
311     static constexpr char F0_CONFIG[] = "f0_measured";
312     static constexpr char F0_CONFIG_DUAL[] = "f0_measured_dual";
313     static constexpr char REDC_CONFIG[] = "redc_measured";
314     static constexpr char Q_CONFIG[] = "q_measured";
315     static constexpr char TICK_VOLTAGES_CONFIG[] = "v_tick";
316     static constexpr char CLICK_VOLTAGES_CONFIG[] = "v_click";
317     static constexpr char LONG_VOLTAGES_CONFIG[] = "v_long";
318 
319     static constexpr uint32_t VERSION_DEFAULT = 2;
320     static constexpr int32_t DEFAULT_FREQUENCY_SHIFT = 0;
321     static constexpr std::array<uint32_t, 2> V_TICK_DEFAULT = {5, 95};
322     static constexpr std::array<uint32_t, 2> V_CLICK_DEFAULT = {5, 95};
323     static constexpr std::array<uint32_t, 2> V_LONG_DEFAULT = {5, 95};
324 
325   public:
HwCal()326     HwCal() {}
Create()327     static std::unique_ptr<HwCal> Create() {
328         auto hwcal = std::unique_ptr<HwCal>(new HwCal());
329         return hwcal;
330     }
331 
getVersion(uint32_t * value)332     bool getVersion(uint32_t *value) override {
333         if (getPersist(VERSION, value)) {
334             return true;
335         }
336         *value = VERSION_DEFAULT;
337         return true;
338     }
getLongFrequencyShift(int32_t * value)339     bool getLongFrequencyShift(int32_t *value) override {
340         return getProperty("long.frequency.shift", value, DEFAULT_FREQUENCY_SHIFT);
341     }
getF0(std::string * value)342     bool getF0(std::string *value) override { return getPersist(F0_CONFIG, value); }
getF0SyncOffset(uint32_t * value)343     bool getF0SyncOffset(uint32_t *value) override {
344         std::string cal_0{8, '0'};
345         std::string cal_1{8, '0'};
346 
347         if (getPersist(F0_CONFIG, &cal_0) && getPersist(F0_CONFIG_DUAL, &cal_1)) {
348             float f0_0 = static_cast<float>(std::stoul(cal_0, nullptr, 16)) / (1 << 14);
349             float f0_1 = static_cast<float>(std::stoul(cal_1, nullptr, 16)) / (1 << 14);
350             float f0_offset = std::abs(f0_0 - f0_1)/2;
351 
352             if (f0_0 < f0_1) {
353                 *value = static_cast<uint32_t>(f0_offset * std::pow(2, 14));
354             } else if (f0_0 > f0_1) {
355                 *value = static_cast<uint32_t>(std::pow(2, 24) - std::abs(f0_offset) * std::pow(2, 14));
356             } else {
357                 *value = 0;
358             }
359 
360             return true;
361         } else {
362             ALOGE("Vibrator: Unable to load F0_CONFIG or F0_CONFIG_DUAL config");
363             *value = 0;
364             return false;
365         }
366     }
getRedc(std::string * value)367     bool getRedc(std::string *value) override { return getPersist(REDC_CONFIG, value); }
getQ(std::string * value)368     bool getQ(std::string *value) override { return getPersist(Q_CONFIG, value); }
getTickVolLevels(std::array<uint32_t,2> * value)369     bool getTickVolLevels(std::array<uint32_t, 2> *value) override {
370         if (getPersist(TICK_VOLTAGES_CONFIG, value)) {
371             return true;
372         }
373         return getProperty(TICK_VOLTAGES_CONFIG, value, V_TICK_DEFAULT);
374     }
getClickVolLevels(std::array<uint32_t,2> * value)375     bool getClickVolLevels(std::array<uint32_t, 2> *value) override {
376         if (getPersist(CLICK_VOLTAGES_CONFIG, value)) {
377             return true;
378         }
379         return getProperty(CLICK_VOLTAGES_CONFIG, value, V_CLICK_DEFAULT);
380     }
getLongVolLevels(std::array<uint32_t,2> * value)381     bool getLongVolLevels(std::array<uint32_t, 2> *value) override {
382         if (getPersist(LONG_VOLTAGES_CONFIG, value)) {
383             return true;
384         }
385         return getProperty(LONG_VOLTAGES_CONFIG, value, V_LONG_DEFAULT);
386     }
isChirpEnabled()387     bool isChirpEnabled() override {
388         return utils::getProperty("persist.vendor.vibrator.hal.chirp.enabled", false);
389     }
getSupportedPrimitives(uint32_t * value)390     bool getSupportedPrimitives(uint32_t *value) override {
391         return getProperty("supported_primitives", value, (uint32_t)0);
392     }
isF0CompEnabled()393     bool isF0CompEnabled() override {
394         bool value;
395         getProperty("f0.comp.enabled", &value, true);
396         return value;
397     }
isRedcCompEnabled()398     bool isRedcCompEnabled() override {
399         bool value;
400         getProperty("redc.comp.enabled", &value, false);
401         return value;
402     }
debug(int fd)403     void debug(int fd) override { HwCalBase::debug(fd); }
404 };
405 
406 }  // namespace vibrator
407 }  // namespace hardware
408 }  // namespace android
409 }  // namespace aidl
410