/*
 * av7110_hw.c: av7110 low level hardware access and firmware interface
 *
 * Copyright (C) 1999-2002 Ralph  Metzler
 *                       & Marcus Metzler for convergence integrated media GmbH
 *
 * originally based on code by:
 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 *
 * the project's page is at http://www.linuxtv.org/dvb/
 */

/* for debugging ARM communication: */
//#define COM_DEBUG

#include <stdarg.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/fs.h>

#include "av7110.h"
#include "av7110_hw.h"

#define _NOHANDSHAKE

/****************************************************************************
 * DEBI functions
 ****************************************************************************/

/* This DEBI code is based on the Stradis driver
   by Nathan Laredo <laredo@gnu.org> */

int av7110_debiwrite(struct av7110 *av7110, u32 config,
		     int addr, u32 val, int count)
{
	struct saa7146_dev *dev = av7110->dev;

	if (count <= 0 || count > 32764) {
		printk("%s: invalid count %d\n", __func__, count);
		return -1;
	}
	if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
		printk("%s: wait_for_debi_done failed\n", __func__);
		return -1;
	}
	saa7146_write(dev, DEBI_CONFIG, config);
	if (count <= 4)		/* immediate transfer */
		saa7146_write(dev, DEBI_AD, val);
	else			/* block transfer */
		saa7146_write(dev, DEBI_AD, av7110->debi_bus);
	saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
	saa7146_write(dev, MC2, (2 << 16) | 2);
	return 0;
}

u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
{
	struct saa7146_dev *dev = av7110->dev;
	u32 result = 0;

	if (count > 32764 || count <= 0) {
		printk("%s: invalid count %d\n", __func__, count);
		return 0;
	}
	if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
		printk("%s: wait_for_debi_done #1 failed\n", __func__);
		return 0;
	}
	saa7146_write(dev, DEBI_AD, av7110->debi_bus);
	saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));

	saa7146_write(dev, DEBI_CONFIG, config);
	saa7146_write(dev, MC2, (2 << 16) | 2);
	if (count > 4)
		return count;
	if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
		printk("%s: wait_for_debi_done #2 failed\n", __func__);
		return 0;
	}

	result = saa7146_read(dev, DEBI_AD);
	result &= (0xffffffffUL >> ((4 - count) * 8));
	return result;
}



/* av7110 ARM core boot stuff */
#if 0
void av7110_reset_arm(struct av7110 *av7110)
{
	saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);

	/* Disable DEBI and GPIO irq */
	SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
	SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);

	saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
	msleep(30);	/* the firmware needs some time to initialize */

	ARM_ResetMailBox(av7110);

	SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
	SAA7146_IER_ENABLE(av7110->dev, MASK_03);

	av7110->arm_ready = 1;
	dprintk(1, "reset ARM\n");
}
#endif  /*  0  */

static int waitdebi(struct av7110 *av7110, int adr, int state)
{
	int k;

	dprintk(4, "%p\n", av7110);

	for (k = 0; k < 100; k++) {
		if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
			return 0;
		udelay(5);
	}
	return -ETIMEDOUT;
}

static int load_dram(struct av7110 *av7110, u32 *data, int len)
{
	int i;
	int blocks, rest;
	u32 base, bootblock = AV7110_BOOT_BLOCK;

	dprintk(4, "%p\n", av7110);

	blocks = len / AV7110_BOOT_MAX_SIZE;
	rest = len % AV7110_BOOT_MAX_SIZE;
	base = DRAM_START_CODE;

	for (i = 0; i < blocks; i++) {
		if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
			printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
			return -ETIMEDOUT;
		}
		dprintk(4, "writing DRAM block %d\n", i);
		mwdebi(av7110, DEBISWAB, bootblock,
		       ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE);
		bootblock ^= 0x1400;
		iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
		iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2);
		iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
		base += AV7110_BOOT_MAX_SIZE;
	}

	if (rest > 0) {
		if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
			printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
			return -ETIMEDOUT;
		}
		if (rest > 4)
			mwdebi(av7110, DEBISWAB, bootblock,
			       ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest);
		else
			mwdebi(av7110, DEBISWAB, bootblock,
			       ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4);

		iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4);
		iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2);
		iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
	}
	if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
		printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
		return -ETIMEDOUT;
	}
	iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2);
	iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
	if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) {
		printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
		return -ETIMEDOUT;
	}
	return 0;
}


