/*
 * Copyright (c) 2022 Grant Ramsay <grant.ramsay@hotmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT espressif_esp32_mdio

#include <soc.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/mdio.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

#include <esp_mac.h>
#include <hal/emac_hal.h>
#include <hal/emac_ll.h>

LOG_MODULE_REGISTER(mdio_esp32, CONFIG_MDIO_LOG_LEVEL);

#define PHY_OPERATION_TIMEOUT_US 1000

struct mdio_esp32_dev_data {
	struct k_sem sem;
	emac_hal_context_t hal;
};

struct mdio_esp32_dev_config {
	const struct pinctrl_dev_config *pcfg;
};

static int mdio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad,
			 bool write, uint16_t data_in, uint16_t *data_out)
{
	struct mdio_esp32_dev_data *const dev_data = dev->data;

	k_sem_take(&dev_data->sem, K_FOREVER);

	if (emac_ll_is_mii_busy(dev_data->hal.mac_regs)) {
		LOG_ERR("phy busy");
		k_sem_give(&dev_data->sem);
		return -EBUSY;
	}

	if (write) {
		emac_ll_set_phy_data(dev_data->hal.mac_regs, data_in);
	}
	emac_hal_set_phy_cmd(&dev_data->hal, prtad, devad, write);

	/* Poll until operation complete */
	bool success = false;

	for (uint32_t t_us = 0; t_us < PHY_OPERATION_TIMEOUT_US; t_us += 100) {
		k_sleep(K_USEC(100));
		if (!emac_ll_is_mii_busy(dev_data->hal.mac_regs)) {
			success = true;
			break;
		}
	}
	if (!success) {
		LOG_ERR("phy timeout");
		k_sem_give(&dev_data->sem);
		return -ETIMEDOUT;
	}

	if (!write && data_out != NULL) {
		*data_out = emac_ll_get_phy_data(dev_data->hal.mac_regs);
	}

	k_sem_give(&dev_data->sem);

	return 0;
}

static int mdio_esp32_read(const struct device *dev, uint8_t prtad, uint8_t devad,
			 uint16_t *data)
{
	return mdio_transfer(dev, prtad, devad, false, 0, data);

}

static int mdio_esp32_write(const struct device *dev, uint8_t prtad,
			  uint8_t devad, uint16_t data)
{
	return mdio_transfer(dev, prtad, devad, true, data, NULL);
}

static void mdio_esp32_bus_enable(const struct device *dev)
{
	ARG_UNUSED(dev);
}

static void mdio_esp32_bus_disable(const struct device *dev)
{
	ARG_UNUSED(dev);
}

static int mdio_esp32_initialize(const struct device *dev)
{
	const struct mdio_esp32_dev_config *const cfg = dev->config;
	struct mdio_esp32_dev_data *const dev_data = dev->data;
	int res;

	k_sem_init(&dev_data->sem, 1, 1);

	res = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
	if (res != 0) {
		goto err;
	}

	const struct device *clock_dev =
		DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_NODELABEL(mdio)));
	clock_control_subsys_t clock_subsys =
		(clock_control_subsys_t)DT_CLOCKS_CELL(DT_NODELABEL(mdio), offset);

	res = clock_control_on(clock_dev, clock_subsys);
	if (res != 0) {
		goto err;
	}

	/* Only the mac registers are required for MDIO */
	dev_data->hal.mac_regs = &EMAC_MAC;

	/* Init MDIO clock */
	emac_hal_set_csr_clock_range(&dev_data->hal, esp_clk_apb_freq());

	return 0;

err:
	return res;
}

static const struct mdio_driver_api mdio_esp32_driver_api = {
	.read = mdio_esp32_read,
	.write = mdio_esp32_write,
	.bus_enable = mdio_esp32_bus_enable,
	.bus_disable = mdio_esp32_bus_disable,
};

#define MDIO_ESP32_CONFIG(n)						\
static const struct mdio_esp32_dev_config mdio_esp32_dev_config_##n = {	\
	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),			\
};

#define MDIO_ESP32_PROTOCOL_ASSERT(n)					\
	BUILD_ASSERT(DT_INST_ENUM_IDX(n, protocol) == CLAUSE_22,	\
		     "ESP32 MDIO only supports CLAUSE_22 protocol")

#define MDIO_ESP32_DEVICE(n)						\
	MDIO_ESP32_PROTOCOL_ASSERT(n);					\
	PINCTRL_DT_INST_DEFINE(n);					\
	MDIO_ESP32_CONFIG(n);						\
	static struct mdio_esp32_dev_data mdio_esp32_dev_data##n;	\
	DEVICE_DT_INST_DEFINE(n,					\
			      &mdio_esp32_initialize,			\
			      NULL,					\
			      &mdio_esp32_dev_data##n,			\
			      &mdio_esp32_dev_config_##n, POST_KERNEL,	\
			      CONFIG_MDIO_INIT_PRIORITY,		\
			      &mdio_esp32_driver_api);

DT_INST_FOREACH_STATUS_OKAY(MDIO_ESP32_DEVICE)
