// SPDX-License-Identifier: GPL-2.0-only
/*
 * SDIO interface.
 *
 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
 * Copyright (c) 2010, ST-Ericsson
 */
#include <linux/module.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/card.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
#include <linux/align.h>

#include "bus.h"
#include "wfx.h"
#include "hwio.h"
#include "main.h"
#include "bh.h"

static const struct wfx_platform_data pdata_wf200 = {
	.file_fw = "wfx/wfm_wf200",
	.file_pds = "wfx/wf200.pds",
};

static const struct wfx_platform_data pdata_brd4001a = {
	.file_fw = "wfx/wfm_wf200",
	.file_pds = "wfx/brd4001a.pds",
};

static const struct wfx_platform_data pdata_brd8022a = {
	.file_fw = "wfx/wfm_wf200",
	.file_pds = "wfx/brd8022a.pds",
};

static const struct wfx_platform_data pdata_brd8023a = {
	.file_fw = "wfx/wfm_wf200",
	.file_pds = "wfx/brd8023a.pds",
};

struct wfx_sdio_priv {
	struct sdio_func *func;
	struct wfx_dev *core;
	u8 buf_id_tx;
	u8 buf_id_rx;
	int of_irq;
};

static int wfx_sdio_copy_from_io(void *priv, unsigned int reg_id, void *dst, size_t count)
{
	struct wfx_sdio_priv *bus = priv;
	unsigned int sdio_addr = reg_id << 2;
	int ret;

	WARN(reg_id > 7, "chip only has 7 registers");
	WARN(!IS_ALIGNED((uintptr_t)dst, 4), "unaligned buffer address");
	WARN(!IS_ALIGNED(count, 4), "unaligned buffer size");

	/* Use queue mode buffers */
	if (reg_id == WFX_REG_IN_OUT_QUEUE)
		sdio_addr |= (bus->buf_id_rx + 1) << 7;
	ret = sdio_memcpy_fromio(bus->func, dst, sdio_addr, count);
	if (!ret && reg_id == WFX_REG_IN_OUT_QUEUE)
		bus->buf_id_rx = (bus->buf_id_rx + 1) % 4;

	return ret;
}

static int wfx_sdio_copy_to_io(void *priv, unsigned int reg_id, const void *src, size_t count)
{
	struct wfx_sdio_priv *bus = priv;
	unsigned int sdio_addr = reg_id << 2;
	int ret;

	WARN(reg_id > 7, "chip only has 7 registers");
	WARN(!IS_ALIGNED((uintptr_t)src, 4), "unaligned buffer address");
	WARN(!IS_ALIGNED(count, 4), "unaligned buffer size");

	/* Use queue mode buffers */
	if (reg_id == WFX_REG_IN_OUT_QUEUE)
		sdio_addr |= bus->buf_id_tx << 7;
	/* FIXME: discards 'const' qualifier for src */
	ret = sdio_memcpy_toio(bus->func, sdio_addr, (void *)src, count);
	if (!ret && reg_id == WFX_REG_IN_OUT_QUEUE)
		bus->buf_id_tx = (bus->buf_id_tx + 1) % 32;

	return ret;
}

static void wfx_sdio_lock(void *priv)
{
	struct wfx_sdio_priv *bus = priv;

	sdio_claim_host(bus->func);
}

static void wfx_sdio_unlock(void *priv)
{
	struct wfx_sdio_priv *bus = priv;

	sdio_release_host(bus->func);
}

static void wfx_sdio_irq_handler(struct sdio_func *func)
{
	struct wfx_sdio_priv *bus = sdio_get_drvdata(func);

	wfx_bh_request_rx(bus->core);
}

static irqreturn_t wfx_sdio_irq_handler_ext(int irq, void *priv)
{
	struct wfx_sdio_priv *bus = priv;

	sdio_claim_host(bus->func);
	wfx_bh_request_rx(bus->core);
	sdio_release_host(bus->func);
	return IRQ_HANDLED;
}

static int wfx_sdio_irq_subscribe(void *priv)
{
	struct wfx_sdio_priv *bus = priv;
	u32 flags;
	int ret;
	u8 cccr;

	if (!bus->of_irq) {
		sdio_claim_host(bus->func);
		ret = sdio_claim_irq(bus->func, wfx_sdio_irq_handler);
		sdio_release_host(bus->func);
		return ret;
	}

	flags = irq_get_trigger_type(bus->of_irq);
	if (!flags)
		flags = IRQF_TRIGGER_HIGH;
	flags |= IRQF_ONESHOT;
	ret = devm_request_threaded_irq(&bus->func->dev, bus->of_irq, NULL,
					wfx_sdio_irq_handler_ext, flags, "wfx", bus);
	if (ret)
		return ret;
	sdio_claim_host(bus->func);
	cccr = sdio_f0_readb(bus->func, SDIO_CCCR_IENx, NULL);
	cccr |= BIT(0);
	cccr |= BIT(bus->func->num);
	sdio_f0_writeb(bus->func, cccr, SDIO_CCCR_IENx, NULL);
	sdio_release_host(bus->func);
	return 0;
}