/* we cannot write av7110 DRAM directly, so load a bootloader into
 * the DPRAM which implements a simple boot protocol */
int av7110_bootarm(struct av7110 *av7110)
{
	const struct firmware *fw;
	const char *fw_name = "av7110/bootcode.bin";
	struct saa7146_dev *dev = av7110->dev;
	u32 ret;
	int i;

	dprintk(4, "%p\n", av7110);

	av7110->arm_ready = 0;

	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);

	/* Disable DEBI and GPIO irq */
	SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
	SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);

	/* enable DEBI */
	saa7146_write(av7110->dev, MC1, 0x08800880);
	saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
	saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));

	/* test DEBI */
	iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
	/* FIXME: Why does Nexus CA require 2x iwdebi for first init? */
	iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);

	if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
		printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
		       "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
		       ret, 0x10325476);
		return -1;
	}
	for (i = 0; i < 8192; i += 4)
		iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
	dprintk(2, "debi test OK\n");

	/* boot */
	dprintk(1, "load boot code\n");
	saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
	//saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
	//saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);

	ret = request_firmware(&fw, fw_name, &dev->pci->dev);
	if (ret) {
		printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
			fw_name);
		return ret;
	}

	mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
	release_firmware(fw);
	iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);

	if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
		printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
		       "saa7146_wait_for_debi_done() timed out\n");
		return -ETIMEDOUT;
	}
	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
	mdelay(1);

	dprintk(1, "load dram code\n");
	if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
		printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
		       "load_dram() failed\n");
		return -1;
	}

	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
	mdelay(1);

	dprintk(1, "load dpram code\n");
	mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);

	if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
		printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
		       "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
		return -ETIMEDOUT;
	}
	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
	msleep(30);	/* the firmware needs some time to initialize */

	//ARM_ClearIrq(av7110);
	ARM_ResetMailBox(av7110);
	SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
	SAA7146_IER_ENABLE(av7110->dev, MASK_03);

	av7110->arm_errors = 0;
	av7110->arm_ready = 1;
	return 0;
}
MODULE_FIRMWARE("av7110/bootcode.bin");

/****************************************************************************
 * DEBI command polling
 ****************************************************************************/

int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
{
	unsigned long start;
	u32 stat;
	int err;

	if (FW_VERSION(av7110->arm_app) <= 0x261c) {
		/* not supported by old firmware */
		msleep(50);
		return 0;
	}

	/* new firmware */
	start = jiffies;
	for (;;) {
		err = time_after(jiffies, start + ARM_WAIT_FREE);
		if (mutex_lock_interruptible(&av7110->dcomlock))
			return -ERESTARTSYS;
		stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
		mutex_unlock(&av7110->dcomlock);
		if ((stat & flags) == 0)
			break;
		if (err) {
			printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
				__func__, stat & flags);
			return -ETIMEDOUT;
		}
		msleep(1);
	}
	return 0;
}

static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
{
	int i;
	unsigned long start;
	char *type = NULL;
	u16 flags[2] = {0, 0};
	u32 stat;
	int err;

//	dprintk(4, "%p\n", av7110);

	if (!av7110->arm_ready) {
		dprintk(1, "arm not ready.\n");
		return -ENXIO;
	}

	start = jiffies;
	while (1) {
		err = time_after(jiffies, start + ARM_WAIT_FREE);
		if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
			break;
		if (err) {
			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__);
			av7110->arm_errors++;
			return -ETIMEDOUT;
		}
		msleep(1);
	}

	if (FW_VERSION(av7110->arm_app) <= 0x261f)
		wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);

