/*
 * Copyright (C) 2012 CERN (www.cern.ch)
 * Author: Alessandro Rubini <rubini@gnudd.com>
 *
 * Released according to the GNU GPL, version 2 or any later version.
 *
 * This work is part of the White Rabbit project, a research effort led
 * by CERN, the European Institute for Nuclear Research.
 */
#include <linux/module.h>
#include <linux/string.h>
#include <linux/firmware.h>
#include <linux/init.h>
#include <linux/fmc.h>
#include <asm/unaligned.h>

/*
 * This module uses the firmware loader to program the whole or part
 * of the FMC eeprom. The meat is in the _run functions.  However, no
 * default file name is provided, to avoid accidental mishaps. Also,
 * you must pass the busid argument
 */
static struct fmc_driver fwe_drv;

FMC_PARAM_BUSID(fwe_drv);

/* The "file=" is like the generic "gateware=" used elsewhere */
static char *fwe_file[FMC_MAX_CARDS];
static int fwe_file_n;
module_param_array_named(file, fwe_file, charp, &fwe_file_n, 0444);

static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw,
	int write)
{
	const uint8_t *p = fw->data;
	int len = fw->size;
	uint16_t thislen, thisaddr;
	int err;

	/* format is: 'w' addr16 len16 data... */
	while (len > 5) {
		thisaddr = get_unaligned_le16(p+1);
		thislen = get_unaligned_le16(p+3);
		if (p[0] != 'w' || thislen + 5 > len) {
			dev_err(&fmc->dev, "invalid tlv at offset %ti\n",
				p - fw->data);
			return -EINVAL;
		}
		err = 0;
		if (write) {
			dev_info(&fmc->dev, "write %i bytes at 0x%04x\n",
				 thislen, thisaddr);
			err = fmc_write_ee(fmc, thisaddr, p + 5, thislen);
		}
		if (err < 0) {
			dev_err(&fmc->dev, "write failure @0x%04x\n",
				thisaddr);
			return err;
		}
		p += 5 + thislen;
		len -= 5 + thislen;
	}
	if (write)
		dev_info(&fmc->dev, "write_eeprom: success\n");
	return 0;
}

static int fwe_run_bin(struct fmc_device *fmc, const struct firmware *fw)
{
	int ret;

	dev_info(&fmc->dev, "programming %zi bytes\n", fw->size);
	ret = fmc_write_ee(fmc, 0, (void *)fw->data, fw->size);
	if (ret < 0) {
		dev_info(&fmc->dev, "write_eeprom: error %i\n", ret);
		return ret;
	}
	dev_info(&fmc->dev, "write_eeprom: success\n");
	return 0;
}

static int fwe_run(struct fmc_device *fmc, const struct firmware *fw, char *s)
{
	char *last4 = s + strlen(s) - 4;
	int err;

	if (!strcmp(last4, ".bin"))
		return fwe_run_bin(fmc, fw);
	if (!strcmp(last4, ".tlv")) {
		err = fwe_run_tlv(fmc, fw, 0);
		if (!err)
			err = fwe_run_tlv(fmc, fw, 1);
		return err;
	}
	dev_err(&fmc->dev, "invalid file name \"%s\"\n", s);
	return -EINVAL;
}

/*
 * Programming is done at probe time. Morever, only those listed with
 * busid= are programmed.
 * card is probed for, only one is programmed. Unfortunately, it's
 * difficult to know in advance when probing the first card if others
 * are there.
 */
static int fwe_probe(struct fmc_device *fmc)
{
	int err, index = 0;
	const struct firmware *fw;
	struct device *dev = &fmc->dev;
	char *s;

	if (!fwe_drv.busid_n) {
		dev_err(dev, "%s: no busid passed, refusing all cards\n",
			KBUILD_MODNAME);
		return -ENODEV;
	}

	index = fmc_validate(fmc, &fwe_drv);
	if (index < 0) {
		pr_err("%s: refusing device \"%s\"\n", KBUILD_MODNAME,
		       dev_name(dev));
		return -ENODEV;
	}
	if (index >= fwe_file_n) {
		pr_err("%s: no filename for device index %i\n",
			KBUILD_MODNAME, index);
		return -ENODEV;
	}
	s = fwe_file[index];
	if (!s) {
		pr_err("%s: no filename for \"%s\" not programming\n",
		       KBUILD_MODNAME, dev_name(dev));
		return -ENOENT;
	}
	err = request_firmware(&fw, s, dev);
	if (err < 0) {
		dev_err(&fmc->dev, "request firmware \"%s\": error %i\n",
			s, err);
		return err;
	}
	fwe_run(fmc, fw, s);
	release_firmware(fw);
	return 0;
}

static int fwe_remove(struct fmc_device *fmc)
{
	return 0;
}

static struct fmc_driver fwe_drv = {
	.version = FMC_VERSION,
	.driver.name = KBUILD_MODNAME,
	.probe = fwe_probe,
	.remove = fwe_remove,
	/* no table, as the current match just matches everything */
};

static int fwe_init(void)
{
	int ret;

	ret = fmc_driver_register(&fwe_drv);
	return ret;
}

static void fwe_exit(void)
{
	fmc_driver_unregister(&fwe_drv);
}

module_init(fwe_init);
module_exit(fwe_exit);

MODULE_LICENSE("GPL");
