/*
 *	w1_ds28e04.c - w1 family 1C (DS28E04) driver
 *
 * Copyright (c) 2012 Markus Franke <franke.m@sebakmt.com>
 *
 * This source code is licensed under the GNU General Public License,
 * Version 2. See the file COPYING for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/crc16.h>
#include <linux/uaccess.h>

#define CRC16_INIT		0
#define CRC16_VALID		0xb001

#include "../w1.h"
#include "../w1_int.h"
#include "../w1_family.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Markus Franke <franke.m@sebakmt.com>, <franm@hrz.tu-chemnitz.de>");
MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO");
MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E04));

/* Allow the strong pullup to be disabled, but default to enabled.
 * If it was disabled a parasite powered device might not get the required
 * current to copy the data from the scratchpad to EEPROM.  If it is enabled
 * parasite powered devices have a better chance of getting the current
 * required.
 */
static int w1_strong_pullup = 1;
module_param_named(strong_pullup, w1_strong_pullup, int, 0);

/* enable/disable CRC checking on DS28E04-100 memory accesses */
static char w1_enable_crccheck = 1;

#define W1_EEPROM_SIZE		512
#define W1_PAGE_COUNT		16
#define W1_PAGE_SIZE		32
#define W1_PAGE_BITS		5
#define W1_PAGE_MASK		0x1F

#define W1_F1C_READ_EEPROM	0xF0
#define W1_F1C_WRITE_SCRATCH	0x0F
#define W1_F1C_READ_SCRATCH	0xAA
#define W1_F1C_COPY_SCRATCH	0x55
#define W1_F1C_ACCESS_WRITE	0x5A

#define W1_1C_REG_LOGIC_STATE	0x220

struct w1_f1C_data {
	u8	memory[W1_EEPROM_SIZE];
	u32	validcrc;
};

/**
 * Check the file size bounds and adjusts count as needed.
 * This would not be needed if the file size didn't reset to 0 after a write.
 */
static inline size_t w1_f1C_fix_count(loff_t off, size_t count, size_t size)
{
	if (off > size)
		return 0;

	if ((off + count) > size)
		return size - off;

	return count;
}

static int w1_f1C_refresh_block(struct w1_slave *sl, struct w1_f1C_data *data,
				int block)
{
	u8	wrbuf[3];
	int	off = block * W1_PAGE_SIZE;

	if (data->validcrc & (1 << block))
		return 0;

	if (w1_reset_select_slave(sl)) {
		data->validcrc = 0;
		return -EIO;
	}

	wrbuf[0] = W1_F1C_READ_EEPROM;
	wrbuf[1] = off & 0xff;
	wrbuf[2] = off >> 8;
	w1_write_block(sl->master, wrbuf, 3);
	w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);

	/* cache the block if the CRC is valid */
	if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
		data->validcrc |= (1 << block);

	return 0;
}

static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data)
{
	u8 wrbuf[3];

	/* read directly from the EEPROM */
	if (w1_reset_select_slave(sl))
		return -EIO;

	wrbuf[0] = W1_F1C_READ_EEPROM;
	wrbuf[1] = addr & 0xff;
	wrbuf[2] = addr >> 8;

	w1_write_block(sl->master, wrbuf, sizeof(wrbuf));
	return w1_read_block(sl->master, data, len);
}

static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t off, size_t count)
{
	struct w1_slave *sl = kobj_to_w1_slave(kobj);
	struct w1_f1C_data *data = sl->family_data;
	int i, min_page, max_page;

	count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE);
	if (count == 0)
		return 0;

	mutex_lock(&sl->master->mutex);

	if (w1_enable_crccheck) {
		min_page = (off >> W1_PAGE_BITS);
		max_page = (off + count - 1) >> W1_PAGE_BITS;
		for (i = min_page; i <= max_page; i++) {
			if (w1_f1C_refresh_block(sl, data, i)) {
				count = -EIO;
				goto out_up;
			}
		}
		memcpy(buf, &data->memory[off], count);
	} else {
		count = w1_f1C_read(sl, off, count, buf);
	}