#ifndef _NOHANDSHAKE
	start = jiffies;
	while (1) {
		err = time_after(jiffies, start + ARM_WAIT_SHAKE);
		if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
			break;
		if (err) {
			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__);
			return -ETIMEDOUT;
		}
		msleep(1);
	}
#endif

	switch ((buf[0] >> 8) & 0xff) {
	case COMTYPE_PIDFILTER:
	case COMTYPE_ENCODER:
	case COMTYPE_REC_PLAY:
	case COMTYPE_MPEGDECODER:
		type = "MSG";
		flags[0] = GPMQOver;
		flags[1] = GPMQFull;
		break;
	case COMTYPE_OSD:
		type = "OSD";
		flags[0] = OSDQOver;
		flags[1] = OSDQFull;
		break;
	case COMTYPE_MISC:
		if (FW_VERSION(av7110->arm_app) >= 0x261d) {
			type = "MSG";
			flags[0] = GPMQOver;
			flags[1] = GPMQBusy;
		}
		break;
	default:
		break;
	}

	if (type != NULL) {
		/* non-immediate COMMAND type */
		start = jiffies;
		for (;;) {
			err = time_after(jiffies, start + ARM_WAIT_FREE);
			stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
			if (stat & flags[0]) {
				printk(KERN_ERR "%s: %s QUEUE overflow\n",
					__func__, type);
				return -1;
			}
			if ((stat & flags[1]) == 0)
				break;
			if (err) {
				printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
					__func__, type);
				av7110->arm_errors++;
				return -ETIMEDOUT;
			}
			msleep(1);
		}
	}

	for (i = 2; i < length; i++)
		wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);

	if (length)
		wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
	else
		wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);

	wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);

	if (FW_VERSION(av7110->arm_app) <= 0x261f)
		wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);

#ifdef COM_DEBUG
	start = jiffies;
	while (1) {
		err = time_after(jiffies, start + ARM_WAIT_FREE);
		if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
			break;
		if (err) {
			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
			       __func__, (buf[0] >> 8) & 0xff);
			return -ETIMEDOUT;
		}
		msleep(1);
	}

	stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
	if (stat & GPMQOver) {
		printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__);
		return -ENOSPC;
	}
	else if (stat & OSDQOver) {
		printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__);
		return -ENOSPC;
	}
#endif

	return 0;
}

static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
{
	int ret;

//	dprintk(4, "%p\n", av7110);

	if (!av7110->arm_ready) {
		dprintk(1, "arm not ready.\n");
		return -1;
	}
	if (mutex_lock_interruptible(&av7110->dcomlock))
		return -ERESTARTSYS;

	ret = __av7110_send_fw_cmd(av7110, buf, length);
	mutex_unlock(&av7110->dcomlock);
	if (ret && ret!=-ERESTARTSYS)
		printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
		       __func__, ret);
	return ret;
}

int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
{
	va_list args;
	u16 buf[num + 2];
	int i, ret;

//	dprintk(4, "%p\n", av7110);

	buf[0] = ((type << 8) | com);
	buf[1] = num;

	if (num) {
		va_start(args, num);
		for (i = 0; i < num; i++)
			buf[i + 2] = va_arg(args, u32);
		va_end(args);
	}

	ret = av7110_send_fw_cmd(av7110, buf, num + 2);
	if (ret && ret != -ERESTARTSYS)
		printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
	return ret;
}

#if 0
int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
{
	int i, ret;
	u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
		16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	dprintk(4, "%p\n", av7110);

	for(i = 0; i < len && i < 32; i++)
	{
		if(i % 2 == 0)
			cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
		else
			cmd[(i / 2) + 2] |= buf[i];
	}

	ret = av7110_send_fw_cmd(av7110, cmd, 18);
	if (ret && ret != -ERESTARTSYS)
		printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
	return ret;
}
#endif  /*  0  */

