/*
 * isl6421.h - driver for lnb supply and control ic ISL6421
 *
 * Copyright (C) 2006 Andrew de Quincey
 * Copyright (C) 2006 Oliver Endriss
 *
 * 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.
 *
 * To obtain the license, point your browser to
 * http://www.gnu.org/copyleft/gpl.html
 *
 *
 * the project's page is at https://linuxtv.org
 */
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>

#include "dvb_frontend.h"
#include "isl6421.h"

struct isl6421 {
	u8			config;
	u8			override_or;
	u8			override_and;
	struct i2c_adapter	*i2c;
	u8			i2c_addr;
	bool			is_off;
};

static int isl6421_set_voltage(struct dvb_frontend *fe,
			       enum fe_sec_voltage voltage)
{
	int ret;
	u8 buf;
	bool is_off;
	struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
	struct i2c_msg msg[2] = {
		{
		  .addr = isl6421->i2c_addr,
		  .flags = 0,
		  .buf = &isl6421->config,
		  .len = 1,
		}, {
		  .addr = isl6421->i2c_addr,
		  .flags = I2C_M_RD,
		  .buf = &buf,
		  .len = 1,
		}

	};

	isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);

	switch(voltage) {
	case SEC_VOLTAGE_OFF:
		is_off = true;
		break;
	case SEC_VOLTAGE_13:
		is_off = false;
		isl6421->config |= ISL6421_EN1;
		break;
	case SEC_VOLTAGE_18:
		is_off = false;
		isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1);
		break;
	default:
		return -EINVAL;
	}

	/*
	 * If LNBf were not powered on, disable dynamic current limit, as,
	 * according with datasheet, highly capacitive load on the output may
	 * cause a difficult start-up.
	 */
	if (isl6421->is_off && !is_off)
		isl6421->config |= ISL6421_DCL;

	isl6421->config |= isl6421->override_or;
	isl6421->config &= isl6421->override_and;

	ret = i2c_transfer(isl6421->i2c, msg, 2);
	if (ret < 0)
		return ret;
	if (ret != 2)
		return -EIO;

	/* Store off status now incase future commands fail */
	isl6421->is_off = is_off;

	/* On overflow, the device will try again after 900 ms (typically) */
	if (!is_off && (buf & ISL6421_OLF1))
		msleep(1000);

	/* Re-enable dynamic current limit */
	if ((isl6421->config & ISL6421_DCL) &&
	    !(isl6421->override_or & ISL6421_DCL)) {
		isl6421->config &= ~ISL6421_DCL;

		ret = i2c_transfer(isl6421->i2c, msg, 2);
		if (ret < 0)
			return ret;
		if (ret != 2)
			return -EIO;
	}

	/* Check if overload flag is active. If so, disable power */
	if (!is_off && (buf & ISL6421_OLF1)) {
		isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);
		ret = i2c_transfer(isl6421->i2c, msg, 1);
		if (ret < 0)
			return ret;
		if (ret != 1)
			return -EIO;
		isl6421->is_off = true;

		dev_warn(&isl6421->i2c->dev,
			 "Overload current detected. disabling LNBf power\n");
		return -EINVAL;
	}

	return 0;
}

static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
	struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
	struct i2c_msg msg = {	.addr = isl6421->i2c_addr, .flags = 0,
				.buf = &isl6421->config,
				.len = sizeof(isl6421->config) };

	if (arg)
		isl6421->config |= ISL6421_LLC1;
	else
		isl6421->config &= ~ISL6421_LLC1;

	isl6421->config |= isl6421->override_or;
	isl6421->config &= isl6421->override_and;

	return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
}

static int isl6421_set_tone(struct dvb_frontend *fe,
			    enum fe_sec_tone_mode tone)
{
	struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
	struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
			       .buf = &isl6421->config,
			       .len = sizeof(isl6421->config) };

	switch (tone) {
	case SEC_TONE_ON:
		isl6421->config |= ISL6421_ENT1;
		break;
	case SEC_TONE_OFF:
		isl6421->config &= ~ISL6421_ENT1;
		break;
	default:
		return -EINVAL;
	}

	isl6421->config |= isl6421->override_or;
	isl6421->config &= isl6421->override_and;

	return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
}

static void isl6421_release(struct dvb_frontend *fe)
{
	/* power off */
	isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);

	/* free */
	kfree(fe->sec_priv);
	fe->sec_priv = NULL;
}

struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
		   u8 override_set, u8 override_clear, bool override_tone)
{
	struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
	if (!isl6421)
		return NULL;

	/* default configuration */
	isl6421->config = ISL6421_ISEL1;
	isl6421->i2c = i2c;
	isl6421->i2c_addr = i2c_addr;
	fe->sec_priv = isl6421;

	/* bits which should be forced to '1' */
	isl6421->override_or = override_set;

	/* bits which should be forced to '0' */
	isl6421->override_and = ~override_clear;

	/* detect if it is present or not */
	if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
		kfree(isl6421);
		fe->sec_priv = NULL;
		return NULL;
	}

	isl6421->is_off = true;

	/* install release callback */
	fe->ops.release_sec = isl6421_release;

	/* override frontend ops */
	fe->ops.set_voltage = isl6421_set_voltage;
	fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
	if (override_tone)
		fe->ops.set_tone = isl6421_set_tone;

	return fe;
}
EXPORT_SYMBOL_GPL(isl6421_attach);

MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
MODULE_LICENSE("GPL");
