// SPDX-License-Identifier: GPL-2.0
/*
 * Generic serial GNSS receiver driver
 *
 * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
 */

#include <linux/errno.h>
#include <linux/gnss.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/serdev.h>
#include <linux/slab.h>

#include "serial.h"

static int gnss_serial_open(struct gnss_device *gdev)
{
	struct gnss_serial *gserial = gnss_get_drvdata(gdev);
	struct serdev_device *serdev = gserial->serdev;
	int ret;

	ret = serdev_device_open(serdev);
	if (ret)
		return ret;

	serdev_device_set_baudrate(serdev, gserial->speed);
	serdev_device_set_flow_control(serdev, false);

	ret = pm_runtime_get_sync(&serdev->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(&serdev->dev);
		goto err_close;
	}

	return 0;

err_close:
	serdev_device_close(serdev);

	return ret;
}

static void gnss_serial_close(struct gnss_device *gdev)
{
	struct gnss_serial *gserial = gnss_get_drvdata(gdev);
	struct serdev_device *serdev = gserial->serdev;

	serdev_device_close(serdev);

	pm_runtime_put(&serdev->dev);
}

static int gnss_serial_write_raw(struct gnss_device *gdev,
		const unsigned char *buf, size_t count)
{
	struct gnss_serial *gserial = gnss_get_drvdata(gdev);
	struct serdev_device *serdev = gserial->serdev;
	int ret;

	/* write is only buffered synchronously */
	ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT);
	if (ret < 0 || ret < count)
		return ret;

	/* FIXME: determine if interrupted? */
	serdev_device_wait_until_sent(serdev, 0);

	return count;
}

static const struct gnss_operations gnss_serial_gnss_ops = {
	.open		= gnss_serial_open,
	.close		= gnss_serial_close,
	.write_raw	= gnss_serial_write_raw,
};

static ssize_t gnss_serial_receive_buf(struct serdev_device *serdev,
				       const u8 *buf, size_t count)
{
	struct gnss_serial *gserial = serdev_device_get_drvdata(serdev);
	struct gnss_device *gdev = gserial->gdev;

	return gnss_insert_raw(gdev, buf, count);
}

static const struct serdev_device_ops gnss_serial_serdev_ops = {
	.receive_buf	= gnss_serial_receive_buf,
	.write_wakeup	= serdev_device_write_wakeup,
};

static int gnss_serial_set_power(struct gnss_serial *gserial,
					enum gnss_serial_pm_state state)
{
	if (!gserial->ops || !gserial->ops->set_power)
		return 0;

	return gserial->ops->set_power(gserial, state);
}

/*
 * FIXME: need to provide subdriver defaults or separate dt parsing from
 * allocation.
 */
static int gnss_serial_parse_dt(struct serdev_device *serdev)
{
	struct gnss_serial *gserial = serdev_device_get_drvdata(serdev);
	struct device_node *node = serdev->dev.of_node;
	u32 speed = 4800;

	of_property_read_u32(node, "current-speed", &speed);

	gserial->speed = speed;

	return 0;
}