int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
		      int request_buf_len, u16 *reply_buf, int reply_buf_len)
{
	int err;
	s16 i;
	unsigned long start;
#ifdef COM_DEBUG
	u32 stat;
#endif

	dprintk(4, "%p\n", av7110);

	if (!av7110->arm_ready) {
		dprintk(1, "arm not ready.\n");
		return -1;
	}

	if (mutex_lock_interruptible(&av7110->dcomlock))
		return -ERESTARTSYS;

	if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
		mutex_unlock(&av7110->dcomlock);
		printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
		return err;
	}

	start = jiffies;
	while (1) {
		err = time_after(jiffies, start + ARM_WAIT_FREE);
		if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
			break;
		if (err) {
			printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__);
			mutex_unlock(&av7110->dcomlock);
			return -ETIMEDOUT;
		}
#ifdef _NOHANDSHAKE
		msleep(1);
#endif
	}

#ifndef _NOHANDSHAKE
	start = jiffies;
	while (1) {
		err = time_after(jiffies, start + ARM_WAIT_SHAKE);
		if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
			break;
		if (err) {
			printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__);
			mutex_unlock(&av7110->dcomlock);
			return -ETIMEDOUT;
		}
		msleep(1);
	}
#endif

#ifdef COM_DEBUG
	stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
	if (stat & GPMQOver) {
		printk(KERN_ERR "%s: GPMQOver\n", __func__);
		mutex_unlock(&av7110->dcomlock);
		return -1;
	}
	else if (stat & OSDQOver) {
		printk(KERN_ERR "%s: OSDQOver\n", __func__);
		mutex_unlock(&av7110->dcomlock);
		return -1;
	}
#endif

	for (i = 0; i < reply_buf_len; i++)
		reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);

	mutex_unlock(&av7110->dcomlock);
	return 0;
}

static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
{
	int ret;
	ret = av7110_fw_request(av7110, &tag, 0, buf, length);
	if (ret)
		printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
	return ret;
}


/****************************************************************************
 * Firmware commands
 ****************************************************************************/

/* get version of the firmware ROM, RTSL, video ucode and ARM application  */
int av7110_firmversion(struct av7110 *av7110)
{
	u16 buf[20];
	u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);

	dprintk(4, "%p\n", av7110);

	if (av7110_fw_query(av7110, tag, buf, 16)) {
		printk("dvb-ttpci: failed to boot firmware @ card %d\n",
		       av7110->dvb_adapter.num);
		return -EIO;
	}

	av7110->arm_fw = (buf[0] << 16) + buf[1];
	av7110->arm_rtsl = (buf[2] << 16) + buf[3];
	av7110->arm_vid = (buf[4] << 16) + buf[5];
	av7110->arm_app = (buf[6] << 16) + buf[7];
	av7110->avtype = (buf[8] << 16) + buf[9];

	printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
	       av7110->dvb_adapter.num, av7110->arm_fw,
	       av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);

	/* print firmware capabilities */
	if (FW_CI_LL_SUPPORT(av7110->arm_app))
		printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
		       av7110->dvb_adapter.num);
	else
		printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
		       av7110->dvb_adapter.num);

	return 0;
}


int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
{
	int i, ret;
	u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
			16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	dprintk(4, "%p\n", av7110);

	if (len > 10)
		len = 10;

	buf[1] = len + 2;
	buf[2] = len;

	if (burst != -1)
		buf[3] = burst ? 0x01 : 0x00;
	else
		buf[3] = 0xffff;

	for (i = 0; i < len; i++)
		buf[i + 4] = msg[i];

	ret = av7110_send_fw_cmd(av7110, buf, 18);
	if (ret && ret!=-ERESTARTSYS)
		printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
	return ret;
}


#ifdef CONFIG_DVB_AV7110_OSD

static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
}

static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
		     enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
			     windownr, colordepth, index, blending);
}

static inline int SetColor_(struct av7110 *av7110, u8 windownr,
		     enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
			     windownr, colordepth, index, colorhi, colorlo);
}

