// SPDX-License-Identifier: GPL-2.0-or-later
/*
* 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>
*
* the project's page is at https://linuxtv.org
*/
/* for debugging ARM communication: */
//#define COM_DEBUG
#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
/*
* Max transfer size done by av7110_fw_cmd()
*
* The maximum size passed to this function is 6 bytes. The buffer also
* uses two additional ones for type and size. So, 8 bytes is enough.
*/
#define MAX_XFER_SIZE 8
/****************************************************************************
* 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, unsigned int count)
{
struct saa7146_dev *dev = av7110->dev;
if (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, unsigned int count)
{
struct saa7146_dev *dev = av7110->dev;
u32 result = 0;
if (count > 32764) {
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 &=