Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit add20636 authored by Manu Abraham's avatar Manu Abraham Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (13794): [Mantis/VP-3028] Initial go at Serial interface...


V4L/DVB (13794): [Mantis/VP-3028] Initial go at Serial interface implementation, add support for VP-3028

Signed-off-by: default avatarManu Abraham <manu@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent ec1b6ff1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
mantis-objs = 	mantis_core.o	\
		mantis_uart.o	\
		mantis_dma.o	\
		mantis_pci.o	\
		mantis_i2c.o	\
@@ -12,6 +13,7 @@ mantis-objs = mantis_core.o \
		mantis_vp1041.o	\
		mantis_vp2033.o	\
		mantis_vp2040.o	\
		mantis_vp3028.o	\
		mantis_vp3030.o

obj-$(CONFIG_DVB_MANTIS) += mantis.o
+10 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>

#include "dvbdev.h"
#include "dvb_demux.h"
@@ -34,6 +35,7 @@
#include "dvb_net.h"
#include <linux/i2c.h>
#include "mantis_reg.h"
#include "mantis_uart.h"

#include "mantis_link.h"

@@ -74,6 +76,10 @@ struct mantis_hwconfig {
	char			*model_name;
	char			*dev_type;
	u32			ts_size;

	enum mantis_baud	baud_rate;
	enum mantis_parity	parity;
	u32			bytes;
};

struct mantis_pci {
@@ -142,6 +148,10 @@ struct mantis_pci {
	u32			gpif_status;

	struct mantis_ca	*mantis_ca;

	wait_queue_head_t	uart_wq;
	struct work_struct	uart_work;
	spinlock_t		uart_lock;
};

#define MANTIS_HIF_STATUS	(mantis->gpio_status)
+8 −0
Original line number Diff line number Diff line
@@ -165,6 +165,10 @@ int mantis_core_init(struct mantis_pci *mantis)
		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
		return err;
	}
	if ((err = mantis_uart_init(mantis)) < 0) {
		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed");
		return err;
	}

	return 0;
}
@@ -173,6 +177,10 @@ int mantis_core_exit(struct mantis_pci *mantis)
{
	mantis_dma_stop(mantis);
	dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping");

	mantis_uart_exit(mantis);
	dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");

	if (mantis_dma_exit(mantis) < 0)
		dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed");
	if (mantis_dvb_exit(mantis) < 0)
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include "mantis_common.h"
#include "mantis_core.h"
#include "mantis_uart.h"

#include <asm/irq.h>
#include <linux/signal.h>
@@ -94,6 +95,7 @@ static irqreturn_t mantis_pci_irq(int irq, void *dev_id)
	}
	if (stat & MANTIS_INT_IRQ1) {
		dprintk(verbose, MANTIS_DEBUG, 0, "* INT IRQ-1 *");
		schedule_work(&mantis->uart_work);
	}
	if (stat & MANTIS_INT_OCERR) {
		dprintk(verbose, MANTIS_DEBUG, 0, "* INT OCERR *");
+139 −0
Original line number Diff line number Diff line
#include <linux/spinlock.h>
#include "mantis_common.h"

struct mantis_uart_params {
	enum mantis_baud	baud_rate;
	enum mantis_parity	parity;
};

#define UART_MAX_BUF			16

int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
{
	struct mantis_hwconfig *config = mantis->hwconfig;
	u32 stat, i;
	unsigned long flags;

	/* get data */
	for (i = 0; i < (config->bytes + 1); i++) {

		if (stat & MANTIS_UART_RXFIFO_FULL) {
			dprintk(verbose, MANTIS_ERROR, 1, "RX Fifo FULL");
		}
		data[i] = mmread(MANTIS_UART_RXD) & 0x3f;

		stat = mmread(MANTIS_UART_STAT);

		dprintk(verbose, MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);

		if (data[i] & (1 << 7)) {
			dprintk(verbose, MANTIS_ERROR, 1, "UART framing error");
			return -EINVAL;
		}
		if (data[i] & (1 << 6)) {
			dprintk(verbose, MANTIS_ERROR, 1, "UART parity error");
			return -EINVAL;
		}
	}

	return 0;
}

static void mantis_uart_work(struct work_struct *work)
{
	struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
	struct mantis_hwconfig *config = mantis->hwconfig;
	u8 buf[16];
	int i;

	dprintk(verbose, MANTIS_DEBUG, 1, "UART read");
	mantis_uart_read(mantis, buf);

	dprintk(verbose, MANTIS_DEBUG, 1, "UART: ");
	for (i = 0; i < (config->bytes + 1); i++)
		dprintk(verbose, MANTIS_DEBUG, 0, "<%02x> ", buf[i]);

	dprintk(verbose, MANTIS_DEBUG, 0, "\n");
}

static int mantis_uart_setup(struct mantis_pci *mantis,
			     struct mantis_uart_params *params)
{
	char* rates[] = { "B_9600", "B_19200", "B_38400", "B_57600", "B_115200" };
	char* parity[] = { "NONE", "ODD", "EVEN" };

	u32 reg;

	dprintk(verbose, MANTIS_DEBUG, 1, "Set Parity <%s> Baud Rate <%s>",
		parity[params->parity],
		rates[params->baud_rate]);

	mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);

	reg = mmread(MANTIS_UART_BAUD);

	switch (params->baud_rate) {
	case MANTIS_BAUD_9600:
		reg |= 0xd8;
		break;
	case MANTIS_BAUD_19200:
		reg |= 0x6c;
		break;
	case MANTIS_BAUD_38400:
		reg |= 0x36;
		break;
	case MANTIS_BAUD_57600:
		reg |= 0x23;
		break;
	case MANTIS_BAUD_115200:
		reg |= 0x11;
		break;
	default:
		return -EINVAL;
	}

	mmwrite(reg, MANTIS_UART_BAUD);

	return 0;
}

int mantis_uart_init(struct mantis_pci *mantis)
{
	struct mantis_hwconfig *config = mantis->hwconfig;
	struct mantis_uart_params params;

	dprintk(verbose, MANTIS_DEBUG, 1, "Initializing UART ..");
	/* default parity: */
	params.baud_rate = config->baud_rate;
	params.parity = config->parity;

	init_waitqueue_head(&mantis->uart_wq);
	spin_lock_init(&mantis->uart_lock);

	INIT_WORK(&mantis->uart_work, mantis_uart_work);

	/* disable interrupt */
	mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);

	mantis_uart_setup(mantis, &params);

	/* default 1 byte */
	mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);

	/* flush buffer */
	mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);

	/* enable interrupt */
	mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
	mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);

	schedule_work(&mantis->uart_work);

	return 0;
}

void mantis_uart_exit(struct mantis_pci *mantis)
{
	/* disable interrupt */
	mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
}
Loading