static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
			  u16 colorfg, u16 colorbg)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4,
			     windownr, fontsize, colorfg, colorbg);
}

static int FlushText(struct av7110 *av7110)
{
	unsigned long start;
	int err;

	if (mutex_lock_interruptible(&av7110->dcomlock))
		return -ERESTARTSYS;
	start = jiffies;
	while (1) {
		err = time_after(jiffies, start + ARM_WAIT_OSD);
		if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
			break;
		if (err) {
			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
			       __func__);
			mutex_unlock(&av7110->dcomlock);
			return -ETIMEDOUT;
		}
		msleep(1);
	}
	mutex_unlock(&av7110->dcomlock);
	return 0;
}

static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
{
	int i, ret;
	unsigned long start;
	int length = strlen(buf) + 1;
	u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };

	if (mutex_lock_interruptible(&av7110->dcomlock))
		return -ERESTARTSYS;

	start = jiffies;
	while (1) {
		ret = time_after(jiffies, start + ARM_WAIT_OSD);
		if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
			break;
		if (ret) {
			printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
			       __func__);
			mutex_unlock(&av7110->dcomlock);
			return -ETIMEDOUT;
		}
		msleep(1);
	}
#ifndef _NOHANDSHAKE
	start = jiffies;
	while (1) {
		ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
		if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
			break;
		if (ret) {
			printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
			       __func__);
			mutex_unlock(&av7110->dcomlock);
			return -ETIMEDOUT;
		}
		msleep(1);
	}
#endif
	for (i = 0; i < length / 2; i++)
		wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2,
		      swab16(*(u16 *)(buf + 2 * i)), 2);
	if (length & 1)
		wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
	ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
	mutex_unlock(&av7110->dcomlock);
	if (ret && ret!=-ERESTARTSYS)
		printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
	return ret;
}

static inline int DrawLine(struct av7110 *av7110, u8 windownr,
			   u16 x, u16 y, u16 dx, u16 dy, u16 color)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6,
			     windownr, x, y, dx, dy, color);
}

static inline int DrawBlock(struct av7110 *av7110, u8 windownr,
			    u16 x, u16 y, u16 dx, u16 dy, u16 color)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6,
			     windownr, x, y, dx, dy, color);
}

static inline int HideWindow(struct av7110 *av7110, u8 windownr)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr);
}

static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
}

static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
}

static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
}

static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
				  osd_raw_window_t disptype,
				  u16 width, u16 height)
{
	return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
			     windownr, disptype, width, height);
}


static enum av7110_osd_palette_type bpp2pal[8] = {
	Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
};
static osd_raw_window_t bpp2bit[8] = {
	OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
};

static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
{
	int ret = wait_event_timeout(av7110->bmpq,
				av7110->bmp_state != BMP_LOADING, 10*HZ);
	if (ret == 0) {
		printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
		       ret, av7110->bmp_state);
		av7110->bmp_state = BMP_NONE;
		return -ETIMEDOUT;
	}
	return 0;
}

static inline int LoadBitmap(struct av7110 *av7110,
			     u16 dx, u16 dy, int inc, u8 __user * data)
{
	u16 format;
	int bpp;
	int i;
	int d, delta;
	u8 c;
	int ret;

	dprintk(4, "%p\n", av7110);

	format = bpp2bit[av7110->osdbpp[av7110->osdwin]];

	av7110->bmp_state = BMP_LOADING;
	if	(format == OSD_BITMAP8) {
		bpp=8; delta = 1;
	} else if (format == OSD_BITMAP4) {
		bpp=4; delta = 2;
	} else if (format == OSD_BITMAP2) {
		bpp=2; delta = 4;
	} else if (format == OSD_BITMAP1) {
		bpp=1; delta = 8;
	} else {
		av7110->bmp_state = BMP_NONE;
		return -EINVAL;
	}
	av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
	av7110->bmpp = 0;
	if (av7110->bmplen > 32768) {
		av7110->bmp_state = BMP_NONE;
		return -EINVAL;
	}
	for (i = 0; i < dy; i++) {
		if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
			av7110->bmp_state = BMP_NONE;
			return -EINVAL;
		}
	}
	if (format != OSD_BITMAP8) {
		for (i = 0; i < dx * dy / delta; i++) {
			c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
			for (d = delta - 2; d >= 0; d--) {
				c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
				      << ((delta - d - 1) * bpp));
				((u8 *)av7110->bmpbuf)[1024 + i] = c;
			}
		}
	}
	av7110->bmplen += 1024;
	dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
	ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
	if (!ret)
		ret = WaitUntilBmpLoaded(av7110);
	return ret;
}