out_up:
	mutex_unlock(&sl->master->mutex);

	return count;
}

/**
 * Writes to the scratchpad and reads it back for verification.
 * Then copies the scratchpad to EEPROM.
 * The data must be on one page.
 * The master must be locked.
 *
 * @param sl	The slave structure
 * @param addr	Address for the write
 * @param len   length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK))
 * @param data	The data to write
 * @return	0=Success -1=failure
 */
static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data)
{
	u8 wrbuf[4];
	u8 rdbuf[W1_PAGE_SIZE + 3];
	u8 es = (addr + len - 1) & 0x1f;
	unsigned int tm = 10;
	int i;
	struct w1_f1C_data *f1C = sl->family_data;

	/* Write the data to the scratchpad */
	if (w1_reset_select_slave(sl))
		return -1;

	wrbuf[0] = W1_F1C_WRITE_SCRATCH;
	wrbuf[1] = addr & 0xff;
	wrbuf[2] = addr >> 8;

	w1_write_block(sl->master, wrbuf, 3);
	w1_write_block(sl->master, data, len);

	/* Read the scratchpad and verify */
	if (w1_reset_select_slave(sl))
		return -1;

	w1_write_8(sl->master, W1_F1C_READ_SCRATCH);
	w1_read_block(sl->master, rdbuf, len + 3);

	/* Compare what was read against the data written */
	if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
	    (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0))
		return -1;

	/* Copy the scratchpad to EEPROM */
	if (w1_reset_select_slave(sl))
		return -1;

	wrbuf[0] = W1_F1C_COPY_SCRATCH;
	wrbuf[3] = es;

	for (i = 0; i < sizeof(wrbuf); ++i) {
		/* issue 10ms strong pullup (or delay) on the last byte
		   for writing the data from the scratchpad to EEPROM */
		if (w1_strong_pullup && i == sizeof(wrbuf)-1)
			w1_next_pullup(sl->master, tm);

		w1_write_8(sl->master, wrbuf[i]);
	}

	if (!w1_strong_pullup)
		msleep(tm);

	if (w1_enable_crccheck) {
		/* invalidate cached data */
		f1C->validcrc &= ~(1 << (addr >> W1_PAGE_BITS));
	}

	/* Reset the bus to wake up the EEPROM (this may not be needed) */
	w1_reset_bus(sl->master);

	return 0;
}

static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t off, size_t count)

{
	struct w1_slave *sl = kobj_to_w1_slave(kobj);
	int addr, len, idx;

	count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE);
	if (count == 0)
		return 0;

	if (w1_enable_crccheck) {
		/* can only write full blocks in cached mode */
		if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
			dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n",
				(int)off, count);
			return -EINVAL;
		}

		/* make sure the block CRCs are valid */
		for (idx = 0; idx < count; idx += W1_PAGE_SIZE) {
			if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE)
				!= CRC16_VALID) {
				dev_err(&sl->dev, "bad CRC at offset %d\n",
					(int)off);
				return -EINVAL;
			}
		}
	}

	mutex_lock(&sl->master->mutex);

	/* Can only write data to one page at a time */
	idx = 0;
	while (idx < count) {
		addr = off + idx;
		len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK);
		if (len > (count - idx))
			len = count - idx;

		if (w1_f1C_write(sl, addr, len, &buf[idx]) < 0) {
			count = -EIO;
			goto out_up;
		}
		idx += len;
	}

out_up:
	mutex_unlock(&sl->master->mutex);

	return count;
}

static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t off, size_t count)

{
	struct w1_slave *sl = kobj_to_w1_slave(kobj);
	int ret;

	/* check arguments */
	if (off != 0 || count != 1 || buf == NULL)
		return -EINVAL;

	mutex_lock(&sl->master->mutex);
	ret = w1_f1C_read(sl, W1_1C_REG_LOGIC_STATE, count, buf);
	mutex_unlock(&sl->master->mutex);

	return ret;
}

static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj,
				struct bin_attribute *bin_attr,
				char *buf, loff_t off, size_t count)

