// SPDX-License-Identifier: GPL-2.0-only
/*
 * w1_ds2406.c - w1 family 12 (DS2406) driver
 * based on w1_ds2413.c by Mariusz Bialonczyk <manio@skyboo.net>
 *
 * Copyright (c) 2014 Scott Alfter <scott@alfter.us>
 */

#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>

#define W1_FAMILY_DS2406	0x12

#define W1_F12_FUNC_READ_STATUS		   0xAA
#define W1_F12_FUNC_WRITE_STATUS	   0x55

static ssize_t w1_f12_read_state(
	struct file *filp, struct kobject *kobj,
	struct bin_attribute *bin_attr,
	char *buf, loff_t off, size_t count)
{
	u8 w1_buf[6]={W1_F12_FUNC_READ_STATUS, 7, 0, 0, 0, 0};
	struct w1_slave *sl = kobj_to_w1_slave(kobj);
	u16 crc=0;
	int i;
	ssize_t rtnval=1;

	if (off != 0)
		return 0;
	if (!buf)
		return -EINVAL;

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

	if (w1_reset_select_slave(sl)) {
		mutex_unlock(&sl->master->bus_mutex);
		return -EIO;
	}

	w1_write_block(sl->master, w1_buf, 3);
	w1_read_block(sl->master, w1_buf+3, 3);
	for (i=0; i<6; i++)
		crc=crc16_byte(crc, w1_buf[i]);
	if (crc==0xb001) /* good read? */
		*buf=((w1_buf[3]>>5)&3)|0x30;
	else
		rtnval=-EIO;

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

	return rtnval;
}

static ssize_t w1_f12_write_output(
	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 w1_buf[6]={W1_F12_FUNC_WRITE_STATUS, 7, 0, 0, 0, 0};
	u16 crc=0;
	int i;
	ssize_t rtnval=1;

	if (count != 1 || off != 0)
		return -EFAULT;

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

	if (w1_reset_select_slave(sl)) {
		mutex_unlock(&sl->master->bus_mutex);
		return -EIO;
	}

	w1_buf[3] = (((*buf)&3)<<5)|0x1F;
	w1_write_block(sl->master, w1_buf, 4);
	w1_read_block(sl->master, w1_buf+4, 2);
	for (i=0; i<6; i++)
		crc=crc16_byte(crc, w1_buf[i]);
	if (crc==0xb001) /* good read? */
		w1_write_8(sl->master, 0xFF);
	else
		rtnval=-EIO;

	mutex_unlock(&sl->master->bus_mutex);
	return rtnval;
}

#define NB_SYSFS_BIN_FILES 2
static struct bin_attribute w1_f12_sysfs_bin_files[NB_SYSFS_BIN_FILES] = {
	{
		.attr = {
			.name = "state",
			.mode = S_IRUGO,
		},
		.size = 1,
		.read = w1_f12_read_state,
	},
	{
		.attr = {
			.name = "output",
			.mode = S_IRUGO | S_IWUSR | S_IWGRP,
		},
		.size = 1,
		.write = w1_f12_write_output,
	}
};

static int w1_f12_add_slave(struct w1_slave *sl)
{
	int err = 0;
	int i;

	for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i)
		err = sysfs_create_bin_file(
			&sl->dev.kobj,
			&(w1_f12_sysfs_bin_files[i]));
	if (err)
		while (--i >= 0)
			sysfs_remove_bin_file(&sl->dev.kobj,
				&(w1_f12_sysfs_bin_files[i]));
	return err;
}

static void w1_f12_remove_slave(struct w1_slave *sl)
{
	int i;
	for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i)
		sysfs_remove_bin_file(&sl->dev.kobj,
			&(w1_f12_sysfs_bin_files[i]));
}

static const struct w1_family_ops w1_f12_fops = {
	.add_slave      = w1_f12_add_slave,
	.remove_slave   = w1_f12_remove_slave,
};

static struct w1_family w1_family_12 = {
	.fid = W1_FAMILY_DS2406,
	.fops = &w1_f12_fops,
};
module_w1_family(w1_family_12);

MODULE_AUTHOR("Scott Alfter <scott@alfter.us>");
MODULE_DESCRIPTION("w1 family 12 driver for DS2406 2 Pin IO");
MODULE_LICENSE("GPL");
