/*
 * tscan1.c: driver for Technologic Systems TS-CAN1 PC104 boards
 *
 * Copyright 2010 Andre B. Oliveira
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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/>.
 */

/*
 * References:
 * - Getting started with TS-CAN1, Technologic Systems, Jun 2009
 *	http://www.embeddedarm.com/documentation/ts-can1-manual.pdf
 */

#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/isa.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include "sja1000.h"

MODULE_DESCRIPTION("Driver for Technologic Systems TS-CAN1 PC104 boards");
MODULE_AUTHOR("Andre B. Oliveira <anbadeol@gmail.com>");
MODULE_LICENSE("GPL");

/* Maximum number of boards (one in each JP1:JP2 setting of IO address) */
#define TSCAN1_MAXDEV 4

/* PLD registers address offsets */
#define TSCAN1_ID1	0
#define TSCAN1_ID2	1
#define TSCAN1_VERSION	2
#define TSCAN1_LED	3
#define TSCAN1_PAGE	4
#define TSCAN1_MODE	5
#define TSCAN1_JUMPERS	6

/* PLD board identifier registers magic values */
#define TSCAN1_ID1_VALUE 0xf6
#define TSCAN1_ID2_VALUE 0xb9

/* PLD mode register SJA1000 IO enable bit */
#define TSCAN1_MODE_ENABLE 0x40

/* PLD jumpers register bits */
#define TSCAN1_JP4 0x10
#define TSCAN1_JP5 0x20

/* PLD IO base addresses start */
#define TSCAN1_PLD_ADDRESS 0x150

/* PLD register space size */
#define TSCAN1_PLD_SIZE 8

/* SJA1000 register space size */
#define TSCAN1_SJA1000_SIZE 32

/* SJA1000 crystal frequency (16MHz) */
#define TSCAN1_SJA1000_XTAL 16000000

/* SJA1000 IO base addresses */
static const unsigned short tscan1_sja1000_addresses[] __devinitconst = {
	0x100, 0x120, 0x180, 0x1a0, 0x200, 0x240, 0x280, 0x320
};

/* Read SJA1000 register */
static u8 tscan1_read(const struct sja1000_priv *priv, int reg)
{
	return inb((unsigned long)priv->reg_base + reg);
}

/* Write SJA1000 register */
static void tscan1_write(const struct sja1000_priv *priv, int reg, u8 val)
{
	outb(val, (unsigned long)priv->reg_base + reg);
}

/* Probe for a TS-CAN1 board with JP2:JP1 jumper setting ID */
static int __devinit tscan1_probe(struct device *dev, unsigned id)
{
	struct net_device *netdev;
	struct sja1000_priv *priv;
	unsigned long pld_base, sja1000_base;
	int irq, i;

	pld_base = TSCAN1_PLD_ADDRESS + id * TSCAN1_PLD_SIZE;
	if (!request_region(pld_base, TSCAN1_PLD_SIZE, dev_name(dev)))
		return -EBUSY;

	if (inb(pld_base + TSCAN1_ID1) != TSCAN1_ID1_VALUE ||
	    inb(pld_base + TSCAN1_ID2) != TSCAN1_ID2_VALUE) {
		release_region(pld_base, TSCAN1_PLD_SIZE);
		return -ENODEV;
	}

	switch (inb(pld_base + TSCAN1_JUMPERS) & (TSCAN1_JP4 | TSCAN1_JP5)) {
	case TSCAN1_JP4:
		irq = 6;
		break;
	case TSCAN1_JP5:
		irq = 7;
		break;
	case TSCAN1_JP4 | TSCAN1_JP5:
		irq = 5;
		break;
	default:
		dev_err(dev, "invalid JP4:JP5 setting (no IRQ)\n");
		release_region(pld_base, TSCAN1_PLD_SIZE);
		return -EINVAL;
	}

	netdev = alloc_sja1000dev(0);
	if (!netdev) {
		release_region(pld_base, TSCAN1_PLD_SIZE);
		return -ENOMEM;
	}

	dev_set_drvdata(dev, netdev);
	SET_NETDEV_DEV(netdev, dev);

	netdev->base_addr = pld_base;
	netdev->irq = irq;

	priv = netdev_priv(netdev);
	priv->read_reg = tscan1_read;
	priv->write_reg = tscan1_write;
	priv->can.clock.freq = TSCAN1_SJA1000_XTAL / 2;
	priv->cdr = CDR_CBP | CDR_CLK_OFF;
	priv->ocr = OCR_TX0_PUSHPULL;

	/* Select the first SJA1000 IO address that is free and that works */
	for (i = 0; i < ARRAY_SIZE(tscan1_sja1000_addresses); i++) {
		sja1000_base = tscan1_sja1000_addresses[i];
		if (!request_region(sja1000_base, TSCAN1_SJA1000_SIZE,
								dev_name(dev)))
			continue;

		/* Set SJA1000 IO base address and enable it */
		outb(TSCAN1_MODE_ENABLE | i, pld_base + TSCAN1_MODE);

		priv->reg_base = (void __iomem *)sja1000_base;
		if (!register_sja1000dev(netdev)) {
			/* SJA1000 probe succeeded; turn LED off and return */
			outb(0, pld_base + TSCAN1_LED);
			netdev_info(netdev, "TS-CAN1 at 0x%lx 0x%lx irq %d\n",
						pld_base, sja1000_base, irq);
			return 0;
		}

		/* SJA1000 probe failed; release and try next address */
		outb(0, pld_base + TSCAN1_MODE);
		release_region(sja1000_base, TSCAN1_SJA1000_SIZE);
	}

	dev_err(dev, "failed to assign SJA1000 IO address\n");
	dev_set_drvdata(dev, NULL);
	free_sja1000dev(netdev);
	release_region(pld_base, TSCAN1_PLD_SIZE);
	return -ENXIO;
}

static int __devexit tscan1_remove(struct device *dev, unsigned id /*unused*/)
{
	struct net_device *netdev;
	struct sja1000_priv *priv;
	unsigned long pld_base, sja1000_base;

	netdev = dev_get_drvdata(dev);
	unregister_sja1000dev(netdev);
	dev_set_drvdata(dev, NULL);

	priv = netdev_priv(netdev);
	pld_base = netdev->base_addr;
	sja1000_base = (unsigned long)priv->reg_base;

	outb(0, pld_base + TSCAN1_MODE);	/* disable SJA1000 IO space */

	release_region(sja1000_base, TSCAN1_SJA1000_SIZE);
	release_region(pld_base, TSCAN1_PLD_SIZE);

	free_sja1000dev(netdev);

	return 0;
}

static struct isa_driver tscan1_isa_driver = {
	.probe = tscan1_probe,
	.remove = __devexit_p(tscan1_remove),
	.driver = {
		.name = "tscan1",
	},
};

static int __init tscan1_init(void)
{
	return isa_register_driver(&tscan1_isa_driver, TSCAN1_MAXDEV);
}
module_init(tscan1_init);

static void __exit tscan1_exit(void)
{
	isa_unregister_driver(&tscan1_isa_driver);
}
module_exit(tscan1_exit);
