// SPDX-License-Identifier: GPL-2.0
/*
 * w1_ds250x.c - w1 family 09/0b/89/91 (DS250x) driver
 */

#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/w1.h>
#include <linux/nvmem-provider.h>

#define W1_DS2501_UNW_FAMILY    0x91
#define W1_DS2501_SIZE          64

#define W1_DS2502_FAMILY        0x09
#define W1_DS2502_UNW_FAMILY    0x89
#define W1_DS2502_SIZE          128

#define W1_DS2505_FAMILY	0x0b
#define W1_DS2505_SIZE		2048

#define W1_PAGE_SIZE		32

#define W1_EXT_READ_MEMORY	0xA5
#define W1_READ_DATA_CRC        0xC3

#define OFF2PG(off)	((off) / W1_PAGE_SIZE)

#define CRC16_INIT		0
#define CRC16_VALID		0xb001

struct w1_eprom_data {
	size_t size;
	int (*read)(struct w1_slave *sl, int pageno);
	u8 eprom[W1_DS2505_SIZE];
	DECLARE_BITMAP(page_present, W1_DS2505_SIZE / W1_PAGE_SIZE);
	char nvmem_name[64];
};

static int w1_ds2502_read_page(struct w1_slave *sl, int pageno)
{
	struct w1_eprom_data *data = sl->family_data;
	int pgoff = pageno * W1_PAGE_SIZE;
	int ret = -EIO;
	u8 buf[3];
	u8 crc8;

	if (test_bit(pageno, data->page_present))
		return 0; /* page already present */

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

	if (w1_reset_select_slave(sl))
		goto err;

	buf[0] = W1_READ_DATA_CRC;
	buf[1] = pgoff & 0xff;
	buf[2] = pgoff >> 8;
	w1_write_block(sl->master, buf, 3);

	crc8 = w1_read_8(sl->master);
	if (w1_calc_crc8(buf, 3) != crc8)
		goto err;

	w1_read_block(sl->master, &data->eprom[pgoff], W1_PAGE_SIZE);

	crc8 = w1_read_8(sl->master);
	if (w1_calc_crc8(&data->eprom[pgoff], W1_PAGE_SIZE) != crc8)
		goto err;

	set_bit(pageno, data->page_present); /* mark page present */
	ret = 0;
err:
	mutex_unlock(&sl->master->bus_mutex);
	return ret;
}

static int w1_ds2505_read_page(struct w1_slave *sl, int pageno)
{
	struct w1_eprom_data *data = sl->family_data;
	int redir_retries = 16;
	int pgoff, epoff;
	int ret = -EIO;
	u8 buf[6];
	u8 redir;
	u16 crc;

	if (test_bit(pageno, data->page_present))
		return 0; /* page already present */

	epoff = pgoff = pageno * W1_PAGE_SIZE;
	mutex_lock(&sl->master->bus_mutex);

retry:
	if (w1_reset_select_slave(sl))
		goto err;

	buf[0] = W1_EXT_READ_MEMORY;
	buf[1] = pgoff & 0xff;
	buf[2] = pgoff >> 8;
	w1_write_block(sl->master, buf, 3);
	w1_read_block(sl->master, buf + 3, 3); /* redir, crc16 */
	redir = buf[3];
	crc = crc16(CRC16_INIT, buf, 6);

	if (crc != CRC16_VALID)
		goto err;


	if (redir != 0xff) {
		redir_retries--;
		if (redir_retries < 0)
			goto err;

		pgoff = (redir ^ 0xff) * W1_PAGE_SIZE;
		goto retry;
	}

	w1_read_block(sl->master, &data->eprom[epoff], W1_PAGE_SIZE);
	w1_read_block(sl->master, buf, 2); /* crc16 */
	crc = crc16(CRC16_INIT, &data->eprom[epoff], W1_PAGE_SIZE);
	crc = crc16(crc, buf, 2);

	if (crc != CRC16_VALID)
		goto err;

	set_bit(pageno, data->page_present);
	ret = 0;
err:
	mutex_unlock(&sl->master->bus_mutex);
	return ret;
}

