18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Earthsoft PT3 driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef PT3_H 98c2ecf20Sopenharmony_ci#define PT3_H 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/atomic.h> 128c2ecf20Sopenharmony_ci#include <linux/types.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <media/dvb_demux.h> 158c2ecf20Sopenharmony_ci#include <media/dvb_frontend.h> 168c2ecf20Sopenharmony_ci#include <media/dmxdev.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "tc90522.h" 198c2ecf20Sopenharmony_ci#include "mxl301rf.h" 208c2ecf20Sopenharmony_ci#include "qm1d1c0042.h" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define DRV_NAME KBUILD_MODNAME 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define PT3_NUM_FE 4 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * register index of the FPGA chip 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci#define REG_VERSION 0x00 308c2ecf20Sopenharmony_ci#define REG_BUS 0x04 318c2ecf20Sopenharmony_ci#define REG_SYSTEM_W 0x08 328c2ecf20Sopenharmony_ci#define REG_SYSTEM_R 0x0c 338c2ecf20Sopenharmony_ci#define REG_I2C_W 0x10 348c2ecf20Sopenharmony_ci#define REG_I2C_R 0x14 358c2ecf20Sopenharmony_ci#define REG_RAM_W 0x18 368c2ecf20Sopenharmony_ci#define REG_RAM_R 0x1c 378c2ecf20Sopenharmony_ci#define REG_DMA_BASE 0x40 /* regs for FE[i] = REG_DMA_BASE + 0x18 * i */ 388c2ecf20Sopenharmony_ci#define OFST_DMA_DESC_L 0x00 398c2ecf20Sopenharmony_ci#define OFST_DMA_DESC_H 0x04 408c2ecf20Sopenharmony_ci#define OFST_DMA_CTL 0x08 418c2ecf20Sopenharmony_ci#define OFST_TS_CTL 0x0c 428c2ecf20Sopenharmony_ci#define OFST_STATUS 0x10 438c2ecf20Sopenharmony_ci#define OFST_TS_ERR 0x14 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/* 468c2ecf20Sopenharmony_ci * internal buffer for I2C 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci#define PT3_I2C_MAX 4091 498c2ecf20Sopenharmony_cistruct pt3_i2cbuf { 508c2ecf20Sopenharmony_ci u8 data[PT3_I2C_MAX]; 518c2ecf20Sopenharmony_ci u8 tmp; 528c2ecf20Sopenharmony_ci u32 num_cmds; 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/* 568c2ecf20Sopenharmony_ci * DMA things 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci#define TS_PACKET_SZ 188 598c2ecf20Sopenharmony_ci/* DMA transfers must not cross 4GiB, so use one page / transfer */ 608c2ecf20Sopenharmony_ci#define DATA_XFER_SZ 4096 618c2ecf20Sopenharmony_ci#define DATA_BUF_XFERS 47 628c2ecf20Sopenharmony_ci/* (num_bufs * DATA_BUF_SZ) % TS_PACKET_SZ must be 0 */ 638c2ecf20Sopenharmony_ci#define DATA_BUF_SZ (DATA_BUF_XFERS * DATA_XFER_SZ) 648c2ecf20Sopenharmony_ci#define MAX_DATA_BUFS 16 658c2ecf20Sopenharmony_ci#define MIN_DATA_BUFS 2 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define DESCS_IN_PAGE (PAGE_SIZE / sizeof(struct xfer_desc)) 688c2ecf20Sopenharmony_ci#define MAX_NUM_XFERS (MAX_DATA_BUFS * DATA_BUF_XFERS) 698c2ecf20Sopenharmony_ci#define MAX_DESC_BUFS DIV_ROUND_UP(MAX_NUM_XFERS, DESCS_IN_PAGE) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* DMA transfer description. 728c2ecf20Sopenharmony_ci * device is passed a pointer to this struct, dma-reads it, 738c2ecf20Sopenharmony_ci * and gets the DMA buffer ring for storing TS data. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_cistruct xfer_desc { 768c2ecf20Sopenharmony_ci u32 addr_l; /* bus address of target data buffer */ 778c2ecf20Sopenharmony_ci u32 addr_h; 788c2ecf20Sopenharmony_ci u32 size; 798c2ecf20Sopenharmony_ci u32 next_l; /* bus address of the next xfer_desc */ 808c2ecf20Sopenharmony_ci u32 next_h; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci/* A DMA mapping of a page containing xfer_desc's */ 848c2ecf20Sopenharmony_cistruct xfer_desc_buffer { 858c2ecf20Sopenharmony_ci dma_addr_t b_addr; 868c2ecf20Sopenharmony_ci struct xfer_desc *descs; /* PAGE_SIZE (xfer_desc[DESCS_IN_PAGE]) */ 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/* A DMA mapping of a data buffer */ 908c2ecf20Sopenharmony_cistruct dma_data_buffer { 918c2ecf20Sopenharmony_ci dma_addr_t b_addr; 928c2ecf20Sopenharmony_ci u8 *data; /* size: u8[PAGE_SIZE] */ 938c2ecf20Sopenharmony_ci}; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* 968c2ecf20Sopenharmony_ci * device things 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_cistruct pt3_adap_config { 998c2ecf20Sopenharmony_ci struct i2c_board_info demod_info; 1008c2ecf20Sopenharmony_ci struct tc90522_config demod_cfg; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci struct i2c_board_info tuner_info; 1038c2ecf20Sopenharmony_ci union tuner_config { 1048c2ecf20Sopenharmony_ci struct qm1d1c0042_config qm1d1c0042; 1058c2ecf20Sopenharmony_ci struct mxl301rf_config mxl301rf; 1068c2ecf20Sopenharmony_ci } tuner_cfg; 1078c2ecf20Sopenharmony_ci u32 init_freq; 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistruct pt3_adapter { 1118c2ecf20Sopenharmony_ci struct dvb_adapter dvb_adap; /* dvb_adap.priv => struct pt3_board */ 1128c2ecf20Sopenharmony_ci int adap_idx; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci struct dvb_demux demux; 1158c2ecf20Sopenharmony_ci struct dmxdev dmxdev; 1168c2ecf20Sopenharmony_ci struct dvb_frontend *fe; 1178c2ecf20Sopenharmony_ci struct i2c_client *i2c_demod; 1188c2ecf20Sopenharmony_ci struct i2c_client *i2c_tuner; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* data fetch thread */ 1218c2ecf20Sopenharmony_ci struct task_struct *thread; 1228c2ecf20Sopenharmony_ci int num_feeds; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci bool cur_lna; 1258c2ecf20Sopenharmony_ci bool cur_lnb; /* current LNB power status (on/off) */ 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci /* items below are for DMA */ 1288c2ecf20Sopenharmony_ci struct dma_data_buffer buffer[MAX_DATA_BUFS]; 1298c2ecf20Sopenharmony_ci int buf_idx; 1308c2ecf20Sopenharmony_ci int buf_ofs; 1318c2ecf20Sopenharmony_ci int num_bufs; /* == pt3_board->num_bufs */ 1328c2ecf20Sopenharmony_ci int num_discard; /* how many access units to discard initially */ 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci struct xfer_desc_buffer desc_buf[MAX_DESC_BUFS]; 1358c2ecf20Sopenharmony_ci int num_desc_bufs; /* == num_bufs * DATA_BUF_XFERS / DESCS_IN_PAGE */ 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistruct pt3_board { 1408c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1418c2ecf20Sopenharmony_ci void __iomem *regs[2]; 1428c2ecf20Sopenharmony_ci /* regs[0]: registers, regs[1]: internal memory, used for I2C */ 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci struct mutex lock; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci /* LNB power shared among sat-FEs */ 1478c2ecf20Sopenharmony_ci int lnb_on_cnt; /* LNB power on count */ 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci /* LNA shared among terr-FEs */ 1508c2ecf20Sopenharmony_ci int lna_on_cnt; /* booster enabled count */ 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci int num_bufs; /* number of DMA buffers allocated/mapped per FE */ 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci struct i2c_adapter i2c_adap; 1558c2ecf20Sopenharmony_ci struct pt3_i2cbuf *i2c_buf; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci struct pt3_adapter *adaps[PT3_NUM_FE]; 1588c2ecf20Sopenharmony_ci}; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/* 1628c2ecf20Sopenharmony_ci * prototypes 1638c2ecf20Sopenharmony_ci */ 1648c2ecf20Sopenharmony_ciextern int pt3_alloc_dmabuf(struct pt3_adapter *adap); 1658c2ecf20Sopenharmony_ciextern void pt3_init_dmabuf(struct pt3_adapter *adap); 1668c2ecf20Sopenharmony_ciextern void pt3_free_dmabuf(struct pt3_adapter *adap); 1678c2ecf20Sopenharmony_ciextern int pt3_start_dma(struct pt3_adapter *adap); 1688c2ecf20Sopenharmony_ciextern int pt3_stop_dma(struct pt3_adapter *adap); 1698c2ecf20Sopenharmony_ciextern int pt3_proc_dma(struct pt3_adapter *adap); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ciextern int pt3_i2c_master_xfer(struct i2c_adapter *adap, 1728c2ecf20Sopenharmony_ci struct i2c_msg *msgs, int num); 1738c2ecf20Sopenharmony_ciextern u32 pt3_i2c_functionality(struct i2c_adapter *adap); 1748c2ecf20Sopenharmony_ciextern void pt3_i2c_reset(struct pt3_board *pt3); 1758c2ecf20Sopenharmony_ciextern int pt3_init_all_demods(struct pt3_board *pt3); 1768c2ecf20Sopenharmony_ciextern int pt3_init_all_mxl301rf(struct pt3_board *pt3); 1778c2ecf20Sopenharmony_ci#endif /* PT3_H */ 178