static int wfx_sdio_irq_unsubscribe(void *priv)
{
	struct wfx_sdio_priv *bus = priv;
	int ret;

	if (bus->of_irq)
		devm_free_irq(&bus->func->dev, bus->of_irq, bus);
	sdio_claim_host(bus->func);
	ret = sdio_release_irq(bus->func);
	sdio_release_host(bus->func);
	return ret;
}

static size_t wfx_sdio_align_size(void *priv, size_t size)
{
	struct wfx_sdio_priv *bus = priv;

	return sdio_align_size(bus->func, size);
}

static const struct wfx_hwbus_ops wfx_sdio_hwbus_ops = {
	.copy_from_io    = wfx_sdio_copy_from_io,
	.copy_to_io      = wfx_sdio_copy_to_io,
	.irq_subscribe   = wfx_sdio_irq_subscribe,
	.irq_unsubscribe = wfx_sdio_irq_unsubscribe,
	.lock            = wfx_sdio_lock,
	.unlock          = wfx_sdio_unlock,
	.align_size      = wfx_sdio_align_size,
};

static const struct of_device_id wfx_sdio_of_match[] = {
	{ .compatible = "silabs,wf200",    .data = &pdata_wf200 },
	{ .compatible = "silabs,brd4001a", .data = &pdata_brd4001a },
	{ .compatible = "silabs,brd8022a", .data = &pdata_brd8022a },
	{ .compatible = "silabs,brd8023a", .data = &pdata_brd8023a },
	{ },
};
MODULE_DEVICE_TABLE(of, wfx_sdio_of_match);

static int wfx_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
{
	const struct wfx_platform_data *pdata = of_device_get_match_data(&func->dev);
	struct device_node *np = func->dev.of_node;
	struct wfx_sdio_priv *bus;
	int ret;

	if (func->num != 1) {
		dev_err(&func->dev, "SDIO function number is %d while it should always be 1 (unsupported chip?)\n",
			func->num);
		return -ENODEV;
	}

	if (!pdata) {
		dev_warn(&func->dev, "no compatible device found in DT\n");
		return -ENODEV;
	}

	bus = devm_kzalloc(&func->dev, sizeof(*bus), GFP_KERNEL);
	if (!bus)
		return -ENOMEM;

	bus->func = func;
	bus->of_irq = irq_of_parse_and_map(np, 0);
	sdio_set_drvdata(func, bus);

	sdio_claim_host(func);
	ret = sdio_enable_func(func);
	/* Block of 64 bytes is more efficient than 512B for frame sizes < 4k */
	sdio_set_block_size(func, 64);
	sdio_release_host(func);
	if (ret)
		return ret;

	bus->core = wfx_init_common(&func->dev, pdata, &wfx_sdio_hwbus_ops, bus);
	if (!bus->core) {
		ret = -EIO;
		goto sdio_release;
	}

	ret = wfx_probe(bus->core);
	if (ret)
		goto sdio_release;

	return 0;

sdio_release:
	sdio_claim_host(func);
	sdio_disable_func(func);
	sdio_release_host(func);
	return ret;
}

static void wfx_sdio_remove(struct sdio_func *func)
{
	struct wfx_sdio_priv *bus = sdio_get_drvdata(func);

	wfx_release(bus->core);
	sdio_claim_host(func);
	sdio_disable_func(func);
	sdio_release_host(func);
}

static const struct sdio_device_id wfx_sdio_ids[] = {
	/* WF200 does not have official VID/PID */
	{ SDIO_DEVICE(0x0000, 0x1000) },
	{ },
};
MODULE_DEVICE_TABLE(sdio, wfx_sdio_ids);

struct sdio_driver wfx_sdio_driver = {
	.name = "wfx-sdio",
	.id_table = wfx_sdio_ids,
	.probe = wfx_sdio_probe,
	.remove = wfx_sdio_remove,
	.drv = {
		.owner = THIS_MODULE,
		.of_match_table = wfx_sdio_of_match,
	}
};
