/*
 * Copyright (C) 2008 Per Dalen <per.dalen@cnw.se>
 *
 * Parts of this software are based on (derived) the following:
 *
 * - Kvaser linux driver, version 4.72 BETA
 *   Copyright (C) 2002-2007 KVASER AB
 *
 * - Lincan driver, version 0.3.3, OCERA project
 *   Copyright (C) 2004 Pavel Pisa
 *   Copyright (C) 2001 Arnaud Westenberg
 *
 * - Socketcan SJA1000 drivers
 *   Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
 *   Copyright (c) 2002-2007 Volkswagen Group Electronic Research
 *   Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
 *   38106 Braunschweig, GERMANY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the version 2 of the GNU General Public License
 * as published by the Free Software Foundation
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/can/dev.h>
#include <linux/io.h>

#include "sja1000.h"

#define DRV_NAME  "kvaser_pci"

MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>");
MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards");
MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card");
MODULE_LICENSE("GPL v2");

#define MAX_NO_OF_CHANNELS        4 /* max no of channels on a single card */

struct kvaser_pci {
	int channel;
	struct pci_dev *pci_dev;
	struct net_device *slave_dev[MAX_NO_OF_CHANNELS-1];
	void __iomem *conf_addr;
	void __iomem *res_addr;
	int no_channels;
	u8 xilinx_ver;
};

#define KVASER_PCI_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 KVASER_PCI_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 0
 * (meaning divide-by-2), the Pelican bit, and the clock-off bit
 * (you will have no need for CLKOUT anyway).
 */
#define KVASER_PCI_CDR            (CDR_CBP | CDR_CLKOUT_MASK)

/*
 * These register values are valid for revision 14 of the Xilinx logic.
 */
#define XILINX_VERINT             7   /* Lower nibble simulate interrupts,
					 high nibble version number. */

#define XILINX_PRESUMED_VERSION   14

/*
 * Important S5920 registers
 */
#define S5920_INTCSR              0x38
#define S5920_PTCR                0x60
#define INTCSR_ADDON_INTENABLE_M  0x2000


#define KVASER_PCI_PORT_BYTES     0x20

#define PCI_CONFIG_PORT_SIZE      0x80      /* size of the config io-memory */
#define PCI_PORT_SIZE             0x80      /* size of a channel io-memory */
#define PCI_PORT_XILINX_SIZE      0x08      /* size of a xilinx io-memory */

#define KVASER_PCI_VENDOR_ID1     0x10e8    /* the PCI device and vendor IDs */
#define KVASER_PCI_DEVICE_ID1     0x8406

#define KVASER_PCI_VENDOR_ID2     0x1a07    /* the PCI device and vendor IDs */
#define KVASER_PCI_DEVICE_ID2     0x0008

static const struct pci_device_id kvaser_pci_tbl[] = {
	{KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
	{KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
	{ 0,}
};

MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl);

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

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

static void kvaser_pci_disable_irq(struct net_device *dev)
{
	struct sja1000_priv *priv = netdev_priv(dev);
	struct kvaser_pci *board = priv->priv;
	u32 intcsr;

	/* Disable interrupts from card */
	intcsr = ioread32(board->conf_addr + S5920_INTCSR);
	intcsr &= ~INTCSR_ADDON_INTENABLE_M;
	iowrite32(intcsr, board->conf_addr + S5920_INTCSR);
}

static void kvaser_pci_enable_irq(struct net_device *dev)
{
	struct sja1000_priv *priv = netdev_priv(dev);
	struct kvaser_pci *board = priv->priv;
	u32 tmp_en_io;

	/* Enable interrupts from card */
	tmp_en_io = ioread32(board->conf_addr + S5920_INTCSR);
	tmp_en_io |= INTCSR_ADDON_INTENABLE_M;
	iowrite32(tmp_en_io, board->conf_addr + S5920_INTCSR);
}

static int number_of_sja1000_chip(void __iomem *base_addr)
{
	u8 status;
	int i;

	for (i = 0; i < MAX_NO_OF_CHANNELS; i++) {
		/* reset chip */
		iowrite8(MOD_RM, base_addr +
			 (i * KVASER_PCI_PORT_BYTES) + SJA1000_MOD);
		status = ioread8(base_addr +
				 (i * KVASER_PCI_PORT_BYTES) + SJA1000_MOD);
		/* check reset bit */
		if (!(status & MOD_RM))
			break;
	}

	return i;
}

static void kvaser_pci_del_chan(struct net_device *dev)
{
	struct sja1000_priv *priv;
	struct kvaser_pci *board;
	int i;

	if (!dev)
		return;
	priv = netdev_priv(dev);
	board = priv->priv;
	if (!board)
		return;

	dev_info(&board->pci_dev->dev, "Removing device %s\n",
		 dev->name);

	/* Disable PCI interrupts */
	kvaser_pci_disable_irq(dev);

	for (i = 0; i < board->no_channels - 1; i++) {
		if (board->slave_dev[i]) {
			dev_info(&board->pci_dev->dev, "Removing device %s\n",
				 board->slave_dev[i]->name);
			unregister_sja1000dev(board->slave_dev[i]);
			free_sja1000dev(board->slave_dev[i]);
		}
	}
	unregister_sja1000dev(dev);

	pci_iounmap(board->pci_dev, priv->reg_base);
	pci_iounmap(board->pci_dev, board->conf_addr);
	pci_iounmap(board->pci_dev, board->res_addr);

	free_sja1000dev(dev);
}

static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
			       struct net_device **master_dev,
			       void __iomem *conf_addr,
			       void __iomem *res_addr,
			       void __iomem *base_addr)
{
	struct net_device *dev;
	struct sja1000_priv *priv;
	struct kvaser_pci *board;
	int err;

	dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
	if (dev == NULL)
		return -ENOMEM;

	priv = netdev_priv(dev);
	board = priv->priv;

	board->pci_dev = pdev;
	board->channel = channel;

	/* S5920 */
	board->conf_addr = conf_addr;

	/* XILINX board wide address */
	board->res_addr = res_addr;

	if (channel == 0) {
		board->xilinx_ver =
			ioread8(board->res_addr + XILINX_VERINT) >> 4;

		/* Assert PTADR# - we're in passive mode so the other bits are
		   not important */
		iowrite32(0x80808080UL, board->conf_addr + S5920_PTCR);

		/* Enable interrupts from card */
		kvaser_pci_enable_irq(dev);
	} else {
		struct sja1000_priv *master_priv = netdev_priv(*master_dev);
		struct kvaser_pci *master_board = master_priv->priv;
		master_board->slave_dev[channel - 1] = dev;
		master_board->no_channels = channel + 1;
		board->xilinx_ver = master_board->xilinx_ver;
	}

	priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES;

	priv->read_reg = kvaser_pci_read_reg;
	priv->write_reg = kvaser_pci_write_reg;

	priv->can.clock.freq = KVASER_PCI_CAN_CLOCK;

	priv->ocr = KVASER_PCI_OCR;
	priv->cdr = KVASER_PCI_CDR;

	priv->irq_flags = IRQF_SHARED;
	dev->irq = pdev->irq;

	dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
		 priv->reg_base, board->conf_addr, dev->irq);

	SET_NETDEV_DEV(dev, &pdev->dev);
	dev->dev_id = channel;

	/* Register SJA1000 device */
	err = register_sja1000dev(dev);
	if (err) {
		dev_err(&pdev->dev, "Registering device failed (err=%d)\n",
			err);
		goto failure;
	}

	if (channel == 0)
		*master_dev = dev;

	return 0;

