// SPDX-License-Identifier: GPL-2.0
/*
 * HMS Profinet Client Driver
 *
 * Copyright (C) 2018 Arcx Inc
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>

/* move to <linux/fieldbus_dev.h> when taking this out of staging */
#include "../fieldbus_dev.h"

/* move to <linux/anybuss-client.h> when taking this out of staging */
#include "anybuss-client.h"

#define PROFI_DPRAM_SIZE	512

/*
 * ---------------------------------------------------------------
 * Anybus Profinet mailbox messages - definitions
 * ---------------------------------------------------------------
 * note that we're depending on the layout of these structures being
 * exactly as advertised.
 */

struct msg_mac_addr {
	u8 addr[6];
};

struct profi_priv {
	struct fieldbus_dev fbdev;
	struct anybuss_client *client;
	struct mutex enable_lock; /* serializes card enable */
	bool power_on;
};

static ssize_t
profi_read_area(struct fieldbus_dev *fbdev, char __user *buf, size_t size,
		loff_t *offset)
{
	struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev);

	return anybuss_read_output(priv->client, buf, size, offset);
}

static ssize_t
profi_write_area(struct fieldbus_dev *fbdev, const char __user *buf,
		 size_t size, loff_t *offset)
{
	struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev);

	return anybuss_write_input(priv->client, buf, size, offset);
}

static int profi_id_get(struct fieldbus_dev *fbdev, char *buf,
			size_t max_size)
{
	struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev);
	struct msg_mac_addr response;
	int ret;

	ret = anybuss_recv_msg(priv->client, 0x0010, &response,
			       sizeof(response));
	if (ret < 0)
		return ret;
	return snprintf(buf, max_size, "%02X:%02X:%02X:%02X:%02X:%02X\n",
		response.addr[0], response.addr[1],
		response.addr[2], response.addr[3],
		response.addr[4], response.addr[5]);
}

static bool profi_enable_get(struct fieldbus_dev *fbdev)
{
	struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev);
	bool power_on;

	mutex_lock(&priv->enable_lock);
	power_on = priv->power_on;
	mutex_unlock(&priv->enable_lock);

	return power_on;
}

static int __profi_enable(struct profi_priv *priv)
{
	int ret;
	struct anybuss_client *client = priv->client;
	/* Initialization Sequence, Generic Anybus Mode */
	const struct anybuss_memcfg mem_cfg = {
		.input_io = 220,
		.input_dpram = PROFI_DPRAM_SIZE,
		.input_total = PROFI_DPRAM_SIZE,
		.output_io = 220,
		.output_dpram = PROFI_DPRAM_SIZE,
		.output_total = PROFI_DPRAM_SIZE,
		.offl_mode = AB_OFFL_MODE_CLEAR,
	};

	/*
	 * switch anybus off then on, this ensures we can do a complete
	 * configuration cycle in case anybus was already on.
	 */
	anybuss_set_power(client, false);
	ret = anybuss_set_power(client, true);
	if (ret)
		goto err;
	ret = anybuss_start_init(client, &mem_cfg);
	if (ret)
		goto err;
	ret = anybuss_finish_init(client);
	if (ret)
		goto err;
	priv->power_on = true;
	return 0;

err:
	anybuss_set_power(client, false);
	priv->power_on = false;
	return ret;
}

static int __profi_disable(struct profi_priv *priv)
{
	struct anybuss_client *client = priv->client;

	anybuss_set_power(client, false);
	priv->power_on = false;
	return 0;
}

static int profi_simple_enable(struct fieldbus_dev *fbdev, bool enable)
{
	int ret;
	struct profi_priv *priv = container_of(fbdev, struct profi_priv, fbdev);

	mutex_lock(&priv->enable_lock);
	if (enable)
		ret = __profi_enable(priv);
	else
		ret = __profi_disable(priv);
	mutex_unlock(&priv->enable_lock);

	return ret;
}

static void profi_on_area_updated(struct anybuss_client *client)
{
	struct profi_priv *priv = anybuss_get_drvdata(client);

	fieldbus_dev_area_updated(&priv->fbdev);
}

static void profi_on_online_changed(struct anybuss_client *client, bool online)
{
	struct profi_priv *priv = anybuss_get_drvdata(client);

	fieldbus_dev_online_changed(&priv->fbdev, online);
}

static int profinet_probe(struct anybuss_client *client)
{
	struct profi_priv *priv;
	struct device *dev = &client->dev;
	int err;

	client->on_area_updated = profi_on_area_updated;
	client->on_online_changed = profi_on_online_changed;
	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	mutex_init(&priv->enable_lock);
	priv->client = client;
	priv->fbdev.read_area_sz = PROFI_DPRAM_SIZE;
	priv->fbdev.write_area_sz = PROFI_DPRAM_SIZE;
	priv->fbdev.card_name = "HMS Profinet IRT (Anybus-S)";
	priv->fbdev.fieldbus_type = FIELDBUS_DEV_TYPE_PROFINET;
	priv->fbdev.read_area = profi_read_area;
	priv->fbdev.write_area = profi_write_area;
	priv->fbdev.fieldbus_id_get = profi_id_get;
	priv->fbdev.enable_get = profi_enable_get;
	priv->fbdev.simple_enable_set = profi_simple_enable;
	priv->fbdev.parent = dev;
	err = fieldbus_dev_register(&priv->fbdev);
	if (err < 0)
		return err;
	dev_info(dev, "card detected, registered as %s",
		 dev_name(priv->fbdev.dev));
	anybuss_set_drvdata(client, priv);

	return 0;
}

static int profinet_remove(struct anybuss_client *client)
{
	struct profi_priv *priv = anybuss_get_drvdata(client);

	fieldbus_dev_unregister(&priv->fbdev);
	return 0;
}

static struct anybuss_client_driver profinet_driver = {
	.probe = profinet_probe,
	.remove = profinet_remove,
	.driver		= {
		.name   = "hms-profinet",
		.owner	= THIS_MODULE,
	},
	.anybus_id = 0x0089,
};

static int __init profinet_init(void)
{
	return anybuss_client_driver_register(&profinet_driver);
}
module_init(profinet_init);

static void __exit profinet_exit(void)
{
	return anybuss_client_driver_unregister(&profinet_driver);
}
module_exit(profinet_exit);

MODULE_AUTHOR("Sven Van Asbroeck <TheSven73@gmail.com>");
MODULE_DESCRIPTION("HMS Profinet IRT Driver (Anybus-S)");
MODULE_LICENSE("GPL v2");
