root/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * cxd2880_tnrdmd.h
 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
 * common control interface
 *
 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
 */

#ifndef CXD2880_TNRDMD_H
#define CXD2880_TNRDMD_H

#include <linux/atomic.h>

#include "cxd2880_common.h"
#include "cxd2880_io.h"
#include "cxd2880_dtv.h"
#include "cxd2880_dvbt.h"
#include "cxd2880_dvbt2.h"

#define CXD2880_TNRDMD_MAX_CFG_MEM_COUNT 100

#define slvt_unfreeze_reg(tnr_dmd) ((void)((tnr_dmd)->io->write_reg\
((tnr_dmd)->io, CXD2880_IO_TGT_DMD, 0x01, 0x00)))

#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_UNDERFLOW     0x0001
#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_OVERFLOW      0x0002
#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_EMPTY  0x0004
#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_FULL   0x0008
#define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_RRDY    0x0010
#define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_COMMAND      0x0020
#define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_ACCESS       0x0040
#define CXD2880_TNRDMD_INTERRUPT_TYPE_CPU_ERROR     0x0100
#define CXD2880_TNRDMD_INTERRUPT_TYPE_LOCK               0x0200
#define CXD2880_TNRDMD_INTERRUPT_TYPE_INV_LOCK       0x0400
#define CXD2880_TNRDMD_INTERRUPT_TYPE_NOOFDM           0x0800
#define CXD2880_TNRDMD_INTERRUPT_TYPE_EWS                 0x1000
#define CXD2880_TNRDMD_INTERRUPT_TYPE_EEW                 0x2000
#define CXD2880_TNRDMD_INTERRUPT_TYPE_FEC_FAIL       0x4000

#define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_L1POST_OK     0x01
#define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_DMD_LOCK       0x02
#define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_TS_LOCK         0x04

enum cxd2880_tnrdmd_chip_id {
        CXD2880_TNRDMD_CHIP_ID_UNKNOWN = 0x00,
        CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X = 0x62,
        CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11 = 0x6a
};

