// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2008 Sebastian Haas (initial chardev implementation)
 * Copyright (C) 2010 Markus Plessing <plessing@ems-wuensche.com>
 * Rework for mainline by Oliver Hartkopp <socketcan@hartkopp.net>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <linux/can.h>
#include <linux/can/dev.h>
#include "sja1000.h"

#define DRV_NAME "ems_pcmcia"

MODULE_AUTHOR("Markus Plessing <plessing@ems-wuensche.com>");
MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-CARD cards");
MODULE_SUPPORTED_DEVICE("EMS CPC-CARD CAN card");
MODULE_LICENSE("GPL v2");

#define EMS_PCMCIA_MAX_CHAN 2

struct ems_pcmcia_card {
	int channels;
	struct pcmcia_device *pcmcia_dev;
	struct net_device *net_dev[EMS_PCMCIA_MAX_CHAN];
	void __iomem *base_addr;
};

#define EMS_PCMCIA_CAN_CLOCK (16000000 / 2)

/*
 * The board configuration is probably following:
 * RX1 is connected to ground.
 * TX1 is not connected.
 * CLKO is not connected.
 * Setting the OCR register to 0xDA is a good idea.
 * This means  normal output mode , push-pull and the correct polarity.
 */
#define EMS_PCMCIA_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)

/*
 * In the CDR register, you should set CBP to 1.
 * You will probably also want to set the clock divider value to 7
 * (meaning direct oscillator output) because the second SJA1000 chip
 * is driven by the first one CLKOUT output.
 */
#define EMS_PCMCIA_CDR (CDR_CBP | CDR_CLKOUT_MASK)
#define EMS_PCMCIA_MEM_SIZE 4096 /* Size of the remapped io-memory */
#define EMS_PCMCIA_CAN_BASE_OFFSET 0x100 /* Offset where controllers starts */
#define EMS_PCMCIA_CAN_CTRL_SIZE 0x80 /* Memory size for each controller */

#define EMS_CMD_RESET 0x00 /* Perform a reset of the card */
#define EMS_CMD_MAP   0x03 /* Map CAN controllers into card' memory */
#define EMS_CMD_UMAP  0x02 /* Unmap CAN controllers from card' memory */

static struct pcmcia_device_id ems_pcmcia_tbl[] = {
	PCMCIA_DEVICE_PROD_ID123("EMS_T_W", "CPC-Card", "V2.0", 0xeab1ea23,
				 0xa338573f, 0xe4575800),
	PCMCIA_DEVICE_NULL,
};

MODULE_DEVICE_TABLE(pcmcia, ems_pcmcia_tbl);

static u8 ems_pcmcia_read_reg(const struct sja1000_priv *priv, int port)
{
	return readb(priv->reg_base + port);
}

static void ems_pcmcia_write_reg(const struct sja1000_priv *priv, int port,
				 u8 val)
{
	writeb(val, priv->reg_base + port);
}

static irqreturn_t ems_pcmcia_interrupt(int irq, void *dev_id)
{
	struct ems_pcmcia_card *card = dev_id;
	struct net_device *dev;
	irqreturn_t retval = IRQ_NONE;
	int i, again;

	/* Card not present */
	if (readw(card->base_addr) != 0xAA55)
		return IRQ_HANDLED;

	do {
		again = 0;

		/* Check interrupt for each channel */
		for (i = 0; i < card->channels; i++) {
			dev = card->net_dev[i];
			if (!dev)
				continue;

			if (sja1000_interrupt(irq, dev) == IRQ_HANDLED)
				again = 1;
		}
		/* At least one channel handled the interrupt */
		if (again)
			retval = IRQ_HANDLED;

	} while (again);

	return retval;
}

/*
 * Check if a CAN controller is present at the specified location
 * by trying to set 'em into the PeliCAN mode
 */
static inline int ems_pcmcia_check_chan(struct sja1000_priv *priv)
{
	/* Make sure SJA1000 is in reset mode */
	ems_pcmcia_write_reg(priv, SJA1000_MOD, 1);
	ems_pcmcia_write_reg(priv, SJA1000_CDR, CDR_PELICAN);

	/* read reset-values */
	if (ems_pcmcia_read_reg(priv, SJA1000_CDR) == CDR_PELICAN)
		return 1;

	return 0;
}

static void ems_pcmcia_del_card(struct pcmcia_device *pdev)
{
	struct ems_pcmcia_card *card = pdev->priv;
	struct net_device *dev;
	int i;

	free_irq(pdev->irq, card);

	for (i = 0; i < card->channels; i++) {
		dev = card->net_dev[i];
		if (!dev)
			continue;

		printk(KERN_INFO "%s: removing %s on channel #%d\n",
		       DRV_NAME, dev->name, i);
		unregister_sja1000dev(dev);
		free_sja1000dev(dev);
	}

	writeb(EMS_CMD_UMAP, card->base_addr);
	iounmap(card->base_addr);
	kfree(card);

	pdev->priv = NULL;
}

