blob: 9d76759a0aca16d50a85fdfa48c788b9782b96f0 [file] [log] [blame]
Ashutosh Joshi14986b02016-01-04 12:21:06 -08001/*
2 * Copyright (C) 2016 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
Trevor Bunkercc886fc2015-10-30 13:31:09 -070017#include <stdlib.h>
18#include <string.h>
19#include <float.h>
20
21#include <eventnums.h>
22#include <gpio.h>
23#include <heap.h>
24#include <hostIntf.h>
25#include <isr.h>
26#include <nanohubPacket.h>
27#include <sensors.h>
28#include <seos.h>
Trevor Bunkerba9f3532016-07-08 01:21:17 -070029#include <slab.h>
Trevor Bunkercc886fc2015-10-30 13:31:09 -070030#include <timer.h>
Alexey Polyudovf8053062016-07-12 18:45:05 -070031#include <plat/gpio.h>
32#include <plat/exti.h>
33#include <plat/syscfg.h>
34#include <variant/variant.h>
Trevor Bunkercc886fc2015-10-30 13:31:09 -070035
Alexey Polyudov54794372016-07-18 12:19:08 -070036#define VSYNC_APP_ID APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 7)
Trevor Bunkerba9f3532016-07-08 01:21:17 -070037#define VSYNC_APP_VERSION 2
38
39// This defines how many vsync events we could handle being backed up in the
40// queue. Use this to size our slab
Ben Fennema8efc9b92016-09-14 15:51:06 -070041#define MAX_VSYNC_EVENTS 4
42#define MAX_VSYNC_INT_LATENCY 1000 /* in ns */
Trevor Bunkerf2930ec2016-03-24 10:19:27 -070043
Trevor Bunkercc886fc2015-10-30 13:31:09 -070044#ifndef VSYNC_PIN
45#error "VSYNC_PIN is not defined; please define in variant.h"
46#endif
47
48#ifndef VSYNC_IRQ
49#error "VSYNC_IRQ is not defined; please define in variant.h"
50#endif
51
Ben Fennemaf53ebf92017-06-13 15:12:30 -070052#define VERBOSE_PRINT(fmt, ...) do { \
53 osLog(LOG_VERBOSE, "%s " fmt, "[VSYNC]", ##__VA_ARGS__); \
54 } while (0);
55
Trevor Bunkerf2930ec2016-03-24 10:19:27 -070056#define INFO_PRINT(fmt, ...) do { \
57 osLog(LOG_INFO, "%s " fmt, "[VSYNC]", ##__VA_ARGS__); \
58 } while (0);
59
Trevor Bunkerba9f3532016-07-08 01:21:17 -070060#define ERROR_PRINT(fmt, ...) INFO_PRINT("%s" fmt, "ERROR: ", ##__VA_ARGS__); \
61
Trevor Bunkerf2930ec2016-03-24 10:19:27 -070062#define DEBUG_PRINT(fmt, ...) do { \
63 if (enable_debug) { \
64 INFO_PRINT(fmt, ##__VA_ARGS__); \
65 } \
66 } while (0);
67
Antonio Borneo3be90c02016-07-04 15:46:32 +020068static const bool __attribute__((unused)) enable_debug = 0;
Trevor Bunkerf2930ec2016-03-24 10:19:27 -070069
Trevor Bunkercc886fc2015-10-30 13:31:09 -070070static struct SensorTask
71{
72 struct Gpio *pin;
73 struct ChainedIsr isr;
Trevor Bunkerba9f3532016-07-08 01:21:17 -070074 struct SlabAllocator *evtSlab;
75
Trevor Bunkercc886fc2015-10-30 13:31:09 -070076
77 uint32_t id;
78 uint32_t sensorHandle;
79
80 bool on;
81} mTask;
82
Trevor Bunkerba9f3532016-07-08 01:21:17 -070083static bool vsyncAllocateEvt(struct SingleAxisDataEvent **evPtr, uint64_t time)
84{
85 struct SingleAxisDataEvent *ev;
86
87 *evPtr = slabAllocatorAlloc(mTask.evtSlab);
88
89 ev = *evPtr;
90 if (!ev) {
91 ERROR_PRINT("slabAllocatorAlloc() failed\n");
92 return false;
93 }
94
95 memset(&ev->samples[0].firstSample, 0x00, sizeof(struct SensorFirstSample));
96 ev->referenceTime = time;
97 ev->samples[0].firstSample.numSamples = 1;
98 ev->samples[0].idata = 1;
99
100 return true;
101}
102
103static void vsyncFreeEvt(void *ptr)
104{
105 slabAllocatorFree(mTask.evtSlab, ptr);
106}
107
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700108static bool vsyncIsr(struct ChainedIsr *localIsr)
109{
110 struct SensorTask *data = container_of(localIsr, struct SensorTask, isr);
Trevor Bunkerba9f3532016-07-08 01:21:17 -0700111 struct SingleAxisDataEvent *ev;
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700112
113 if (!extiIsPendingGpio(data->pin)) {
114 return false;
115 }
116
117 if (data->on) {
Trevor Bunkerba9f3532016-07-08 01:21:17 -0700118 if (vsyncAllocateEvt(&ev, sensorGetTime())) {
Peng Xu10443d12016-09-13 17:29:10 -0700119 if (!osEnqueueEvtOrFree(sensorGetMyEventType(SENS_TYPE_VSYNC), ev, vsyncFreeEvt)) {
Trevor Bunkerba9f3532016-07-08 01:21:17 -0700120 ERROR_PRINT("osEnqueueEvtOrFree() failed\n");
121 }
122 }
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700123 }
124
125 extiClearPendingGpio(data->pin);
126 return true;
127}
128
129static bool enableInterrupt(struct Gpio *pin, struct ChainedIsr *isr)
130{
131 gpioConfigInput(pin, GPIO_SPEED_LOW, GPIO_PULL_NONE);
132 syscfgSetExtiPort(pin);
133 extiEnableIntGpio(pin, EXTI_TRIGGER_FALLING);
134 extiChainIsr(VSYNC_IRQ, isr);
135 return true;
136}
137
138static bool disableInterrupt(struct Gpio *pin, struct ChainedIsr *isr)
139{
140 extiUnchainIsr(VSYNC_IRQ, isr);
141 extiDisableIntGpio(pin);
142 return true;
143}
144
145static const struct SensorInfo mSensorInfo =
146{
Ben Fennema4d17cb52016-01-21 10:06:12 -0800147 .sensorName = "Camera Vsync",
148 .sensorType = SENS_TYPE_VSYNC,
Trevor Bunkerba9f3532016-07-08 01:21:17 -0700149 .numAxis = NUM_AXIS_ONE,
Ben Fennema4d17cb52016-01-21 10:06:12 -0800150 .interrupt = NANOHUB_INT_NONWAKEUP,
151 .minSamples = 20,
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700152};
153
Ben Fennemae7238152015-12-28 16:40:51 -0800154static bool vsyncPower(bool on, void *cookie)
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700155{
Ben Fennemaf53ebf92017-06-13 15:12:30 -0700156 VERBOSE_PRINT("power %d\n", on);
Trevor Bunkerf2930ec2016-03-24 10:19:27 -0700157
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700158 if (on) {
159 extiClearPendingGpio(mTask.pin);
160 enableInterrupt(mTask.pin, &mTask.isr);
161 } else {
162 disableInterrupt(mTask.pin, &mTask.isr);
163 extiClearPendingGpio(mTask.pin);
164 }
165
166 mTask.on = on;
167 sensorSignalInternalEvt(mTask.sensorHandle, SENSOR_INTERNAL_EVT_POWER_STATE_CHG, on, 0);
168 return true;
169}
170
Ben Fennemae7238152015-12-28 16:40:51 -0800171static bool vsyncFirmwareUpload(void *cookie)
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700172{
173 return sensorSignalInternalEvt(mTask.sensorHandle, SENSOR_INTERNAL_EVT_FW_STATE_CHG, 1, 0);
174}
175
Ben Fennemae7238152015-12-28 16:40:51 -0800176static bool vsyncSetRate(uint32_t rate, uint64_t latency, void *cookie)
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700177{
Ben Fennemaf53ebf92017-06-13 15:12:30 -0700178 VERBOSE_PRINT("setRate\n");
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700179 return sensorSignalInternalEvt(mTask.sensorHandle, SENSOR_INTERNAL_EVT_RATE_CHG, rate, latency);
180}
181
Ben Fennemae7238152015-12-28 16:40:51 -0800182static bool vsyncFlush(void *cookie)
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700183{
Ben Fennemaf53ebf92017-06-13 15:12:30 -0700184 VERBOSE_PRINT("flush\n");
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700185 return osEnqueueEvt(sensorGetMyEventType(SENS_TYPE_VSYNC), SENSOR_DATA_EVENT_FLUSH, NULL);
186}
187
188static const struct SensorOps mSensorOps =
189{
Ben Fennema4d17cb52016-01-21 10:06:12 -0800190 .sensorPower = vsyncPower,
191 .sensorFirmwareUpload = vsyncFirmwareUpload,
192 .sensorSetRate = vsyncSetRate,
193 .sensorFlush = vsyncFlush,
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700194};
195
196static void handleEvent(uint32_t evtType, const void* evtData)
197{
198}
199
200static bool startTask(uint32_t taskId)
201{
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700202 mTask.id = taskId;
Ben Fennemae7238152015-12-28 16:40:51 -0800203 mTask.sensorHandle = sensorRegister(&mSensorInfo, &mSensorOps, NULL, true);
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700204 mTask.pin = gpioRequest(VSYNC_PIN);
205 mTask.isr.func = vsyncIsr;
Ben Fennema8efc9b92016-09-14 15:51:06 -0700206 mTask.isr.maxLatencyNs = MAX_VSYNC_INT_LATENCY;
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700207
Trevor Bunkerba9f3532016-07-08 01:21:17 -0700208 mTask.evtSlab = slabAllocatorNew(sizeof(struct SingleAxisDataEvent) + sizeof(struct SingleAxisDataPoint), 4, MAX_VSYNC_EVENTS);
209 if (!mTask.evtSlab) {
210 ERROR_PRINT("slabAllocatorNew() failed\n");
211 return false;
212 }
213
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700214 return true;
215}
216
217static void endTask(void)
218{
219 disableInterrupt(mTask.pin, &mTask.isr);
220 extiUnchainIsr(VSYNC_IRQ, &mTask.isr);
221 extiClearPendingGpio(mTask.pin);
222 gpioRelease(mTask.pin);
223 sensorUnregister(mTask.sensorHandle);
Trevor Bunkercc886fc2015-10-30 13:31:09 -0700224}
225
Trevor Bunkerf2930ec2016-03-24 10:19:27 -0700226INTERNAL_APP_INIT(VSYNC_APP_ID, VSYNC_APP_VERSION, startTask, endTask, handleEvent);