162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci	Mantis PCI bridge driver
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci*/
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/signal.h>
1262306a36Sopenharmony_ci#include <linux/sched.h>
1362306a36Sopenharmony_ci#include <linux/interrupt.h>
1462306a36Sopenharmony_ci#include <asm/io.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <media/dmxdev.h>
1762306a36Sopenharmony_ci#include <media/dvbdev.h>
1862306a36Sopenharmony_ci#include <media/dvb_demux.h>
1962306a36Sopenharmony_ci#include <media/dvb_frontend.h>
2062306a36Sopenharmony_ci#include <media/dvb_net.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#include "mantis_common.h"
2362306a36Sopenharmony_ci#include "mantis_link.h"
2462306a36Sopenharmony_ci#include "mantis_hif.h"
2562306a36Sopenharmony_ci#include "mantis_reg.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic void mantis_hifevm_work(struct work_struct *work)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work);
3062306a36Sopenharmony_ci	struct mantis_pci *mantis = ca->ca_priv;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	u32 gpif_stat;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	gpif_stat = mmread(MANTIS_GPIF_STATUS);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	if (gpif_stat & MANTIS_GPIF_DETSTAT) {
3762306a36Sopenharmony_ci		if (gpif_stat & MANTIS_CARD_PLUGIN) {
3862306a36Sopenharmony_ci			dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num);
3962306a36Sopenharmony_ci			mmwrite(0xdada0000, MANTIS_CARD_RESET);
4062306a36Sopenharmony_ci			mantis_event_cam_plugin(ca);
4162306a36Sopenharmony_ci			dvb_ca_en50221_camchange_irq(&ca->en50221,
4262306a36Sopenharmony_ci						     0,
4362306a36Sopenharmony_ci						     DVB_CA_EN50221_CAMCHANGE_INSERTED);
4462306a36Sopenharmony_ci		}
4562306a36Sopenharmony_ci	} else {
4662306a36Sopenharmony_ci		if (gpif_stat & MANTIS_CARD_PLUGOUT) {
4762306a36Sopenharmony_ci			dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num);
4862306a36Sopenharmony_ci			mmwrite(0xdada0000, MANTIS_CARD_RESET);
4962306a36Sopenharmony_ci			mantis_event_cam_unplug(ca);
5062306a36Sopenharmony_ci			dvb_ca_en50221_camchange_irq(&ca->en50221,
5162306a36Sopenharmony_ci						     0,
5262306a36Sopenharmony_ci						     DVB_CA_EN50221_CAMCHANGE_REMOVED);
5362306a36Sopenharmony_ci		}
5462306a36Sopenharmony_ci	}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ)
5762306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	if (mantis->gpif_status & MANTIS_SBUF_WSTO)
6062306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num);
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	if (mantis->gpif_status & MANTIS_GPIF_OTHERR)
6362306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num);
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if (gpif_stat & MANTIS_SBUF_OVFLW)
6662306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	if (gpif_stat & MANTIS_GPIF_BRRDY)
6962306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	if (gpif_stat & MANTIS_GPIF_INTSTAT)
7262306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	if (gpif_stat & MANTIS_SBUF_EMPTY)
7562306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	if (gpif_stat & MANTIS_SBUF_OPDONE) {
7862306a36Sopenharmony_ci		dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num);
7962306a36Sopenharmony_ci		ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL;
8062306a36Sopenharmony_ci		ca->hif_event = MANTIS_SBUF_OPDONE;
8162306a36Sopenharmony_ci		wake_up(&ca->hif_opdone_wq);
8262306a36Sopenharmony_ci	}
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciint mantis_evmgr_init(struct mantis_ca *ca)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	struct mantis_pci *mantis = ca->ca_priv;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager");
9062306a36Sopenharmony_ci	INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work);
9162306a36Sopenharmony_ci	mantis_pcmcia_init(ca);
9262306a36Sopenharmony_ci	schedule_work(&ca->hif_evm_work);
9362306a36Sopenharmony_ci	mantis_hif_init(ca);
9462306a36Sopenharmony_ci	return 0;
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_civoid mantis_evmgr_exit(struct mantis_ca *ca)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	struct mantis_pci *mantis = ca->ca_priv;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting");
10262306a36Sopenharmony_ci	flush_work(&ca->hif_evm_work);
10362306a36Sopenharmony_ci	mantis_hif_exit(ca);
10462306a36Sopenharmony_ci	mantis_pcmcia_exit(ca);
10562306a36Sopenharmony_ci}
106