static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
{
	dprintk(4, "%p\n", av7110);

	return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
}

static inline int ReleaseBitmap(struct av7110 *av7110)
{
	dprintk(4, "%p\n", av7110);

	if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
		return -1;
	if (av7110->bmp_state == BMP_LOADING)
		dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
	av7110->bmp_state = BMP_NONE;
	return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
}

static u32 RGB2YUV(u16 R, u16 G, u16 B)
{
	u16 y, u, v;
	u16 Y, Cr, Cb;

	y = R * 77 + G * 150 + B * 29;	/* Luma=0.299R+0.587G+0.114B 0..65535 */
	u = 2048 + B * 8 -(y >> 5);	/* Cr 0..4095 */
	v = 2048 + R * 8 -(y >> 5);	/* Cb 0..4095 */

	Y = y / 256;
	Cb = u / 16;
	Cr = v / 16;

	return Cr | (Cb << 16) | (Y << 8);
}

static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
{
	int ret;

	u16 ch, cl;
	u32 yuv;

	yuv = blend ? RGB2YUV(r,g,b) : 0;
	cl = (yuv & 0xffff);
	ch = ((yuv >> 16) & 0xffff);
	ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
			color, ch, cl);
	if (!ret)
		ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
				color, ((blend >> 4) & 0x0f));
	return ret;
}

static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
{
	int i;
	int length = last - first + 1;

	if (length * 4 > DATA_BUFF3_SIZE)
		return -EINVAL;

	for (i = 0; i < length; i++) {
		u32 color, blend, yuv;

		if (get_user(color, colors + i))
			return -EFAULT;
		blend = (color & 0xF0000000) >> 4;
		yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
				     (color >> 16) & 0xFF) | blend : 0;
		yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
		wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
	}
	return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
			    av7110->osdwin,
			    bpp2pal[av7110->osdbpp[av7110->osdwin]],
			    first, last);
}

static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
		       int x1, int y1, int inc, u8 __user * data)
{
	uint w, h, bpp, bpl, size, lpb, bnum, brest;
	int i;
	int rc,release_rc;

	w = x1 - x0 + 1;
	h = y1 - y0 + 1;
	if (inc <= 0)
		inc = w;
	if (w <= 0 || w > 720 || h <= 0 || h > 576)
		return -EINVAL;
	bpp = av7110->osdbpp[av7110->osdwin] + 1;
	bpl = ((w * bpp + 7) & ~7) / 8;
	size = h * bpl;
	lpb = (32 * 1024) / bpl;
	bnum = size / (lpb * bpl);
	brest = size - bnum * lpb * bpl;

	if (av7110->bmp_state == BMP_LOADING) {
		/* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
		BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
		rc = WaitUntilBmpLoaded(av7110);
		if (rc)
			return rc;
		/* just continue. This should work for all fw versions
		 * if bnum==1 && !brest && LoadBitmap was successful
		 */
	}

	rc = 0;
	for (i = 0; i < bnum; i++) {
		rc = LoadBitmap(av7110, w, lpb, inc, data);
		if (rc)
			break;
		rc = BlitBitmap(av7110, x0, y0 + i * lpb);
		if (rc)
			break;
		data += lpb * inc;
	}
	if (!rc && brest) {
		rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
		if (!rc)
			rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
	}
	release_rc = ReleaseBitmap(av7110);
	if (!rc)
		rc = release_rc;
	if (rc)
		dprintk(1,"returns %d\n",rc);
	return rc;
}