{
	struct w1_slave *sl = kobj_to_w1_slave(kobj);
	u8 wrbuf[3];
	u8 ack;

	/* check arguments */
	if (off != 0 || count != 1 || buf == NULL)
		return -EINVAL;

	mutex_lock(&sl->master->mutex);

	/* Write the PIO data */
	if (w1_reset_select_slave(sl)) {
		mutex_unlock(&sl->master->mutex);
		return -1;
	}

	/* set bit 7..2 to value '1' */
	*buf = *buf | 0xFC;

	wrbuf[0] = W1_F1C_ACCESS_WRITE;
	wrbuf[1] = *buf;
	wrbuf[2] = ~(*buf);
	w1_write_block(sl->master, wrbuf, 3);

	w1_read_block(sl->master, &ack, sizeof(ack));

	mutex_unlock(&sl->master->mutex);

	/* check for acknowledgement */
	if (ack != 0xAA)
		return -EIO;

	return count;
}

static ssize_t w1_f1C_show_crccheck(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	if (put_user(w1_enable_crccheck + 0x30, buf))
		return -EFAULT;

	return sizeof(w1_enable_crccheck);
}

static ssize_t w1_f1C_store_crccheck(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	char val;

	if (count != 1 || !buf)
		return -EINVAL;

	if (get_user(val, buf))
		return -EFAULT;

	/* convert to decimal */
	val = val - 0x30;
	if (val != 0 && val != 1)
		return -EINVAL;

	/* set the new value */
	w1_enable_crccheck = val;

	return sizeof(w1_enable_crccheck);
}

#define NB_SYSFS_BIN_FILES 2
static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = {
	{
		.attr = {
			.name = "eeprom",
			.mode = S_IRUGO | S_IWUSR,
		},
		.size = W1_EEPROM_SIZE,
		.read = w1_f1C_read_bin,
		.write = w1_f1C_write_bin,
	},
	{
		.attr = {
			.name = "pio",
			.mode = S_IRUGO | S_IWUSR,
		},
		.size = 1,
		.read = w1_f1C_read_pio,
		.write = w1_f1C_write_pio,
	}
};

static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO,
		   w1_f1C_show_crccheck, w1_f1C_store_crccheck);

static int w1_f1C_add_slave(struct w1_slave *sl)
{
	int err = 0;
	int i;
	struct w1_f1C_data *data = NULL;

	if (w1_enable_crccheck) {
		data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL);
		if (!data)
			return -ENOMEM;
		sl->family_data = data;
	}

	/* create binary sysfs attributes */
	for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i)
		err = sysfs_create_bin_file(
			&sl->dev.kobj, &(w1_f1C_bin_attr[i]));

	if (!err) {
		/* create device attributes */
		err = device_create_file(&sl->dev, &dev_attr_crccheck);
	}

	if (err) {
		/* remove binary sysfs attributes */
		for (i = 0; i < NB_SYSFS_BIN_FILES; ++i)
			sysfs_remove_bin_file(
				&sl->dev.kobj, &(w1_f1C_bin_attr[i]));

		kfree(data);
	}

	return err;
}

static void w1_f1C_remove_slave(struct w1_slave *sl)
{
	int i;

	kfree(sl->family_data);
	sl->family_data = NULL;

	/* remove device attributes */
	device_remove_file(&sl->dev, &dev_attr_crccheck);

	/* remove binary sysfs attributes */
	for (i = 0; i < NB_SYSFS_BIN_FILES; ++i)
		sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i]));
}

static struct w1_family_ops w1_f1C_fops = {
	.add_slave      = w1_f1C_add_slave,
	.remove_slave   = w1_f1C_remove_slave,
};

static struct w1_family w1_family_1C = {
	.fid = W1_FAMILY_DS28E04,
	.fops = &w1_f1C_fops,
};

static int __init w1_f1C_init(void)
{
	return w1_register_family(&w1_family_1C);
}

static void __exit w1_f1C_fini(void)
{
	w1_unregister_family(&w1_family_1C);
}

module_init(w1_f1C_init);
module_exit(w1_f1C_fini);