#define CXD2880_TNRDMD_CHIP_ID_VALID(chip_id) \
        (((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) || \
         ((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11))

enum cxd2880_tnrdmd_state {
        CXD2880_TNRDMD_STATE_UNKNOWN,
        CXD2880_TNRDMD_STATE_SLEEP,
        CXD2880_TNRDMD_STATE_ACTIVE,
        CXD2880_TNRDMD_STATE_INVALID
};

enum cxd2880_tnrdmd_divermode {
        CXD2880_TNRDMD_DIVERMODE_SINGLE,
        CXD2880_TNRDMD_DIVERMODE_MAIN,
        CXD2880_TNRDMD_DIVERMODE_SUB
};

enum cxd2880_tnrdmd_clockmode {
        CXD2880_TNRDMD_CLOCKMODE_UNKNOWN,
        CXD2880_TNRDMD_CLOCKMODE_A,
        CXD2880_TNRDMD_CLOCKMODE_B,
        CXD2880_TNRDMD_CLOCKMODE_C
};

enum cxd2880_tnrdmd_tsout_if {
        CXD2880_TNRDMD_TSOUT_IF_TS,
        CXD2880_TNRDMD_TSOUT_IF_SPI,
        CXD2880_TNRDMD_TSOUT_IF_SDIO
};

enum cxd2880_tnrdmd_xtal_share {
        CXD2880_TNRDMD_XTAL_SHARE_NONE,
        CXD2880_TNRDMD_XTAL_SHARE_EXTREF,
        CXD2880_TNRDMD_XTAL_SHARE_MASTER,
        CXD2880_TNRDMD_XTAL_SHARE_SLAVE
};

enum cxd2880_tnrdmd_spectrum_sense {
        CXD2880_TNRDMD_SPECTRUM_NORMAL,
        CXD2880_TNRDMD_SPECTRUM_INV
};

enum cxd2880_tnrdmd_cfg_id {
        CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB,
        CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI,
        CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI,
        CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI,
        CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE,
        CXD2880_TNRDMD_CFG_TSCLK_CONT,
        CXD2880_TNRDMD_CFG_TSCLK_MASK,
        CXD2880_TNRDMD_CFG_TSVALID_MASK,
        CXD2880_TNRDMD_CFG_TSERR_MASK,
        CXD2880_TNRDMD_CFG_TSERR_VALID_DIS,
        CXD2880_TNRDMD_CFG_TSPIN_CURRENT,
        CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL,
        CXD2880_TNRDMD_CFG_TSPIN_PULLUP,
        CXD2880_TNRDMD_CFG_TSCLK_FREQ,
        CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL,
        CXD2880_TNRDMD_CFG_TS_PACKET_GAP,
        CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE,
        CXD2880_TNRDMD_CFG_PWM_VALUE,
        CXD2880_TNRDMD_CFG_INTERRUPT,
        CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL,
        CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL,
        CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS,
        CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS,
        CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS,
        CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE,
        CXD2880_TNRDMD_CFG_CABLE_INPUT,
        CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE,
        CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE,
        CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST,
        CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD,
        CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD,
        CXD2880_TNRDMD_CFG_DVBT_PER_MES,
        CXD2880_TNRDMD_CFG_DVBT2_BBER_MES,
        CXD2880_TNRDMD_CFG_DVBT2_LBER_MES,
        CXD2880_TNRDMD_CFG_DVBT2_PER_MES,
};

enum cxd2880_tnrdmd_lock_result {
        CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT,
        CXD2880_TNRDMD_LOCK_RESULT_LOCKED,
        CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
};

enum cxd2880_tnrdmd_gpio_mode {
        CXD2880_TNRDMD_GPIO_MODE_OUTPUT = 0x00,
        CXD2880_TNRDMD_GPIO_MODE_INPUT = 0x01,
        CXD2880_TNRDMD_GPIO_MODE_INT = 0x02,
        CXD2880_TNRDMD_GPIO_MODE_FEC_FAIL = 0x03,
        CXD2880_TNRDMD_GPIO_MODE_PWM = 0x04,
        CXD2880_TNRDMD_GPIO_MODE_EWS = 0x05,
        CXD2880_TNRDMD_GPIO_MODE_EEW = 0x06
};

enum cxd2880_tnrdmd_serial_ts_clk {
        CXD2880_TNRDMD_SERIAL_TS_CLK_FULL,
        CXD2880_TNRDMD_SERIAL_TS_CLK_HALF
};

struct cxd2880_tnrdmd_cfg_mem {
        enum cxd2880_io_tgt tgt;
        u8 bank;
        u8 address;
        u8 value;
        u8 bit_mask;
};

struct cxd2880_tnrdmd_pid_cfg {
        u8 is_en;
        u16 pid;
};

struct cxd2880_tnrdmd_pid_ftr_cfg {
        u8 is_negative;
        struct cxd2880_tnrdmd_pid_cfg pid_cfg[32];
};

struct cxd2880_tnrdmd_lna_thrs {
        u8 off_on;
        u8 on_off;
};

struct cxd2880_tnrdmd_lna_thrs_tbl_air {
        struct cxd2880_tnrdmd_lna_thrs thrs[24];
};

struct cxd2880_tnrdmd_lna_thrs_tbl_cable {
        struct cxd2880_tnrdmd_lna_thrs thrs[32];
};

struct cxd2880_tnrdmd_create_param {
        enum cxd2880_tnrdmd_tsout_if ts_output_if;
        u8 en_internal_ldo;
        enum cxd2880_tnrdmd_xtal_share xtal_share_type;
        u8 xosc_cap;
        u8 xosc_i;
        u8 is_cxd2881gg;
        u8 stationary_use;
};

struct cxd2880_tnrdmd_diver_create_param {
        enum cxd2880_tnrdmd_tsout_if ts_output_if;
        u8 en_internal_ldo;
        u8 xosc_cap_main;
        u8 xosc_i_main;
        u8 xosc_i_sub;
        u8 is_cxd2881gg;
        u8 stationary_use;
};

struct cxd2880_tnrdmd {
        struct cxd2880_tnrdmd *diver_sub;
        struct cxd2880_io *io;
        struct cxd2880_tnrdmd_create_param create_param;
        enum cxd2880_tnrdmd_divermode diver_mode;
        enum cxd2880_tnrdmd_clockmode fixed_clk_mode;
        u8 is_cable_input;
        u8 en_fef_intmtnt_base;
        u8 en_fef_intmtnt_lite;
        u8 blind_tune_dvbt2_first;
        int (*rf_lvl_cmpstn)(struct cxd2880_tnrdmd *tnr_dmd,
                             int *rf_lvl_db);
        struct cxd2880_tnrdmd_lna_thrs_tbl_air *lna_thrs_tbl_air;
        struct cxd2880_tnrdmd_lna_thrs_tbl_cable *lna_thrs_tbl_cable;
        u8 srl_ts_clk_mod_cnts;
        enum cxd2880_tnrdmd_serial_ts_clk srl_ts_clk_frq;
        u8 ts_byte_clk_manual_setting;
        u8 is_ts_backwards_compatible_mode;
        struct cxd2880_tnrdmd_cfg_mem cfg_mem[CXD2880_TNRDMD_MAX_CFG_MEM_COUNT];
        u8 cfg_mem_last_entry;
        struct cxd2880_tnrdmd_pid_ftr_cfg pid_ftr_cfg;
        u8 pid_ftr_cfg_en;
        void *user;
        enum cxd2880_tnrdmd_chip_id chip_id;
        enum cxd2880_tnrdmd_state state;
        enum cxd2880_tnrdmd_clockmode clk_mode;
        u32 frequency_khz;
        enum cxd2880_dtv_sys sys;
        enum cxd2880_dtv_bandwidth bandwidth;
        u8 scan_mode;
        atomic_t cancel;
};

int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
                          struct cxd2880_io *io,
                          struct cxd2880_tnrdmd_create_param
                          *create_param);

int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd
                                *tnr_dmd_main,
                                struct cxd2880_io *io_main,
                                struct cxd2880_tnrdmd *tnr_dmd_sub,
                                struct cxd2880_io *io_sub,
                                struct
                                cxd2880_tnrdmd_diver_create_param
                                *create_param);

