/*
 * Support of SDHCI platform devices for Microchip PIC32.
 *
 * Copyright (C) 2015 Microchip
 * Andrei Pistirica, Paul Thacker
 *
 * Inspired by sdhci-pltfm.c
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/io.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include <linux/platform_data/sdhci-pic32.h>

#define SDH_SHARED_BUS_CTRL		0x000000E0
#define SDH_SHARED_BUS_NR_CLK_PINS_MASK	0x7
#define SDH_SHARED_BUS_NR_IRQ_PINS_MASK	0x30
#define SDH_SHARED_BUS_CLK_PINS		0x10
#define SDH_SHARED_BUS_IRQ_PINS		0x14
#define SDH_CAPS_SDH_SLOT_TYPE_MASK	0xC0000000
#define SDH_SLOT_TYPE_REMOVABLE		0x0
#define SDH_SLOT_TYPE_EMBEDDED		0x1
#define SDH_SLOT_TYPE_SHARED_BUS	0x2
#define SDHCI_CTRL_CDSSEL		0x80
#define SDHCI_CTRL_CDTLVL		0x40

#define ADMA_FIFO_RD_THSHLD	512
#define ADMA_FIFO_WR_THSHLD	512

struct pic32_sdhci_priv {
	struct platform_device	*pdev;
	struct clk *sys_clk;
	struct clk *base_clk;
};

static unsigned int pic32_sdhci_get_max_clock(struct sdhci_host *host)
{
	struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);

	return clk_get_rate(sdhci_pdata->base_clk);
}

static void pic32_sdhci_set_bus_width(struct sdhci_host *host, int width)
{
	u8 ctrl;

	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
	if (width == MMC_BUS_WIDTH_8) {
		ctrl &= ~SDHCI_CTRL_4BITBUS;
		if (host->version >= SDHCI_SPEC_300)
			ctrl |= SDHCI_CTRL_8BITBUS;
	} else {
		if (host->version >= SDHCI_SPEC_300)
			ctrl &= ~SDHCI_CTRL_8BITBUS;
		if (width == MMC_BUS_WIDTH_4)
			ctrl |= SDHCI_CTRL_4BITBUS;
		else
			ctrl &= ~SDHCI_CTRL_4BITBUS;
	}

	/* CD select and test bits must be set for errata workaround. */
	ctrl &= ~SDHCI_CTRL_CDTLVL;
	ctrl |= SDHCI_CTRL_CDSSEL;
	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}

static unsigned int pic32_sdhci_get_ro(struct sdhci_host *host)
{
	/*
	 * The SDHCI_WRITE_PROTECT bit is unstable on current hardware so we
	 * can't depend on its value in any way.
	 */
	return 0;
}

static const struct sdhci_ops pic32_sdhci_ops = {
	.get_max_clock = pic32_sdhci_get_max_clock,
	.set_clock = sdhci_set_clock,
	.set_bus_width = pic32_sdhci_set_bus_width,
	.reset = sdhci_reset,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
	.get_ro = pic32_sdhci_get_ro,
};

static const struct sdhci_pltfm_data sdhci_pic32_pdata = {
	.ops = &pic32_sdhci_ops,
	.quirks = SDHCI_QUIRK_NO_HISPD_BIT,
	.quirks2 = SDHCI_QUIRK2_NO_1_8_V,
};

static void pic32_sdhci_shared_bus(struct platform_device *pdev)
{
	struct sdhci_host *host = platform_get_drvdata(pdev);
	u32 bus = readl(host->ioaddr + SDH_SHARED_BUS_CTRL);
	u32 clk_pins = (bus & SDH_SHARED_BUS_NR_CLK_PINS_MASK) >> 0;
	u32 irq_pins = (bus & SDH_SHARED_BUS_NR_IRQ_PINS_MASK) >> 4;

	/* select first clock */
	if (clk_pins & 1)
		bus |= (1 << SDH_SHARED_BUS_CLK_PINS);

	/* select first interrupt */
	if (irq_pins & 1)
		bus |= (1 << SDH_SHARED_BUS_IRQ_PINS);

	writel(bus, host->ioaddr + SDH_SHARED_BUS_CTRL);
}

static int pic32_sdhci_probe_platform(struct platform_device *pdev,
				      struct pic32_sdhci_priv *pdata)
{
	int ret = 0;
	u32 caps_slot_type;
	struct sdhci_host *host = platform_get_drvdata(pdev);