int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
{
	int ret;

	if (mutex_lock_interruptible(&av7110->osd_mutex))
		return -ERESTARTSYS;

	switch (dc->cmd) {
	case OSD_Close:
		ret = DestroyOSDWindow(av7110, av7110->osdwin);
		break;
	case OSD_Open:
		av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
		ret = CreateOSDWindow(av7110, av7110->osdwin,
				bpp2bit[av7110->osdbpp[av7110->osdwin]],
				dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
		if (ret)
			break;
		if (!dc->data) {
			ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
			if (ret)
				break;
			ret = SetColorBlend(av7110, av7110->osdwin);
		}
		break;
	case OSD_Show:
		ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
		break;
	case OSD_Hide:
		ret = HideWindow(av7110, av7110->osdwin);
		break;
	case OSD_Clear:
		ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
		break;
	case OSD_Fill:
		ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
		break;
	case OSD_SetColor:
		ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
		break;
	case OSD_SetPalette:
		if (FW_VERSION(av7110->arm_app) >= 0x2618)
			ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
		else {
			int i, len = dc->x0-dc->color+1;
			u8 __user *colors = (u8 __user *)dc->data;
			u8 r, g = 0, b = 0, blend = 0;
			ret = 0;
			for (i = 0; i<len; i++) {
				if (get_user(r, colors + i * 4) ||
				    get_user(g, colors + i * 4 + 1) ||
				    get_user(b, colors + i * 4 + 2) ||
				    get_user(blend, colors + i * 4 + 3)) {
					ret = -EFAULT;
					break;
				    }
				ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
				if (ret)
					break;
			}
		}
		break;
	case OSD_SetPixel:
		ret = DrawLine(av7110, av7110->osdwin,
			 dc->x0, dc->y0, 0, 0, dc->color);
		break;
	case OSD_SetRow:
		dc->y1 = dc->y0;
		/* fall through */
	case OSD_SetBlock:
		ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
		break;
	case OSD_FillRow:
		ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
			  dc->x1-dc->x0+1, dc->y1, dc->color);
		break;
	case OSD_FillBlock:
		ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
			  dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
		break;
	case OSD_Line:
		ret = DrawLine(av7110, av7110->osdwin,
			 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
		break;
	case OSD_Text:
	{
		char textbuf[240];

		if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
			ret = -EFAULT;
			break;
		}
		textbuf[239] = 0;
		if (dc->x1 > 3)
			dc->x1 = 3;
		ret = SetFont(av7110, av7110->osdwin, dc->x1,
			(u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
		if (!ret)
			ret = FlushText(av7110);
		if (!ret)
			ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
		break;
	}
	case OSD_SetWindow:
		if (dc->x0 < 1 || dc->x0 > 7)
			ret = -EINVAL;
		else {
			av7110->osdwin = dc->x0;
			ret = 0;
		}
		break;
	case OSD_MoveWindow:
		ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
		if (!ret)
			ret = SetColorBlend(av7110, av7110->osdwin);
		break;
	case OSD_OpenRaw:
		if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
			ret = -EINVAL;
			break;
		}
		if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
			av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
		else
			av7110->osdbpp[av7110->osdwin] = 0;
		ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
				dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
		if (ret)
			break;
		if (!dc->data) {
			ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
			if (!ret)
				ret = SetColorBlend(av7110, av7110->osdwin);
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}

	mutex_unlock(&av7110->osd_mutex);
	if (ret==-ERESTARTSYS)
		dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
	else if (ret)
		dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);

	return ret;
}

int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
{
	switch (cap->cmd) {
	case OSD_CAP_MEMSIZE:
		if (FW_4M_SDRAM(av7110->arm_app))
			cap->val = 1000000;
		else
			cap->val = 92000;
		return 0;
	default:
		return -EINVAL;
	}
}
#endif /* CONFIG_DVB_AV7110_OSD */