int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd);

int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd);

int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
                                             *tnr_dmd,
                                             u8 *task_completed);

int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd
                                        *tnr_dmd,
                                        enum cxd2880_dtv_sys sys,
                                        u32 frequency_khz,
                                        enum cxd2880_dtv_bandwidth
                                        bandwidth, u8 one_seg_opt,
                                        u8 one_seg_opt_shft_dir);

int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
                                        *tnr_dmd,
                                        enum cxd2880_dtv_sys sys,
                                        u8 en_fef_intmtnt_ctrl);

int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd);

int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
                           enum cxd2880_tnrdmd_cfg_id id,
                           int value);

int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
                                u8 id,
                                u8 en,
                                enum cxd2880_tnrdmd_gpio_mode mode,
                                u8 open_drain, u8 invert);

int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd,
                                    u8 id,
                                    u8 en,
                                    enum cxd2880_tnrdmd_gpio_mode
                                    mode, u8 open_drain,
                                    u8 invert);

int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
                             u8 id, u8 *value);

int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
                                 u8 id, u8 *value);

int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
                              u8 id, u8 value);

int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
                                  u8 id, u8 value);

int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
                                  u16 *value);

int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
                                   u16 value);

int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd,
                                u8 clear_overflow_flag,
                                u8 clear_underflow_flag,
                                u8 clear_buf);

int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
                           enum cxd2880_tnrdmd_chip_id *chip_id);

int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd
                                         *tnr_dmd,
                                         enum cxd2880_io_tgt tgt,
                                         u8 bank, u8 address,
                                         u8 value, u8 bit_mask);

int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
                                 enum cxd2880_dtv_sys sys,
                                 u8 scan_mode_end);

int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
                               struct cxd2880_tnrdmd_pid_ftr_cfg
                               *pid_ftr_cfg);

int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
                                     *tnr_dmd,
                                     int (*rf_lvl_cmpstn)
                                     (struct cxd2880_tnrdmd *,
                                     int *));

int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd *tnr_dmd,
                                         int (*rf_lvl_cmpstn)
                                         (struct cxd2880_tnrdmd *,
                                         int *));

int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd,
                                struct
                                cxd2880_tnrdmd_lna_thrs_tbl_air
                                *tbl_air,
                                struct
                                cxd2880_tnrdmd_lna_thrs_tbl_cable
                                *tbl_cable);

int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd,
                                    struct
                                    cxd2880_tnrdmd_lna_thrs_tbl_air
                                    *tbl_air,
                                    struct
                                    cxd2880_tnrdmd_lna_thrs_tbl_cable
                                    *tbl_cable);

int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
                                       *tnr_dmd, u8 en, u8 value);

int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
                                 u8 en);

int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd);

#endif