18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci Mantis PCI bridge driver 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci Copyright (C) Manu Abraham (abraham.manu@gmail.com) 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci*/ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/signal.h> 128c2ecf20Sopenharmony_ci#include <linux/sched.h> 138c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 148c2ecf20Sopenharmony_ci#include <asm/io.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <media/dmxdev.h> 178c2ecf20Sopenharmony_ci#include <media/dvbdev.h> 188c2ecf20Sopenharmony_ci#include <media/dvb_demux.h> 198c2ecf20Sopenharmony_ci#include <media/dvb_frontend.h> 208c2ecf20Sopenharmony_ci#include <media/dvb_net.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include "mantis_common.h" 238c2ecf20Sopenharmony_ci#include "mantis_link.h" 248c2ecf20Sopenharmony_ci#include "mantis_hif.h" 258c2ecf20Sopenharmony_ci#include "mantis_reg.h" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic void mantis_hifevm_work(struct work_struct *work) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); 308c2ecf20Sopenharmony_ci struct mantis_pci *mantis = ca->ca_priv; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci u32 gpif_stat; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci gpif_stat = mmread(MANTIS_GPIF_STATUS); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_GPIF_DETSTAT) { 378c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_CARD_PLUGIN) { 388c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num); 398c2ecf20Sopenharmony_ci mmwrite(0xdada0000, MANTIS_CARD_RESET); 408c2ecf20Sopenharmony_ci mantis_event_cam_plugin(ca); 418c2ecf20Sopenharmony_ci dvb_ca_en50221_camchange_irq(&ca->en50221, 428c2ecf20Sopenharmony_ci 0, 438c2ecf20Sopenharmony_ci DVB_CA_EN50221_CAMCHANGE_INSERTED); 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci } else { 468c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_CARD_PLUGOUT) { 478c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num); 488c2ecf20Sopenharmony_ci mmwrite(0xdada0000, MANTIS_CARD_RESET); 498c2ecf20Sopenharmony_ci mantis_event_cam_unplug(ca); 508c2ecf20Sopenharmony_ci dvb_ca_en50221_camchange_irq(&ca->en50221, 518c2ecf20Sopenharmony_ci 0, 528c2ecf20Sopenharmony_ci DVB_CA_EN50221_CAMCHANGE_REMOVED); 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci } 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ) 578c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci if (mantis->gpif_status & MANTIS_SBUF_WSTO) 608c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (mantis->gpif_status & MANTIS_GPIF_OTHERR) 638c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_SBUF_OVFLW) 668c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_GPIF_BRRDY) 698c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_GPIF_INTSTAT) 728c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_SBUF_EMPTY) 758c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci if (gpif_stat & MANTIS_SBUF_OPDONE) { 788c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num); 798c2ecf20Sopenharmony_ci ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL; 808c2ecf20Sopenharmony_ci ca->hif_event = MANTIS_SBUF_OPDONE; 818c2ecf20Sopenharmony_ci wake_up(&ca->hif_opdone_wq); 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciint mantis_evmgr_init(struct mantis_ca *ca) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci struct mantis_pci *mantis = ca->ca_priv; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager"); 908c2ecf20Sopenharmony_ci INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work); 918c2ecf20Sopenharmony_ci mantis_pcmcia_init(ca); 928c2ecf20Sopenharmony_ci schedule_work(&ca->hif_evm_work); 938c2ecf20Sopenharmony_ci mantis_hif_init(ca); 948c2ecf20Sopenharmony_ci return 0; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_civoid mantis_evmgr_exit(struct mantis_ca *ca) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci struct mantis_pci *mantis = ca->ca_priv; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); 1028c2ecf20Sopenharmony_ci flush_work(&ca->hif_evm_work); 1038c2ecf20Sopenharmony_ci mantis_hif_exit(ca); 1048c2ecf20Sopenharmony_ci mantis_pcmcia_exit(ca); 1058c2ecf20Sopenharmony_ci} 106