1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * ddbridge-mci.h: Digital Devices micro code interface 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2017-2018 Digital Devices GmbH 6*4882a593Smuzhiyun * Marcus Metzler <mocm@metzlerbros.de> 7*4882a593Smuzhiyun * Ralph Metzler <rjkm@metzlerbros.de> 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or 10*4882a593Smuzhiyun * modify it under the terms of the GNU General Public License 11*4882a593Smuzhiyun * version 2 only, as published by the Free Software Foundation. 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 14*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*4882a593Smuzhiyun * GNU General Public License for more details. 17*4882a593Smuzhiyun */ 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #ifndef _DDBRIDGE_MCI_H_ 20*4882a593Smuzhiyun #define _DDBRIDGE_MCI_H_ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun #define MCI_DEMOD_MAX 8 23*4882a593Smuzhiyun #define MCI_TUNER_MAX 4 24*4882a593Smuzhiyun #define DEMOD_UNUSED (0xFF) 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #define MCI_CONTROL (0x500) 27*4882a593Smuzhiyun #define MCI_COMMAND (0x600) 28*4882a593Smuzhiyun #define MCI_RESULT (0x680) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun #define MCI_COMMAND_SIZE (0x80) 31*4882a593Smuzhiyun #define MCI_RESULT_SIZE (0x80) 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define MCI_CONTROL_START_COMMAND (0x00000001) 34*4882a593Smuzhiyun #define MCI_CONTROL_ENABLE_DONE_INTERRUPT (0x00000002) 35*4882a593Smuzhiyun #define MCI_CONTROL_RESET (0x00008000) 36*4882a593Smuzhiyun #define MCI_CONTROL_READY (0x00010000) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun #define SX8_TSCONFIG (0x280) 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_MASK (0x00000003) 41*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_OFF (0x00000000) 42*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_NORMAL (0x00000001) 43*4882a593Smuzhiyun #define SX8_TSCONFIG_MODE_IQ (0x00000003) 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun /* 46*4882a593Smuzhiyun * IQMode is only available on MaxSX8 on a single tuner 47*4882a593Smuzhiyun * 48*4882a593Smuzhiyun * IQ_MODE_SAMPLES 49*4882a593Smuzhiyun * sampling rate is 1550/24 MHz (64.583 MHz) 50*4882a593Smuzhiyun * channel agc is frozen, to allow stitching the FFT results together 51*4882a593Smuzhiyun * 52*4882a593Smuzhiyun * IQ_MODE_VTM 53*4882a593Smuzhiyun * sampling rate is the supplied symbolrate 54*4882a593Smuzhiyun * channel agc is active 55*4882a593Smuzhiyun * 56*4882a593Smuzhiyun * in both cases down sampling is done with a RRC Filter (currently fixed to 57*4882a593Smuzhiyun * alpha = 0.05) which causes some (ca 5%) aliasing at the edges from 58*4882a593Smuzhiyun * outside the spectrum 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun #define SX8_TSCONFIG_TSHEADER (0x00000004) 62*4882a593Smuzhiyun #define SX8_TSCONFIG_BURST (0x00000008) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_MASK (0x00000030) 65*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_2K (0x00000000) 66*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_4K (0x00000010) 67*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_8K (0x00000020) 68*4882a593Smuzhiyun #define SX8_TSCONFIG_BURSTSIZE_16K (0x00000030) 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun #define SX8_DEMOD_STOPPED (0) 71*4882a593Smuzhiyun #define SX8_DEMOD_IQ_MODE (1) 72*4882a593Smuzhiyun #define SX8_DEMOD_WAIT_SIGNAL (2) 73*4882a593Smuzhiyun #define SX8_DEMOD_WAIT_MATYPE (3) 74*4882a593Smuzhiyun #define SX8_DEMOD_TIMEOUT (14) 75*4882a593Smuzhiyun #define SX8_DEMOD_LOCKED (15) 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun #define MCI_CMD_STOP (0x01) 78*4882a593Smuzhiyun #define MCI_CMD_GETSTATUS (0x02) 79*4882a593Smuzhiyun #define MCI_CMD_GETSIGNALINFO (0x03) 80*4882a593Smuzhiyun #define MCI_CMD_RFPOWER (0x04) 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun #define MCI_CMD_SEARCH_DVBS (0x10) 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun #define MCI_CMD_GET_IQSYMBOL (0x30) 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun #define SX8_CMD_INPUT_ENABLE (0x40) 87*4882a593Smuzhiyun #define SX8_CMD_INPUT_DISABLE (0x41) 88*4882a593Smuzhiyun #define SX8_CMD_START_IQ (0x42) 89*4882a593Smuzhiyun #define SX8_CMD_STOP_IQ (0x43) 90*4882a593Smuzhiyun #define SX8_CMD_ENABLE_IQOUTPUT (0x44) 91*4882a593Smuzhiyun #define SX8_CMD_DISABLE_IQOUTPUT (0x45) 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun #define MCI_STATUS_OK (0x00) 94*4882a593Smuzhiyun #define MCI_STATUS_UNSUPPORTED (0x80) 95*4882a593Smuzhiyun #define MCI_STATUS_RETRY (0xFD) 96*4882a593Smuzhiyun #define MCI_STATUS_NOT_READY (0xFE) 97*4882a593Smuzhiyun #define MCI_STATUS_ERROR (0xFF) 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun #define MCI_SUCCESS(status) ((status & MCI_STATUS_UNSUPPORTED) == 0) 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun struct mci_command { 102*4882a593Smuzhiyun union { 103*4882a593Smuzhiyun u32 command_word; 104*4882a593Smuzhiyun struct { 105*4882a593Smuzhiyun u8 command; 106*4882a593Smuzhiyun u8 tuner; 107*4882a593Smuzhiyun u8 demod; 108*4882a593Smuzhiyun u8 output; 109*4882a593Smuzhiyun }; 110*4882a593Smuzhiyun }; 111*4882a593Smuzhiyun union { 112*4882a593Smuzhiyun u32 params[31]; 113*4882a593Smuzhiyun struct { 114*4882a593Smuzhiyun /* 115*4882a593Smuzhiyun * Bit 0: DVB-S Enabled 116*4882a593Smuzhiyun * Bit 1: DVB-S2 Enabled 117*4882a593Smuzhiyun * Bit 7: InputStreamID 118*4882a593Smuzhiyun */ 119*4882a593Smuzhiyun u8 flags; 120*4882a593Smuzhiyun /* 121*4882a593Smuzhiyun * Bit 0: QPSK, 122*4882a593Smuzhiyun * Bit 1: 8PSK/8APSK 123*4882a593Smuzhiyun * Bit 2: 16APSK 124*4882a593Smuzhiyun * Bit 3: 32APSK 125*4882a593Smuzhiyun * Bit 4: 64APSK 126*4882a593Smuzhiyun * Bit 5: 128APSK 127*4882a593Smuzhiyun * Bit 6: 256APSK 128*4882a593Smuzhiyun */ 129*4882a593Smuzhiyun u8 s2_modulation_mask; 130*4882a593Smuzhiyun u8 rsvd1; 131*4882a593Smuzhiyun u8 retry; 132*4882a593Smuzhiyun u32 frequency; 133*4882a593Smuzhiyun u32 symbol_rate; 134*4882a593Smuzhiyun u8 input_stream_id; 135*4882a593Smuzhiyun u8 rsvd2[3]; 136*4882a593Smuzhiyun u32 scrambling_sequence_index; 137*4882a593Smuzhiyun u32 frequency_range; 138*4882a593Smuzhiyun } dvbs2_search; 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun struct { 141*4882a593Smuzhiyun u8 tap; 142*4882a593Smuzhiyun u8 rsvd; 143*4882a593Smuzhiyun u16 point; 144*4882a593Smuzhiyun } get_iq_symbol; 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun struct { 147*4882a593Smuzhiyun /* 148*4882a593Smuzhiyun * Bit 0: 0=VTM/1=SCAN 149*4882a593Smuzhiyun * Bit 1: Set Gain 150*4882a593Smuzhiyun */ 151*4882a593Smuzhiyun u8 flags; 152*4882a593Smuzhiyun u8 roll_off; 153*4882a593Smuzhiyun u8 rsvd1; 154*4882a593Smuzhiyun u8 rsvd2; 155*4882a593Smuzhiyun u32 frequency; 156*4882a593Smuzhiyun u32 symbol_rate; /* Only in VTM mode */ 157*4882a593Smuzhiyun u16 gain; 158*4882a593Smuzhiyun } sx8_start_iq; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun struct { 161*4882a593Smuzhiyun /* 162*4882a593Smuzhiyun * Bit 1:0 = STVVGLNA Gain. 163*4882a593Smuzhiyun * 0 = AGC, 1 = 0dB, 2 = Minimum, 3 = Maximum 164*4882a593Smuzhiyun */ 165*4882a593Smuzhiyun u8 flags; 166*4882a593Smuzhiyun } sx8_input_enable; 167*4882a593Smuzhiyun }; 168*4882a593Smuzhiyun }; 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun struct mci_result { 171*4882a593Smuzhiyun union { 172*4882a593Smuzhiyun u32 status_word; 173*4882a593Smuzhiyun struct { 174*4882a593Smuzhiyun u8 status; 175*4882a593Smuzhiyun u8 mode; 176*4882a593Smuzhiyun u16 time; 177*4882a593Smuzhiyun }; 178*4882a593Smuzhiyun }; 179*4882a593Smuzhiyun union { 180*4882a593Smuzhiyun u32 result[27]; 181*4882a593Smuzhiyun struct { 182*4882a593Smuzhiyun /* 1 = DVB-S, 2 = DVB-S2X */ 183*4882a593Smuzhiyun u8 standard; 184*4882a593Smuzhiyun /* puncture rate for DVB-S */ 185*4882a593Smuzhiyun u8 pls_code; 186*4882a593Smuzhiyun /* 2-0: rolloff */ 187*4882a593Smuzhiyun u8 roll_off; 188*4882a593Smuzhiyun u8 rsvd; 189*4882a593Smuzhiyun /* actual frequency in Hz */ 190*4882a593Smuzhiyun u32 frequency; 191*4882a593Smuzhiyun /* actual symbolrate in Hz */ 192*4882a593Smuzhiyun u32 symbol_rate; 193*4882a593Smuzhiyun /* channel power in dBm x 100 */ 194*4882a593Smuzhiyun s16 channel_power; 195*4882a593Smuzhiyun /* band power in dBm x 100 */ 196*4882a593Smuzhiyun s16 band_power; 197*4882a593Smuzhiyun /* 198*4882a593Smuzhiyun * SNR in dB x 100 199*4882a593Smuzhiyun * Note: negative values are valid in DVB-S2 200*4882a593Smuzhiyun */ 201*4882a593Smuzhiyun s16 signal_to_noise; 202*4882a593Smuzhiyun s16 rsvd2; 203*4882a593Smuzhiyun /* 204*4882a593Smuzhiyun * Counter for packet errors 205*4882a593Smuzhiyun * (set to 0 on start command) 206*4882a593Smuzhiyun */ 207*4882a593Smuzhiyun u32 packet_errors; 208*4882a593Smuzhiyun /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ 209*4882a593Smuzhiyun u32 ber_numerator; 210*4882a593Smuzhiyun u32 ber_denominator; 211*4882a593Smuzhiyun } dvbs2_signal_info; 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun struct { 214*4882a593Smuzhiyun s16 i; 215*4882a593Smuzhiyun s16 q; 216*4882a593Smuzhiyun } iq_symbol; 217*4882a593Smuzhiyun }; 218*4882a593Smuzhiyun u32 version[4]; 219*4882a593Smuzhiyun }; 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun struct mci_base { 222*4882a593Smuzhiyun struct list_head mci_list; 223*4882a593Smuzhiyun void *key; 224*4882a593Smuzhiyun struct ddb_link *link; 225*4882a593Smuzhiyun struct completion completion; 226*4882a593Smuzhiyun struct device *dev; 227*4882a593Smuzhiyun struct mutex tuner_lock; /* concurrent tuner access lock */ 228*4882a593Smuzhiyun struct mutex mci_lock; /* concurrent MCI access lock */ 229*4882a593Smuzhiyun int count; 230*4882a593Smuzhiyun int type; 231*4882a593Smuzhiyun }; 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun struct mci { 234*4882a593Smuzhiyun struct mci_base *base; 235*4882a593Smuzhiyun struct dvb_frontend fe; 236*4882a593Smuzhiyun int nr; 237*4882a593Smuzhiyun int demod; 238*4882a593Smuzhiyun int tuner; 239*4882a593Smuzhiyun }; 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun struct mci_cfg { 242*4882a593Smuzhiyun int type; 243*4882a593Smuzhiyun struct dvb_frontend_ops *fe_ops; 244*4882a593Smuzhiyun u32 base_size; 245*4882a593Smuzhiyun u32 state_size; 246*4882a593Smuzhiyun int (*init)(struct mci *mci); 247*4882a593Smuzhiyun int (*base_init)(struct mci_base *mci_base); 248*4882a593Smuzhiyun int (*set_input)(struct dvb_frontend *fe, int input); 249*4882a593Smuzhiyun }; 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun /* defined in ddbridge-sx8.c */ 252*4882a593Smuzhiyun extern const struct mci_cfg ddb_max_sx8_cfg; 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun int ddb_mci_cmd(struct mci *state, struct mci_command *command, 255*4882a593Smuzhiyun struct mci_result *result); 256*4882a593Smuzhiyun int ddb_mci_config(struct mci *state, u32 config); 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun struct dvb_frontend 259*4882a593Smuzhiyun *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, 260*4882a593Smuzhiyun int (**fn_set_input)(struct dvb_frontend *fe, int input)); 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun #endif /* _DDBRIDGE_MCI_H_ */ 263