static int w1_nvmem_read(void *priv, unsigned int off, void *buf, size_t count)
{
	struct w1_slave *sl = priv;
	struct w1_eprom_data *data = sl->family_data;
	size_t eprom_size = data->size;
	int ret;
	int i;

	if (off > eprom_size)
		return -EINVAL;

	if ((off + count) > eprom_size)
		count = eprom_size - off;

	i = OFF2PG(off);
	do {
		ret = data->read(sl, i++);
		if (ret < 0)
			return ret;
	} while (i < OFF2PG(off + count));

	memcpy(buf, &data->eprom[off], count);
	return 0;
}

static int w1_eprom_add_slave(struct w1_slave *sl)
{
	struct w1_eprom_data *data;
	struct nvmem_device *nvmem;
	struct nvmem_config nvmem_cfg = {
		.dev = &sl->dev,
		.add_legacy_fixed_of_cells = true,
		.reg_read = w1_nvmem_read,
		.type = NVMEM_TYPE_OTP,
		.read_only = true,
		.word_size = 1,
		.priv = sl,
		.id = -1
	};

	data = devm_kzalloc(&sl->dev, sizeof(struct w1_eprom_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	sl->family_data = data;
	switch (sl->family->fid) {
	case W1_DS2501_UNW_FAMILY:
		data->size = W1_DS2501_SIZE;
		data->read = w1_ds2502_read_page;
		break;
	case W1_DS2502_FAMILY:
	case W1_DS2502_UNW_FAMILY:
		data->size = W1_DS2502_SIZE;
		data->read = w1_ds2502_read_page;
		break;
	case W1_DS2505_FAMILY:
		data->size = W1_DS2505_SIZE;
		data->read = w1_ds2505_read_page;
		break;
	}

	if (sl->master->bus_master->dev_id)
		snprintf(data->nvmem_name, sizeof(data->nvmem_name),
			 "%s-%02x-%012llx",
			 sl->master->bus_master->dev_id, sl->reg_num.family,
			 (unsigned long long)sl->reg_num.id);
	else
		snprintf(data->nvmem_name, sizeof(data->nvmem_name),
			 "%02x-%012llx",
			 sl->reg_num.family,
			 (unsigned long long)sl->reg_num.id);

	nvmem_cfg.name = data->nvmem_name;
	nvmem_cfg.size = data->size;

	nvmem = devm_nvmem_register(&sl->dev, &nvmem_cfg);
	return PTR_ERR_OR_ZERO(nvmem);
}

static const struct w1_family_ops w1_eprom_fops = {
	.add_slave	= w1_eprom_add_slave,
};

static struct w1_family w1_family_09 = {
	.fid = W1_DS2502_FAMILY,
	.fops = &w1_eprom_fops,
};

static struct w1_family w1_family_0b = {
	.fid = W1_DS2505_FAMILY,
	.fops = &w1_eprom_fops,
};

static struct w1_family w1_family_89 = {
	.fid = W1_DS2502_UNW_FAMILY,
	.fops = &w1_eprom_fops,
};

static struct w1_family w1_family_91 = {
	.fid = W1_DS2501_UNW_FAMILY,
	.fops = &w1_eprom_fops,
};

static int __init w1_ds250x_init(void)
{
	int err;

	err = w1_register_family(&w1_family_09);
	if (err)
		return err;

	err = w1_register_family(&w1_family_0b);
	if (err)
		goto err_0b;

	err = w1_register_family(&w1_family_89);
	if (err)
		goto err_89;

	err = w1_register_family(&w1_family_91);
	if (err)
		goto err_91;

	return 0;

err_91:
	w1_unregister_family(&w1_family_89);
err_89:
	w1_unregister_family(&w1_family_0b);
err_0b:
	w1_unregister_family(&w1_family_09);
	return err;
}

static void __exit w1_ds250x_exit(void)
{
	w1_unregister_family(&w1_family_09);
	w1_unregister_family(&w1_family_0b);
	w1_unregister_family(&w1_family_89);
	w1_unregister_family(&w1_family_91);
}

module_init(w1_ds250x_init);
module_exit(w1_ds250x_exit);

MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfe@suse.de>");
MODULE_DESCRIPTION("w1 family driver for DS250x Add Only Memory");
MODULE_LICENSE("GPL");
MODULE_ALIAS("w1-family-" __stringify(W1_DS2502_FAMILY));
MODULE_ALIAS("w1-family-" __stringify(W1_DS2505_FAMILY));
MODULE_ALIAS("w1-family-" __stringify(W1_DS2501_UNW_FAMILY));
MODULE_ALIAS("w1-family-" __stringify(W1_DS2502_UNW_FAMILY));