struct gnss_serial *gnss_serial_allocate(struct serdev_device *serdev,
						size_t data_size)
{
	struct gnss_serial *gserial;
	struct gnss_device *gdev;
	int ret;

	gserial = kzalloc(sizeof(*gserial) + data_size, GFP_KERNEL);
	if (!gserial)
		return ERR_PTR(-ENOMEM);

	gdev = gnss_allocate_device(&serdev->dev);
	if (!gdev) {
		ret = -ENOMEM;
		goto err_free_gserial;
	}

	gdev->ops = &gnss_serial_gnss_ops;
	gnss_set_drvdata(gdev, gserial);

	gserial->serdev = serdev;
	gserial->gdev = gdev;

	serdev_device_set_drvdata(serdev, gserial);
	serdev_device_set_client_ops(serdev, &gnss_serial_serdev_ops);

	ret = gnss_serial_parse_dt(serdev);
	if (ret)
		goto err_put_device;

	return gserial;

err_put_device:
	gnss_put_device(gserial->gdev);
err_free_gserial:
	kfree(gserial);

	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(gnss_serial_allocate);

void gnss_serial_free(struct gnss_serial *gserial)
{
	gnss_put_device(gserial->gdev);
	kfree(gserial);
}
EXPORT_SYMBOL_GPL(gnss_serial_free);

int gnss_serial_register(struct gnss_serial *gserial)
{
	struct serdev_device *serdev = gserial->serdev;
	int ret;

	if (IS_ENABLED(CONFIG_PM)) {
		pm_runtime_enable(&serdev->dev);
	} else {
		ret = gnss_serial_set_power(gserial, GNSS_SERIAL_ACTIVE);
		if (ret < 0)
			return ret;
	}

	ret = gnss_register_device(gserial->gdev);
	if (ret)
		goto err_disable_rpm;

	return 0;

err_disable_rpm:
	if (IS_ENABLED(CONFIG_PM))
		pm_runtime_disable(&serdev->dev);
	else
		gnss_serial_set_power(gserial, GNSS_SERIAL_OFF);

	return ret;
}
EXPORT_SYMBOL_GPL(gnss_serial_register);

void gnss_serial_deregister(struct gnss_serial *gserial)
{
	struct serdev_device *serdev = gserial->serdev;

	gnss_deregister_device(gserial->gdev);

	if (IS_ENABLED(CONFIG_PM))
		pm_runtime_disable(&serdev->dev);
	else
		gnss_serial_set_power(gserial, GNSS_SERIAL_OFF);
}
EXPORT_SYMBOL_GPL(gnss_serial_deregister);

#ifdef CONFIG_PM
static int gnss_serial_runtime_suspend(struct device *dev)
{
	struct gnss_serial *gserial = dev_get_drvdata(dev);

	return gnss_serial_set_power(gserial, GNSS_SERIAL_STANDBY);
}

static int gnss_serial_runtime_resume(struct device *dev)
{
	struct gnss_serial *gserial = dev_get_drvdata(dev);

	return gnss_serial_set_power(gserial, GNSS_SERIAL_ACTIVE);
}
#endif /* CONFIG_PM */

static int gnss_serial_prepare(struct device *dev)
{
	if (pm_runtime_suspended(dev))
		return 1;

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int gnss_serial_suspend(struct device *dev)
{
	struct gnss_serial *gserial = dev_get_drvdata(dev);
	int ret = 0;

	/*
	 * FIXME: serdev currently lacks support for managing the underlying
	 * device's wakeup settings. A workaround would be to close the serdev
	 * device here if it is open.
	 */

	if (!pm_runtime_suspended(dev))
		ret = gnss_serial_set_power(gserial, GNSS_SERIAL_STANDBY);

	return ret;
}

static int gnss_serial_resume(struct device *dev)
{
	struct gnss_serial *gserial = dev_get_drvdata(dev);
	int ret = 0;

	if (!pm_runtime_suspended(dev))
		ret = gnss_serial_set_power(gserial, GNSS_SERIAL_ACTIVE);

	return ret;
}
#endif /* CONFIG_PM_SLEEP */

const struct dev_pm_ops gnss_serial_pm_ops = {
	.prepare	= gnss_serial_prepare,
	SET_SYSTEM_SLEEP_PM_OPS(gnss_serial_suspend, gnss_serial_resume)
	SET_RUNTIME_PM_OPS(gnss_serial_runtime_suspend, gnss_serial_runtime_resume, NULL)
};
EXPORT_SYMBOL_GPL(gnss_serial_pm_ops);

MODULE_AUTHOR("Johan Hovold <johan@kernel.org>");
MODULE_DESCRIPTION("Generic serial GNSS receiver driver");
MODULE_LICENSE("GPL v2");