/*
 * Probe PCI device for EMS CAN signature and register each available
 * CAN channel to SJA1000 Socket-CAN subsystem.
 */
static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
{
	struct sja1000_priv *priv;
	struct net_device *dev;
	struct ems_pcmcia_card *card;
	int err, i;

	/* Allocating card structures to hold addresses, ... */
	card = kzalloc(sizeof(struct ems_pcmcia_card), GFP_KERNEL);
	if (!card)
		return -ENOMEM;

	pdev->priv = card;
	card->channels = 0;

	card->base_addr = ioremap(base, EMS_PCMCIA_MEM_SIZE);
	if (!card->base_addr) {
		err = -ENOMEM;
		goto failure_cleanup;
	}

	/* Check for unique EMS CAN signature */
	if (readw(card->base_addr) != 0xAA55) {
		err = -ENODEV;
		goto failure_cleanup;
	}

	/* Request board reset */
	writeb(EMS_CMD_RESET, card->base_addr);

	/* Make sure CAN controllers are mapped into card's memory space */
	writeb(EMS_CMD_MAP, card->base_addr);

	/* Detect available channels */
	for (i = 0; i < EMS_PCMCIA_MAX_CHAN; i++) {
		dev = alloc_sja1000dev(0);
		if (!dev) {
			err = -ENOMEM;
			goto failure_cleanup;
		}

		card->net_dev[i] = dev;
		priv = netdev_priv(dev);
		priv->priv = card;
		SET_NETDEV_DEV(dev, &pdev->dev);
		dev->dev_id = i;

		priv->irq_flags = IRQF_SHARED;
		dev->irq = pdev->irq;
		priv->reg_base = card->base_addr + EMS_PCMCIA_CAN_BASE_OFFSET +
			(i * EMS_PCMCIA_CAN_CTRL_SIZE);

		/* Check if channel is present */
		if (ems_pcmcia_check_chan(priv)) {
			priv->read_reg  = ems_pcmcia_read_reg;
			priv->write_reg = ems_pcmcia_write_reg;
			priv->can.clock.freq = EMS_PCMCIA_CAN_CLOCK;
			priv->ocr = EMS_PCMCIA_OCR;
			priv->cdr = EMS_PCMCIA_CDR;
			priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER;

			/* Register SJA1000 device */
			err = register_sja1000dev(dev);
			if (err) {
				free_sja1000dev(dev);
				goto failure_cleanup;
			}

			card->channels++;

			printk(KERN_INFO "%s: registered %s on channel "
			       "#%d at 0x%p, irq %d\n", DRV_NAME, dev->name,
			       i, priv->reg_base, dev->irq);
		} else
			free_sja1000dev(dev);
	}

	if (!card->channels) {
		err = -ENODEV;
		goto failure_cleanup;
	}

	err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
			  DRV_NAME, card);
	if (!err)
		return 0;

failure_cleanup:
	ems_pcmcia_del_card(pdev);
	return err;
}

/*
 * Setup PCMCIA socket and probe for EMS CPC-CARD
 */
static int ems_pcmcia_probe(struct pcmcia_device *dev)
{
	int csval;

	/* General socket configuration */
	dev->config_flags |= CONF_ENABLE_IRQ;
	dev->config_index = 1;
	dev->config_regs = PRESENT_OPTION;

	/* The io structure describes IO port mapping */
	dev->resource[0]->end = 16;
	dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
	dev->resource[1]->end = 16;
	dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
	dev->io_lines = 5;

	/* Allocate a memory window */
	dev->resource[2]->flags =
		(WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE);
	dev->resource[2]->start = dev->resource[2]->end = 0;

	csval = pcmcia_request_window(dev, dev->resource[2], 0);
	if (csval) {
		dev_err(&dev->dev, "pcmcia_request_window failed (err=%d)\n",
			csval);
		return 0;
	}

	csval = pcmcia_map_mem_page(dev, dev->resource[2], dev->config_base);
	if (csval) {
		dev_err(&dev->dev, "pcmcia_map_mem_page failed (err=%d)\n",
			csval);
		return 0;
	}

	csval = pcmcia_enable_device(dev);
	if (csval) {
		dev_err(&dev->dev, "pcmcia_enable_device failed (err=%d)\n",
			csval);
		return 0;
	}

	ems_pcmcia_add_card(dev, dev->resource[2]->start);
	return 0;
}

/*
 * Release claimed resources
 */
static void ems_pcmcia_remove(struct pcmcia_device *dev)
{
	ems_pcmcia_del_card(dev);
	pcmcia_disable_device(dev);
}

static struct pcmcia_driver ems_pcmcia_driver = {
	.name = DRV_NAME,
	.probe = ems_pcmcia_probe,
	.remove = ems_pcmcia_remove,
	.id_table = ems_pcmcia_tbl,
};
module_pcmcia_driver(ems_pcmcia_driver);
