/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <sys/printk.h>
#include "dummy_parent.h"
#include "dummy_driver.h"

static struct k_poll_event async_evt;
u32_t device_power_state;
static struct device *parent;

static int dummy_open(struct device *dev)
{
	int ret;
	int signaled = 0, result;

	printk("open()\n");

	/* Make sure parent is resumed */
	ret = device_pm_get_sync(parent);
	if (ret < 0) {
		return ret;
	}

	ret = device_pm_get(dev);
	if (ret < 0) {
		return ret;
	}

	printk("Async wakeup request queued\n");

	do {
		(void)k_poll(&async_evt, 1, K_FOREVER);
		k_poll_signal_check(&dev->config->pm->signal,
						&signaled, &result);
	} while (!signaled);

	async_evt.state = K_POLL_STATE_NOT_READY;
	k_poll_signal_reset(&dev->config->pm->signal);

	if (result == DEVICE_PM_ACTIVE_STATE) {
		printk("Dummy device resumed\n");
		ret = 0;
	} else {
		printk("Dummy device Not resumed\n");
		ret = -1;
	}

	return ret;
}

static int dummy_read(struct device *dev, u32_t *val)
{
	struct dummy_parent_api *api;
	int ret;

	printk("read()\n");

	api = (struct dummy_parent_api *)parent->driver_api;
	ret = api->transfer(parent, DUMMY_PARENT_RD, val);
	return ret;
}

static int dummy_write(struct device *dev, u32_t val)
{
	struct dummy_parent_api *api;
	int ret;

	printk("write()\n");
	api = (struct dummy_parent_api *)parent->driver_api;
	ret = api->transfer(parent, DUMMY_PARENT_WR, &val);
	return ret;
}

static int dummy_close(struct device *dev)
{
	int ret;

	printk("close()\n");
	ret = device_pm_put_sync(dev);
	if (ret == 1) {
		printk("Async suspend request ququed\n");
	}

	/* Parent can be suspended */
	if (parent) {
		device_pm_put(parent);
	}

	return ret;
}

static u32_t dummy_get_power_state(struct device *dev)
{
	return device_power_state;
}

static int dummy_suspend(struct device *dev)
{
	printk("child suspending..\n");
	device_power_state = DEVICE_PM_SUSPEND_STATE;

	return 0;
}

static int dummy_resume_from_suspend(struct device *dev)
{
	printk("child resuming..\n");
	device_power_state = DEVICE_PM_ACTIVE_STATE;

	return 0;
}

static int dummy_device_pm_ctrl(struct device *dev, u32_t ctrl_command,
				void *context, device_pm_cb cb, void *arg)
{
	int ret = 0;

	switch (ctrl_command) {
	case DEVICE_PM_SET_POWER_STATE:
		if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
			ret = dummy_resume_from_suspend(dev);
		} else {
			ret = dummy_suspend(dev);
		}
		break;
	case DEVICE_PM_GET_POWER_STATE:
		*((u32_t *)context) = dummy_get_power_state(dev);
		break;
	default:
		ret = -EINVAL;

	}

	cb(dev, ret, context, arg);

	return ret;
}

static const struct dummy_driver_api funcs = {
	.open = dummy_open,
	.read = dummy_read,
	.write = dummy_write,
	.close = dummy_close,
};

int dummy_init(struct device *dev)
{
	parent = device_get_binding(DUMMY_PARENT_NAME);
	if (!parent) {
		printk("parent not found\n");
	}

	device_pm_enable(dev);
	device_power_state = DEVICE_PM_ACTIVE_STATE;

	k_poll_event_init(&async_evt, K_POLL_TYPE_SIGNAL,
			K_POLL_MODE_NOTIFY_ONLY, &dev->config->pm->signal);
	return 0;
}

DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init,
		    dummy_device_pm_ctrl, NULL, NULL, APPLICATION,
		    CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