	/* Check card slot connected on shared bus. */
	host->caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
	caps_slot_type = (host->caps & SDH_CAPS_SDH_SLOT_TYPE_MASK) >> 30;
	if (caps_slot_type == SDH_SLOT_TYPE_SHARED_BUS)
		pic32_sdhci_shared_bus(pdev);

	return ret;
}

static int pic32_sdhci_probe(struct platform_device *pdev)
{
	struct sdhci_host *host;
	struct sdhci_pltfm_host *pltfm_host;
	struct pic32_sdhci_priv *sdhci_pdata;
	struct pic32_sdhci_platform_data *plat_data;
	int ret;

	host = sdhci_pltfm_init(pdev, &sdhci_pic32_pdata,
				sizeof(struct pic32_sdhci_priv));
	if (IS_ERR(host)) {
		ret = PTR_ERR(host);
		goto err;
	}

	pltfm_host = sdhci_priv(host);
	sdhci_pdata = sdhci_pltfm_priv(pltfm_host);

	plat_data = pdev->dev.platform_data;
	if (plat_data && plat_data->setup_dma) {
		ret = plat_data->setup_dma(ADMA_FIFO_RD_THSHLD,
					   ADMA_FIFO_WR_THSHLD);
		if (ret)
			goto err_host;
	}

	sdhci_pdata->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
	if (IS_ERR(sdhci_pdata->sys_clk)) {
		ret = PTR_ERR(sdhci_pdata->sys_clk);
		dev_err(&pdev->dev, "Error getting clock\n");
		goto err_host;
	}

	ret = clk_prepare_enable(sdhci_pdata->sys_clk);
	if (ret) {
		dev_err(&pdev->dev, "Error enabling clock\n");
		goto err_host;
	}

	sdhci_pdata->base_clk = devm_clk_get(&pdev->dev, "base_clk");
	if (IS_ERR(sdhci_pdata->base_clk)) {
		ret = PTR_ERR(sdhci_pdata->base_clk);
		dev_err(&pdev->dev, "Error getting clock\n");
		goto err_sys_clk;
	}

	ret = clk_prepare_enable(sdhci_pdata->base_clk);
	if (ret) {
		dev_err(&pdev->dev, "Error enabling clock\n");
		goto err_base_clk;
	}

	ret = mmc_of_parse(host->mmc);
	if (ret)
		goto err_base_clk;

	ret = pic32_sdhci_probe_platform(pdev, sdhci_pdata);
	if (ret) {
		dev_err(&pdev->dev, "failed to probe platform!\n");
		goto err_base_clk;
	}

	ret = sdhci_add_host(host);
	if (ret)
		goto err_base_clk;

	dev_info(&pdev->dev, "Successfully added sdhci host\n");
	return 0;

err_base_clk:
	clk_disable_unprepare(sdhci_pdata->base_clk);
err_sys_clk:
	clk_disable_unprepare(sdhci_pdata->sys_clk);
err_host:
	sdhci_pltfm_free(pdev);
err:
	dev_err(&pdev->dev, "pic32-sdhci probe failed: %d\n", ret);
	return ret;
}

static int pic32_sdhci_remove(struct platform_device *pdev)
{
	struct sdhci_host *host = platform_get_drvdata(pdev);
	struct pic32_sdhci_priv *sdhci_pdata = sdhci_priv(host);
	u32 scratch;

	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
	sdhci_remove_host(host, scratch == (u32)~0);
	clk_disable_unprepare(sdhci_pdata->base_clk);
	clk_disable_unprepare(sdhci_pdata->sys_clk);
	sdhci_pltfm_free(pdev);

	return 0;
}

static const struct of_device_id pic32_sdhci_id_table[] = {
	{ .compatible = "microchip,pic32mzda-sdhci" },
	{}
};
MODULE_DEVICE_TABLE(of, pic32_sdhci_id_table);

static struct platform_driver pic32_sdhci_driver = {
	.driver = {
		.name	= "pic32-sdhci",
		.of_match_table = of_match_ptr(pic32_sdhci_id_table),
	},
	.probe		= pic32_sdhci_probe,
	.remove		= pic32_sdhci_remove,
};

module_platform_driver(pic32_sdhci_driver);

MODULE_DESCRIPTION("Microchip PIC32 SDHCI driver");
MODULE_AUTHOR("Pistirica Sorin Andrei & Sandeep Sheriker");
MODULE_LICENSE("GPL v2");