failure:
	kvaser_pci_del_chan(dev);
	return err;
}

static int kvaser_pci_init_one(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	int err;
	struct net_device *master_dev = NULL;
	struct sja1000_priv *priv;
	struct kvaser_pci *board;
	int no_channels;
	void __iomem *base_addr = NULL;
	void __iomem *conf_addr = NULL;
	void __iomem *res_addr = NULL;
	int i;

	dev_info(&pdev->dev, "initializing device %04x:%04x\n",
		 pdev->vendor, pdev->device);

	err = pci_enable_device(pdev);
	if (err)
		goto failure;

	err = pci_request_regions(pdev, DRV_NAME);
	if (err)
		goto failure_release_pci;

	/* S5920 */
	conf_addr = pci_iomap(pdev, 0, PCI_CONFIG_PORT_SIZE);
	if (conf_addr == NULL) {
		err = -ENODEV;
		goto failure_release_regions;
	}

	/* XILINX board wide address */
	res_addr = pci_iomap(pdev, 2, PCI_PORT_XILINX_SIZE);
	if (res_addr == NULL) {
		err = -ENOMEM;
		goto failure_iounmap;
	}

	base_addr = pci_iomap(pdev, 1, PCI_PORT_SIZE);
	if (base_addr == NULL) {
		err = -ENOMEM;
		goto failure_iounmap;
	}

	no_channels = number_of_sja1000_chip(base_addr);
	if (no_channels == 0) {
		err = -ENOMEM;
		goto failure_iounmap;
	}

	for (i = 0; i < no_channels; i++) {
		err = kvaser_pci_add_chan(pdev, i, &master_dev,
					  conf_addr, res_addr,
					  base_addr);
		if (err)
			goto failure_cleanup;
	}

	priv = netdev_priv(master_dev);
	board = priv->priv;

	dev_info(&pdev->dev, "xilinx version=%d number of channels=%d\n",
		 board->xilinx_ver, board->no_channels);

	pci_set_drvdata(pdev, master_dev);
	return 0;

failure_cleanup:
	kvaser_pci_del_chan(master_dev);

failure_iounmap:
	if (conf_addr != NULL)
		pci_iounmap(pdev, conf_addr);
	if (res_addr != NULL)
		pci_iounmap(pdev, res_addr);
	if (base_addr != NULL)
		pci_iounmap(pdev, base_addr);

failure_release_regions:
	pci_release_regions(pdev);

failure_release_pci:
	pci_disable_device(pdev);

failure:
	return err;

}

static void kvaser_pci_remove_one(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);

	kvaser_pci_del_chan(dev);

	pci_release_regions(pdev);
	pci_disable_device(pdev);
}

static struct pci_driver kvaser_pci_driver = {
	.name = DRV_NAME,
	.id_table = kvaser_pci_tbl,
	.probe = kvaser_pci_init_one,
	.remove = kvaser_pci_remove_one,
};

module_pci_driver(kvaser_pci_driver);
