123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt/*
223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * Copyright (C) 2017 The Android Open Source Project
323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt *
423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License");
523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * you may not use this file except in compliance with the License.
623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * You may obtain a copy of the License at
723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt *
823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt *      http://www.apache.org/licenses/LICENSE-2.0
923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt *
1023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * Unless required by applicable law or agreed to in writing, software
1123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS,
1223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * See the License for the specific language governing permissions and
1423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt * limitations under the License.
1523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt */
1623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
1723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <stdlib.h>
1823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <string.h>
1923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
2023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <eventnums.h>
2123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <gpio.h>
2223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <hostIntf.h>
2323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <leds_gpio.h>
2423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <nanohubPacket.h>
2523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <sensors.h>
2623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <seos.h>
2723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <plat/gpio.h>
2823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <plat/exti.h>
2923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <plat/syscfg.h>
3023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#include <variant/variant.h>
3123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
3223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#define LEDS_GPIO_APP_ID	APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 20)
3323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#define LEDS_GPIO_APP_VERSION	1
3423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
3523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt#define DBG_ENABLE		0
3623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
3723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic struct LedsTask
3823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt{
3923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    struct Gpio *led[LEDS_GPIO_MAX];
4023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    uint32_t num;
4123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
4223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    uint32_t id;
4323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    uint32_t sHandle;
4423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt} mTask;
4523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
4623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic bool sensorConfigLedsGpio(void *cfgData, void *buf)
4723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt{
4823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    struct LedsCfg *lcfg = (struct LedsCfg *)cfgData;
4923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
5023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    if (lcfg->led_num >= mTask.num) {
5123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        osLog(LOG_INFO, "Wrong led number %"PRIu32"\n", lcfg->led_num);
5223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        return false;
5323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    }
5423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    gpioSet(mTask.led[lcfg->led_num], lcfg->value ? 1 : 0);
5523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    osLog(LOG_INFO, "Set led[%"PRIu32"]=%"PRIu32"\n", lcfg->led_num, lcfg->value);
5623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    return true;
5723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt}
5823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
5923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic bool sensorSelfTestLedsGpio(void *buf)
6023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt{
6123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    uint32_t i;
6223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
6323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    gpioSet(mTask.led[0], 1);
6423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    for (i=1; i < mTask.num; i++) {
6523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        gpioSet(mTask.led[i-1], 0);
6623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        gpioSet(mTask.led[i], 1);
6723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    }
6823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    gpioSet(mTask.led[i-1], 0);
6923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    return true;
7023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt}
7123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
7223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic const struct SensorInfo sensorInfoLedsGpio = {
7323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    .sensorName = "Leds-Gpio",
7423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    .sensorType = SENS_TYPE_LEDS,
7523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt};
7623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
7723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic const struct SensorOps sensorOpsLedsGpio = {
7823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    .sensorCfgData = sensorConfigLedsGpio,
7923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    .sensorSelfTest = sensorSelfTestLedsGpio,
8023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt};
8123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
8223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic void handleEvent(uint32_t evtType, const void *evtData)
8323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt{
8423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    switch (evtType) {
8523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    case EVT_APP_START:
8623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        osEventUnsubscribe(mTask.id, EVT_APP_START);
8723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        /* Test leds */
8823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        if (DBG_ENABLE)
8923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt            sensorSelfTest(mTask.sHandle);
9023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        osLog(LOG_INFO, "[Leds-Gpio] detected\n");
9123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        break;
9223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    }
9323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt}
9423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
9523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic bool startTask(uint32_t taskId)
9623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt{
9723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    const struct LedsGpio *leds;
9823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    struct Gpio *led;
9923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    uint32_t i;
10023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
10123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    mTask.id = taskId;
10223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    mTask.num = 0;
10323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
10423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    leds = ledsGpioBoardCfg();
10523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    for (i=0; i < leds->num && i < LEDS_GPIO_MAX; i++) {
10623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        led = gpioRequest(leds->leds_array[i]);
10723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        if (!led)
10823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt            continue;
10923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        mTask.led[mTask.num++] = led;
11023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        gpioConfigOutput(led, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_OUT_PUSH_PULL, 0);
11123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    }
11223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    if (mTask.num == 0)
11323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        return false;
11423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    mTask.sHandle = sensorRegister(&sensorInfoLedsGpio, &sensorOpsLedsGpio, NULL, true);
11523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    osEventSubscribe(taskId, EVT_APP_START);
11623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    return true;
11723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt}
11823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
11923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidtstatic void endTask(void)
12023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt{
12123110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    uint32_t i;
12223110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
12323110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    sensorUnregister(mTask.sHandle);
12423110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    for (i=0; i < mTask.num; i++) {
12523110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        gpioSet(mTask.led[i], 0);
12623110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt        gpioRelease(mTask.led[i]);
12723110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt    }
12823110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt}
12923110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry Shmidt
13023110ab9ec0777d0cce0fbe14a6bf90bda55989cDmitry ShmidtINTERNAL_APP_INIT(LEDS_GPIO_APP_ID, LEDS_GPIO_APP_VERSION, startTask, endTask, handleEvent);
131