^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <media/dvb_math.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "dib9000.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "dibx000_common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define dprintk(fmt, arg...) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) printk(KERN_DEBUG pr_fmt("%s: " fmt), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __func__, ##arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MAX_NUMBER_OF_FRONTENDS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct i2c_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct i2c_adapter *i2c_adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u8 *i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u8 *i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct dib9000_pid_ctrl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DIB9000_PID_FILTER_CTRL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DIB9000_PID_FILTER 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u16 pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u8 onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct dib9000_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct i2c_device i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct dibx000_i2c_master i2c_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct i2c_adapter tuner_adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct i2c_adapter component_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u16 revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 reg_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) enum frontend_tune_state tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct dvb_frontend_parametersContext channel_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 fe_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u16 gpio_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define DIB9000_GPIO_DEFAULT_VALUES 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u16 gpio_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define DIB9000_GPIO_DEFAULT_PWM_POS 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u16 gpio_pwm_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) union { /* common for all chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 mobile_mode:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct dib9000_fe_memory_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u16 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u16 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) } fe_mm[18];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u8 memcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct mutex mbx_if_lock; /* to protect read/write operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct mutex mbx_lock; /* to protect the whole mailbox handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct mutex mem_lock; /* to protect the memory accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct mutex mem_mbx_lock; /* to protect the memory-based mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define MBX_MAX_WORDS (256 - 200 - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define DIB9000_MSG_CACHE_SIZE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u8 fw_is_running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) } risc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) } platform;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) union { /* common for all platforms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct dib9000_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } d9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u16 component_bus_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* for the I2C transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct i2c_msg msg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 i2c_write_buffer[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 i2c_read_buffer[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct mutex demod_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 get_frontend_internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct dib9000_pid_ctrl pid_ctrl[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 0, 0, 0, 0, 0, 0, 0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) enum dib9000_power_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) DIB9000_POWER_ALL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) DIB9000_POWER_NO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) DIB9000_POWER_INTERF_ANALOG_AGC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) DIB9000_POWER_INTERFACE_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) enum dib9000_out_messages {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) OUT_MSG_HBM_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) OUT_MSG_HOST_BUF_FAIL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) OUT_MSG_REQ_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) OUT_MSG_BRIDGE_I2C_W,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) OUT_MSG_BRIDGE_I2C_R,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) OUT_MSG_BRIDGE_APB_W,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) OUT_MSG_BRIDGE_APB_R,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) OUT_MSG_SCAN_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) OUT_MSG_MONIT_DEMOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) OUT_MSG_CONF_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) OUT_MSG_DEBUG_HELP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) OUT_MSG_SUBBAND_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) OUT_MSG_ENABLE_TIME_SLICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) OUT_MSG_FE_FW_DL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) OUT_MSG_FE_CHANNEL_SEARCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) OUT_MSG_FE_CHANNEL_TUNE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) OUT_MSG_FE_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) OUT_MSG_FE_SYNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) OUT_MSG_CTL_MONIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) OUT_MSG_CONF_SVC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) OUT_MSG_SET_HBM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) OUT_MSG_INIT_DEMOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) OUT_MSG_ENABLE_DIVERSITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) OUT_MSG_SET_OUTPUT_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) OUT_MSG_SET_PRIORITARY_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) OUT_MSG_ACK_FRG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) OUT_MSG_INIT_PMU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) enum dib9000_in_messages {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) IN_MSG_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) IN_MSG_FRAME_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) IN_MSG_CTL_MONIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) IN_MSG_ACK_FREE_ITEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) IN_MSG_DEBUG_BUF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) IN_MSG_MPE_MONITOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) IN_MSG_RAWTS_MONITOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) IN_MSG_END_BRIDGE_I2C_RW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) IN_MSG_END_BRIDGE_APB_RW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) IN_MSG_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) IN_MSG_END_OF_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) IN_MSG_MONIT_DEMOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) IN_MSG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) IN_MSG_FE_FW_DL_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) IN_MSG_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) IN_MSG_ACK_CHANGE_SVC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) IN_MSG_HBM_PROF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* memory_access requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define FE_MM_W_CHANNEL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define FE_MM_W_FE_INFO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define FE_MM_RW_SYNC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define FE_SYNC_CHANNEL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define FE_SYNC_W_GENERIC_MONIT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define FE_SYNC_COMPONENT_ACCESS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define FE_MM_R_CHANNEL_SEARCH_STATE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define FE_MM_R_CHANNEL_UNION_CONTEXT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define FE_MM_R_FE_INFO 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define FE_MM_R_FE_MONITOR 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define FE_MM_W_CHANNEL_HEAD 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define FE_MM_W_CHANNEL_UNION 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define FE_MM_W_CHANNEL_CONTEXT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define FE_MM_R_CHANNEL_UNION 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define FE_MM_R_CHANNEL_CONTEXT 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define FE_MM_R_CHANNEL_TUNE_STATE 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define FE_MM_R_GENERIC_MONITORING_SIZE 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define FE_MM_W_GENERIC_MONITORING 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define FE_MM_R_GENERIC_MONITORING 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define FE_MM_W_COMPONENT_ACCESS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static u16 to_fw_output_mode(u16 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case OUTMODE_HIGH_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case OUTMODE_MPEG2_PAR_GATED_CLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case OUTMODE_MPEG2_PAR_CONT_CLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case OUTMODE_MPEG2_SERIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case OUTMODE_DIVERSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) case OUTMODE_MPEG2_FIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case OUTMODE_ANALOG_ADC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 *b, u32 len, u16 attribute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u32 chunk_size = 126;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u32 l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (state->platform.risc.fw_is_running && (reg < 1024))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) state->msg[0].addr = state->i2c.i2c_addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) state->msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) state->msg[0].buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) state->msg[0].len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) state->msg[1].addr = state->i2c.i2c_addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) state->msg[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) state->msg[1].buf = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) state->msg[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) state->i2c_write_buffer[0] = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) state->i2c_write_buffer[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) state->i2c_write_buffer[0] |= (1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) state->i2c_write_buffer[0] |= (1 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) l = len < chunk_size ? len : chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) state->msg[1].len = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) state->msg[1].buf = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dprintk("i2c read error on %d\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) b += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) len -= l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) reg += l / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) } while ((ret == 0) && len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct i2c_msg msg[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {.addr = i2c->i2c_addr >> 1, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .buf = i2c->i2c_write_buffer, .len = 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .buf = i2c->i2c_read_buffer, .len = 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) i2c->i2c_write_buffer[0] = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) i2c->i2c_write_buffer[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dprintk("read register %x error\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) attribute) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *buf, u32 len, u16 attribute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u32 chunk_size = 126;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u32 l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (state->platform.risc.fw_is_running && (reg < 1024)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (dib9000_risc_apb_access_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) memset(&state->msg[0], 0, sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) state->msg[0].addr = state->i2c.i2c_addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) state->msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) state->msg[0].buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) state->msg[0].len = len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) state->i2c_write_buffer[1] = (reg) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) state->i2c_write_buffer[0] |= (1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) state->i2c_write_buffer[0] |= (1 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) l = len < chunk_size ? len : chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) state->msg[0].len = l + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) memcpy(&state->i2c_write_buffer[2], buf, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) buf += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) len -= l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) reg += l / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) } while ((ret == 0) && len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .addr = i2c->i2c_addr >> 1, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .buf = i2c->i2c_write_buffer, .len = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) i2c->i2c_write_buffer[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) i2c->i2c_write_buffer[3] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) u8 b[2] = { val >> 8, val & 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return dib9000_write16_attr(state, reg, b, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) u8 b[2] = { val >> 8, val & 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return dib9000_write16_attr(state, reg, b, 2, attribute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) #define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #define MAC_IRQ (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) #define IRQ_POL_MSK (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u8 b[14] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* b[0] = 0 << 7; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) b[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* b[2] = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* b[3] = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) b[4] = (u8) (addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) b[5] = (u8) (addr & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* b[10] = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* b[11] = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) b[12] = (u8) (addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) b[13] = (u8) (addr & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) addr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* b[6] = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* b[7] = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) b[8] = (u8) (addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) b[9] = (u8) (addr & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) dib9000_write(state, 1056, b, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (reading)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dib9000_write_word(state, 1056, (1 << 15) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) state->platform.risc.memcmd = -1; /* if it was called directly reset it - to force a future setup-call to set it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* decide whether we need to "refresh" the memory controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (state->platform.risc.memcmd == cmd && /* same command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) state->platform.risc.memcmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dib9000_risc_mem_setup(state, cmd | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dib9000_risc_mem_read_chunks(state, b, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) mutex_unlock(&state->platform.risc.mem_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dib9000_risc_mem_setup(state, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dib9000_risc_mem_write_chunks(state, b, m->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) mutex_unlock(&state->platform.risc.mem_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u16 offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (risc_id == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) offs = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* config crtl reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dib9000_write_word(state, 1024 + offs, 0x000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dib9000_write_word(state, 1025 + offs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dib9000_write_word(state, 1031 + offs, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) dprintk("going to download %dB of microcode\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) dprintk("error while downloading microcode for RISC %c\n", 'A' + risc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) dprintk("Microcode for RISC %c loaded\n", 'A' + risc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) u16 mbox_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u16 reset_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) u16 tries = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (risc_id == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mbox_offs = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mbox_offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* Reset mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Read reset status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) } while ((reset_reg & 0x8000) && --tries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (reset_reg & 0x8000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dprintk("MBX: init ERROR, no response from RISC %c\n", 'A' + risc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) dprintk("MBX: initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #define MAX_MAILBOX_TRY 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) u8 *d, b[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u16 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (!state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) tmp = MAX_MAILBOX_TRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dprintk("MBX: RISC mbx full, retrying\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*dprintk( "MBX: size: %d\n", size); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (tmp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #ifdef DUMP_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) dprintk("--> %02x %d %*ph\n", id, len + 1, len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) /* byte-order conversion - works on big (where it is not necessary) or little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) d = (u8 *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) tmp = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *d++ = tmp >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) *d++ = tmp & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* write msg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) b[0] = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) b[1] = len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* update register nb_mes_in_RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mutex_unlock(&state->platform.risc.mbx_if_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #ifdef DUMP_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u16 *d = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) u16 tmp, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) u8 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) u8 mc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (risc_id == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mc_base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mc_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* Length and type in the first word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) size = *data & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (size <= MBX_MAX_WORDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) size--; /* Initial word already read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* to word conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) tmp = *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) *data = (tmp >> 8) | (tmp << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) #ifdef DUMP_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) dprintk("<--\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) for (i = 0; i < size + 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dprintk("%04x\n", d[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dprintk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dprintk("MBX: message is too big for message cache (%d), flushing message\n", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) size--; /* Initial word already read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) while (size--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* Update register nb_mes_in_TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) mutex_unlock(&state->platform.risc.mbx_if_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u32 ts = data[1] << 16 | data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) char *b = (char *)&data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (*b == '~') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) b++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dprintk("%s\n", b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dprintk("RISC%d: %d.%04d %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) state->fe_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ts / 10000, ts % 10000, *b ? b : "<empty>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u8 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u16 *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /* find a free slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) block = state->platform.risc.message_cache[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (*block == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) size = dib9000_mbx_read(state, block, 1, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* dprintk( "MBX: fetched %04x message to cache\n", *block); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) switch (*block >> 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case IN_MSG_DEBUG_BUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) *block = 0; /* free the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) case IN_MSG_DATA: /* FE-TRACE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dib9000_risc_data_process(state, block + 1, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) dprintk("MBX: no free cache-slot found for new message...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (risc_id == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f; /* 5 bit field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f; /* 7 bit field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ret = dib9000_mbx_fetch_to_cache(state, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* if (tmp) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* dprintk( "cleared IRQ: %x\n", tmp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) mutex_unlock(&state->platform.risc.mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) u16 *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) u16 timeout = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) *msg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* dib9000_mbx_get_from_cache(); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) block = state->platform.risc.message_cache[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if ((*block >> 8) == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) *size = (*block & 0xff) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) memcpy(msg, block + 1, (*size) * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) *block = 0; /* free the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) i = 0; /* signal that we found a message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (dib9000_mbx_process(state, attr) == -1) /* try to fetch one message - if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) } while (--timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dprintk("waiting for message %d timed out\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return i == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static int dib9000_risc_check_version(struct dib9000_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) u8 r[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) u8 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) u16 fw_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) fw_version = (r[0] << 8) | r[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dprintk("RISC: ver: %d.%02d (IC: %d)\n", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if ((fw_version >> 10) != 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) switch (fw_version & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case 14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case 17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dprintk("RISC: invalid firmware version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dprintk("RISC: valid firmware version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Reconfig pool mac ram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dib9000_write_word(state, 1225, 0x02); /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dib9000_write_word(state, 1226, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* Toggles IP crypto to Host APB interface. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dib9000_write_word(state, 1542, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* Set jump and no jump in the dma box */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dib9000_write_word(state, 1074, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dib9000_write_word(state, 1075, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /* Set MAC as APB Master. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dib9000_write_word(state, 1237, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* Reset the RISCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (codeA != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dib9000_write_word(state, 1024, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dib9000_write_word(state, 1024, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (codeB != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dib9000_write_word(state, 1040, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (codeA != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (codeB != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /* Run the RISCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (codeA != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dib9000_write_word(state, 1024, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (codeB != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) dib9000_write_word(state, 1040, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (codeA != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (dib9000_mbx_host_init(state, 0) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (codeB != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (dib9000_mbx_host_init(state, 1) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) state->platform.risc.fw_is_running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (dib9000_risc_check_version(state) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) state->platform.risc.memcmd = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static u16 dib9000_identify(struct i2c_device *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) value = dib9000_i2c_read16(client, 896);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (value != 0x01b3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) dprintk("wrong Vendor ID (0x%x)\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) value = dib9000_i2c_read16(client, 897);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dprintk("wrong Device ID (0x%x)\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* protect this driver to be used with 7000PC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) dprintk("this driver does not work with DiB7000PC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) switch (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) case 0x4000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dprintk("found DiB7000MA/PA/MB/PB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case 0x4001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) dprintk("found DiB7000HC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) case 0x4002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) dprintk("found DiB7000MC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) case 0x4003:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) dprintk("found DiB9000A\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) case 0x4004:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) dprintk("found DiB9000H\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case 0x4005:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) dprintk("found DiB9000M\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* by default everything is going to be powered off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) u8 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) offset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* now, depending on the requested mode, we power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* power up everything in the demod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) case DIB9000_POWER_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) reg_903 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) reg_904 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) reg_905 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) reg_906 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case DIB9000_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) case DIB9000_POWER_INTERF_ANALOG_AGC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) reg_906 &= ~((1 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) reg_903 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) reg_904 = 0x801f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) reg_905 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) reg_906 &= ~((1 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) reg_903 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) reg_904 = 0x8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) reg_905 = 0x010b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) reg_906 &= ~((1 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) case DIB9000_POWER_NO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /* always power down unused parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!state->platform.host.mobile_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* P_sdio_select_clk = 0 on MC and after */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (state->revision != 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) reg_906 <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dib9000_write_word(state, 903 + offset, reg_903);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) dib9000_write_word(state, 904 + offset, reg_904);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) dib9000_write_word(state, 905 + offset, reg_905);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dib9000_write_word(state, 906 + offset, reg_906);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static int dib9000_fw_reset(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) dib9000_write_word(state, 1817, 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) dib9000_write_word(state, 1227, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dib9000_write_word(state, 1227, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) switch ((state->revision = dib9000_identify(&state->i2c))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) case 0x4003:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) case 0x4004:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) case 0x4005:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) state->reg_offs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* reset the i2c-master to use the host interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) dibx000_reset_i2c_master(&state->i2c_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) dib9000_set_power_mode(state, DIB9000_POWER_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /* unforce divstr regardless whether i2c enumeration was done or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) dib9000_write_word(state, 1796, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) dib9000_write_word(state, 1805, 0x805);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* restart all parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) dib9000_write_word(state, 898, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) dib9000_write_word(state, 899, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) dib9000_write_word(state, 900, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) dib9000_write_word(state, 901, 0xff19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dib9000_write_word(state, 902, 0x003c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) dib9000_write_word(state, 898, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) dib9000_write_word(state, 899, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) dib9000_write_word(state, 900, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) dib9000_write_word(state, 901, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) dib9000_write_word(state, 902, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) u16 mb[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) u8 i, s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (address >= 1024 || !state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /* dprintk( "APB access through rd fw %d %x\n", address, attribute); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) mb[0] = (u16) address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) mb[1] = len / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) s--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) for (i = 0; i < s; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) b[i * 2] = (mb[i + 1] >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) b[i * 2 + 1] = (mb[i + 1]) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) u16 mb[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) u8 s, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (address >= 1024 || !state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (len > 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /* dprintk( "APB access through wr fw %d %x\n", address, attribute); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mb[0] = (u16)address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) for (i = 0; i + 1 < len; i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) mb[1 + i / 2] = b[i] << 8 | b[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (len & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) mb[1 + len / 2] = b[len - 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, (3 + len) / 2, attribute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) u8 index_loop = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (!state->platform.risc.fw_is_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) } while (state->i2c_read_buffer[0] && index_loop--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (index_loop > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static int dib9000_fw_init(struct dib9000_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct dibGPIOFunction *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) u16 b[40] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) u8 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) /* initialize the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) f = &state->chip.d9.cfg.gpio_function[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (f->mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) switch (f->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) case BOARD_GPIO_FUNCTION_COMPONENT_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) b[0] = (u16) f->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) b[1] = (u16) f->direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) b[2] = (u16) f->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) b[3] = (u16) f->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) b[4] = (u16) f->direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) b[5] = (u16) f->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /* subband */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) b[1 + i * 4] = 0; /* fe_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* 0 - id, 1 - no_of_frontends */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) b[0] = (0 << 8) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* 0 = i2c-address demod, 0 = tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) b[1] = (0 << 8) | (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) b[29] = state->chip.d9.cfg.if_drives;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (size > ARRAY_SIZE(b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) (int)ARRAY_SIZE(b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) for (i = 0; i < size; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) state->platform.risc.fe_mm[i / 2].size = b[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static void dib9000_fw_set_channel_head(struct dib9000_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) u8 b[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (state->fe_id % 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) freq += 101;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) b[0] = (u8) ((freq >> 0) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) b[1] = (u8) ((freq >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) b[2] = (u8) ((freq >> 16) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) b[3] = (u8) ((freq >> 24) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) b[8] = 0x80; /* do not wait for CELL ID when doing autosearch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) b[8] |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static int dib9000_fw_get_channel(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) struct dibDVBTChannel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) s8 spectrum_inversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) s8 nfft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) s8 guard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) s8 constellation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) s8 hrch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) s8 alpha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) s8 code_rate_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) s8 code_rate_lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) s8 select_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) s8 intlv_native;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct dibDVBTChannel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) switch (ch->spectrum_inversion & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) switch (ch->nfft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) switch (ch->guard) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) switch (ch->constellation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) state->fe[0]->dtv_property_cache.modulation = QAM_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) state->fe[0]->dtv_property_cache.modulation = QAM_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) state->fe[0]->dtv_property_cache.modulation = QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) switch (ch->hrch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) switch (ch->code_rate_hp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) switch (ch->code_rate_lp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static int dib9000_fw_set_channel_union(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct dibDVBTChannel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) s8 spectrum_inversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) s8 nfft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) s8 guard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) s8 constellation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) s8 hrch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) s8 alpha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) s8 code_rate_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) s8 code_rate_lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) s8 select_hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) s8 intlv_native;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct dibDVBTChannel ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) switch (state->fe[0]->dtv_property_cache.inversion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) case INVERSION_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) ch.spectrum_inversion = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) case INVERSION_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ch.spectrum_inversion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) case INVERSION_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ch.spectrum_inversion = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) switch (state->fe[0]->dtv_property_cache.transmission_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) case TRANSMISSION_MODE_2K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) ch.nfft = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) case TRANSMISSION_MODE_4K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) ch.nfft = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) case TRANSMISSION_MODE_8K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) ch.nfft = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) case TRANSMISSION_MODE_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ch.nfft = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) switch (state->fe[0]->dtv_property_cache.guard_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) case GUARD_INTERVAL_1_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ch.guard = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) case GUARD_INTERVAL_1_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) ch.guard = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) case GUARD_INTERVAL_1_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) ch.guard = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) case GUARD_INTERVAL_1_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) ch.guard = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case GUARD_INTERVAL_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) ch.guard = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) switch (state->fe[0]->dtv_property_cache.modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) ch.constellation = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) case QAM_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ch.constellation = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) case QPSK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) ch.constellation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) case QAM_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ch.constellation = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) switch (state->fe[0]->dtv_property_cache.hierarchy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) case HIERARCHY_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) ch.hrch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) case HIERARCHY_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) case HIERARCHY_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) case HIERARCHY_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) ch.hrch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) case HIERARCHY_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) ch.hrch = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) ch.alpha = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) case FEC_1_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) ch.code_rate_hp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case FEC_2_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) ch.code_rate_hp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case FEC_3_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ch.code_rate_hp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) case FEC_5_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) ch.code_rate_hp = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) case FEC_7_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) ch.code_rate_hp = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) case FEC_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) ch.code_rate_hp = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) case FEC_1_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) ch.code_rate_lp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) case FEC_2_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) ch.code_rate_lp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) case FEC_3_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) ch.code_rate_lp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) case FEC_5_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ch.code_rate_lp = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) case FEC_7_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) ch.code_rate_lp = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) case FEC_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) ch.code_rate_lp = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ch.select_hp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) ch.intlv_native = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int dib9000_fw_tune(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) s8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) switch (state->tune_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) case CT_DEMOD_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) dib9000_fw_set_channel_head(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /* write the channel context - a channel is initialized to 0, so it is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (search)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) dib9000_fw_set_channel_union(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) state->tune_state = CT_DEMOD_STEP_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) case CT_DEMOD_STEP_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (search)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) i = (s8)state->i2c_read_buffer[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) switch (i) { /* something happened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) case -2: /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (search)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) state->status = FE_STATUS_DEMOD_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) state->tune_state = CT_DEMOD_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) state->status = FE_STATUS_LOCKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) state->status = FE_STATUS_TUNE_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) state->tune_state = CT_DEMOD_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) ret = FE_CALLBACK_TIME_NEVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) u16 mode = (u16) onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) u16 outreg, smo_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dprintk("setting output mode for demod %p to %d\n", fe, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) case OUTMODE_MPEG2_PAR_GATED_CLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) outreg = (1 << 10); /* 0x0400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) case OUTMODE_MPEG2_PAR_CONT_CLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) outreg = (1 << 10) | (1 << 6); /* 0x0440 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) case OUTMODE_MPEG2_SERIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) case OUTMODE_DIVERSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) outreg = (1 << 10) | (4 << 6); /* 0x0500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) case OUTMODE_MPEG2_FIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) outreg = (1 << 10) | (5 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) case OUTMODE_HIGH_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) outreg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->fe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) dib9000_write_word(state, 1795, outreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) case OUTMODE_MPEG2_PAR_GATED_CLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) case OUTMODE_MPEG2_PAR_CONT_CLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) case OUTMODE_MPEG2_SERIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case OUTMODE_MPEG2_FIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) smo_mode |= (1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) dib9000_write_word(state, 295, smo_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) outreg = to_fw_output_mode(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) u16 i, len, t, index_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) for (index_msg = 0; index_msg < num; index_msg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (msg[index_msg].flags & I2C_M_RD) { /* read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) len = msg[index_msg].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (len > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) len = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (dib9000_read_word(state, 790) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) dprintk("TunerITF: read busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) dib9000_write_word(state, 787, (len / 2) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) dib9000_write_word(state, 786, 1); /* start read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) i = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) while (dib9000_read_word(state, 790) != (len / 2) && i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) dprintk("TunerITF: read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) for (i = 0; i < len; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) t = dib9000_read_word(state, 785);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) msg[index_msg].buf[i] = (t >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) msg[index_msg].buf[i + 1] = (t) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (dib9000_read_word(state, 790) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) dprintk("TunerITF: read more data than expected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) i = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) while (dib9000_read_word(state, 789) && i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) dprintk("TunerITF: write busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) len = msg[index_msg].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (len > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) len = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) for (i = 0; i < len; i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) dib9000_write_word(state, 787, (len / 2) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) dib9000_write_word(state, 786, 0); /* start write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) i = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) while (dib9000_read_word(state, 791) > 0 && i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) dprintk("TunerITF: write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) state->component_bus_speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) u8 type = 0; /* I2C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) u16 scl = state->component_bus_speed; /* SCL frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) u8 p[13] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) p[0] = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) p[1] = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) p[2] = msg[0].addr << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) p[3] = (u8) scl & 0xff; /* scl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) p[4] = (u8) (scl >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) p[7] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) p[8] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) p[9] = (u8) (msg[0].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) p[10] = (u8) (msg[0].len >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) p[11] = (u8) (msg[1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) p[12] = (u8) (msg[1].len >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) p[11] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) p[12] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) { /* write-part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /* do the transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) /* read back any possible result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if ((num > 1) && (msg[1].flags & I2C_M_RD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) return I2C_FUNC_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) static const struct i2c_algorithm dib9000_tuner_algo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) .master_xfer = dib9000_tuner_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) .functionality = dib9000_i2c_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) static const struct i2c_algorithm dib9000_component_bus_algo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) .master_xfer = dib9000_fw_component_bus_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) .functionality = dib9000_i2c_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct dib9000_state *st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) return &st->tuner_adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) EXPORT_SYMBOL(dib9000_get_tuner_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) struct dib9000_state *st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) return &st->component_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) EXPORT_SYMBOL(dib9000_get_component_bus_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) struct dib9000_state *st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) EXPORT_SYMBOL(dib9000_get_i2c_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct dib9000_state *st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) st->i2c.i2c_adap = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) EXPORT_SYMBOL(dib9000_set_i2c_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) st->gpio_dir = dib9000_read_word(st, 773);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) st->gpio_dir &= ~(1 << num); /* reset the direction bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) dib9000_write_word(st, 773, st->gpio_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) st->gpio_val = dib9000_read_word(st, 774);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) st->gpio_val &= ~(1 << num); /* reset the direction bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) st->gpio_val |= (val & 0x01) << num; /* set the new value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) dib9000_write_word(st, 774, st->gpio_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) dprintk("gpio dir: %04x: gpio val: %04x\n", st->gpio_dir, st->gpio_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) return dib9000_cfg_gpio(state, num, dir, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) EXPORT_SYMBOL(dib9000_set_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) /* postpone the pid filtering cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) dprintk("pid filter cmd postpone\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) state->pid_ctrl_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) val = dib9000_read_word(state, 294 + 1) & 0xffef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) val |= (onoff & 0x1) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) dprintk("PID filter enabled %d\n", onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) ret = dib9000_write_word(state, 294 + 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (state->pid_ctrl_index != -2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /* postpone the pid filtering cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) dprintk("pid filter postpone\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (state->pid_ctrl_index < 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) state->pid_ctrl_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) state->pid_ctrl[state->pid_ctrl_index].id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) state->pid_ctrl[state->pid_ctrl_index].pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) dprintk("can not add any more pid ctrl cmd\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) dprintk("Index %x, PID %d, OnOff %d\n", id, pid, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) ret = dib9000_write_word(state, 300 + 1 + id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) onoff ? (1 << 13) | pid : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) EXPORT_SYMBOL(dib9000_fw_pid_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return dib9000_fw_init(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static void dib9000_release(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct dib9000_state *st = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) u8 index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) dvb_frontend_detach(st->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) dibx000_exit_i2c_master(&st->i2c_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) i2c_del_adapter(&st->tuner_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) i2c_del_adapter(&st->component_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) kfree(st->fe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) static int dib9000_wakeup(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) static int dib9000_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) u8 index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) tune->min_delay_ms = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) static int dib9000_get_frontend(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) u8 index_frontend, sub_index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) enum fe_status stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if (state->get_frontend_internal == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (stat & FE_HAS_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) dprintk("TPS lock on the slave%i\n", index_frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /* synchronize the cache with the other frontends */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) sub_index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (sub_index_frontend != index_frontend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) state->fe[sub_index_frontend]->dtv_property_cache.modulation =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) state->fe[index_frontend]->dtv_property_cache.modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) state->fe[sub_index_frontend]->dtv_property_cache.inversion =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) state->fe[index_frontend]->dtv_property_cache.inversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) state->fe[index_frontend]->dtv_property_cache.transmission_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) state->fe[index_frontend]->dtv_property_cache.guard_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) state->fe[index_frontend]->dtv_property_cache.hierarchy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) state->fe[index_frontend]->dtv_property_cache.rolloff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) goto return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) /* get the channel from master chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) ret = dib9000_fw_get_channel(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) goto return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) /* synchronize the cache with the other frontends */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) state->fe[index_frontend]->dtv_property_cache.inversion = c->inversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) state->fe[index_frontend]->dtv_property_cache.transmission_mode = c->transmission_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) state->fe[index_frontend]->dtv_property_cache.guard_interval = c->guard_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) state->fe[index_frontend]->dtv_property_cache.modulation = c->modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) state->fe[index_frontend]->dtv_property_cache.hierarchy = c->hierarchy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) state->fe[index_frontend]->dtv_property_cache.code_rate_HP = c->code_rate_HP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) state->fe[index_frontend]->dtv_property_cache.code_rate_LP = c->code_rate_LP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) state->fe[index_frontend]->dtv_property_cache.rolloff = c->rolloff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) return_value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (state->get_frontend_internal == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) state->tune_state = tune_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (tune_state == CT_DEMOD_START)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) state->status = FE_STATUS_TUNE_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) static u32 dib9000_get_status(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) return state->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) static int dib9000_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) int sleep_time, sleep_time_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) u32 frontend_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) struct dvb_frontend_parametersContext channel_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) /* check that the correct parameters are set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (state->fe[0]->dtv_property_cache.frequency == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) dprintk("dib9000: must specify frequency\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) dprintk("dib9000: must specify bandwidth\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) fe->dtv_property_cache.delivery_system = SYS_DVBT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) /* set the master status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) state->fe[0]->dtv_property_cache.modulation == QAM_AUTO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) state->fe[0]->dtv_property_cache.code_rate_HP == FEC_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) /* no channel specified, autosearch the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) /* set mode and status for the different frontends */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) /* synchronization of the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) /* actual tune */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) index_frontend_success = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) sleep_time = dib9000_fw_tune(state->fe[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (sleep_time == FE_CALLBACK_TIME_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) sleep_time = sleep_time_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) sleep_time = sleep_time_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) if (sleep_time != FE_CALLBACK_TIME_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) msleep(sleep_time / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) nbr_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) exit_condition = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) index_frontend_success = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) frontend_status = -dib9000_get_status(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) if (frontend_status > -FE_STATUS_TUNE_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) exit_condition = 2; /* tune success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) index_frontend_success = index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) if (frontend_status == -FE_STATUS_TUNE_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) nbr_pending++; /* some frontends are still tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) if ((exit_condition != 2) && (nbr_pending == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) exit_condition = 1; /* if all tune are done and no success, exit: tune failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) } while (exit_condition == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) /* check the tune result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if (exit_condition == 1) { /* tune failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) dprintk("tune failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) /* tune failed; put all the pid filtering cmd to junk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) state->pid_ctrl_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) dprintk("tune success on frontend%i\n", index_frontend_success);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) /* synchronize all the channel cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) state->get_frontend_internal = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) dib9000_get_frontend(state->fe[0], &state->fe[0]->dtv_property_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) state->get_frontend_internal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) /* retune the other frontends with the found channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) /* only retune the frontends which was not tuned success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (index_frontend != index_frontend_success) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) sleep_time = FE_CALLBACK_TIME_NEVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) if (index_frontend != index_frontend_success) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) if (sleep_time == FE_CALLBACK_TIME_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) sleep_time = sleep_time_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) sleep_time = sleep_time_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (sleep_time != FE_CALLBACK_TIME_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) msleep(sleep_time / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) nbr_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) if (index_frontend != index_frontend_success) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) frontend_status = -dib9000_get_status(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) nbr_pending++; /* some frontends are still tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) } while (nbr_pending != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) /* set the output mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /* turn off the diversity for the last frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (state->pid_ctrl_index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) u8 index_pid_filter_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) u8 pid_ctrl_index = state->pid_ctrl_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) state->pid_ctrl_index = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) for (index_pid_filter_cmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) index_pid_filter_cmd <= pid_ctrl_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) index_pid_filter_cmd++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) dib9000_fw_pid_filter_ctrl(state->fe[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) state->pid_ctrl[index_pid_filter_cmd].onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) dib9000_fw_pid_filter(state->fe[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) state->pid_ctrl[index_pid_filter_cmd].id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) state->pid_ctrl[index_pid_filter_cmd].pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) state->pid_ctrl[index_pid_filter_cmd].onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) /* do not postpone any more the pid filtering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) state->pid_ctrl_index = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) static u16 dib9000_read_lock(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) return dib9000_read_word(state, 535);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) static int dib9000_read_status(struct dvb_frontend *fe, enum fe_status *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) u8 index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) u16 lock = 0, lock_slave = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) lock = dib9000_read_word(state, 535);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) *stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if ((lock & 0x8000) || (lock_slave & 0x8000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) *stat |= FE_HAS_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) if ((lock & 0x3000) || (lock_slave & 0x3000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) *stat |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if ((lock & 0x0100) || (lock_slave & 0x0100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) *stat |= FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) *stat |= FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if ((lock & 0x0008) || (lock_slave & 0x0008))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) *stat |= FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) u16 *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) ret = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) state->i2c_read_buffer, 16 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) c = (u16 *)state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) *ber = c[10] << 16 | c[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) u8 index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) u16 *c = (u16 *)state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) *strength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (val > 65535 - *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) *strength = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) *strength += val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) ret = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) val = 65535 - c[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) if (val > 65535 - *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) *strength = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) *strength += val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static u32 dib9000_get_snr(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) u16 *c = (u16 *)state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) u32 n, s, exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) val = c[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) n = (val >> 4) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) exp = ((val & 0xf) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) val = c[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) exp += ((val >> 14) & 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if ((exp & 0x20) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) exp -= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) n <<= exp + 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) s = (val >> 6) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) exp = (val & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if ((exp & 0x20) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) exp -= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) s <<= exp + 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) if (n > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) u32 t = (s / n) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) return t + ((s << 16) - n * t) / n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) return 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) u8 index_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) u32 snr_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) snr_master = dib9000_get_snr(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) snr_master += dib9000_get_snr(state->fe[index_frontend]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) if ((snr_master >> 16) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) snr_master = 10 * intlog10(snr_master >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) *snr = snr_master / ((1 << 24) / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) *snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) u16 *c = (u16 *)state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (mutex_lock_interruptible(&state->demod_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) dprintk("could not get the lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) ret = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) mutex_unlock(&state->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) *unc = c[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) mutex_unlock(&state->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) int k = 0, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) u8 new_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) struct i2c_device client = {.i2c_adap = i2c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) client.i2c_write_buffer = kzalloc(4, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) if (!client.i2c_write_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) dprintk("%s: not enough memory\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) client.i2c_read_buffer = kzalloc(4, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) if (!client.i2c_read_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) dprintk("%s: not enough memory\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) goto error_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) client.i2c_addr = default_addr + 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) dib9000_i2c_write16(&client, 1796, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) for (k = no_of_demods - 1; k >= 0; k--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) /* designated i2c address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) new_addr = first_addr + (k << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) client.i2c_addr = default_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) dib9000_i2c_write16(&client, 1817, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) dib9000_i2c_write16(&client, 1796, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) dib9000_i2c_write16(&client, 1227, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) dib9000_i2c_write16(&client, 1227, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) client.i2c_addr = new_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) dib9000_i2c_write16(&client, 1817, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) dib9000_i2c_write16(&client, 1796, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) dib9000_i2c_write16(&client, 1227, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) dib9000_i2c_write16(&client, 1227, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) if (dib9000_identify(&client) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) client.i2c_addr = default_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) if (dib9000_identify(&client) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) dprintk("DiB9000 #%d: not identified\n", k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) for (k = 0; k < no_of_demods; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) new_addr = first_addr | (k << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) client.i2c_addr = new_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) dib9000_i2c_write16(&client, 1794, (new_addr << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) dib9000_i2c_write16(&client, 1795, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) kfree(client.i2c_read_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) error_memory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) kfree(client.i2c_write_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) EXPORT_SYMBOL(dib9000_i2c_enumeration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) u8 index_frontend = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) index_frontend++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) dprintk("set slave fe %p to index %i\n", fe_slave, index_frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) state->fe[index_frontend] = fe_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) dprintk("too many slave frontend\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) EXPORT_SYMBOL(dib9000_set_slave_frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) struct dib9000_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) return state->fe[slave_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) EXPORT_SYMBOL(dib9000_get_slave_frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) static const struct dvb_frontend_ops dib9000_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) struct dvb_frontend *fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) struct dib9000_state *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) if (st == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) if (fe == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) st->i2c.i2c_adap = i2c_adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) st->i2c.i2c_addr = i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) st->i2c.i2c_write_buffer = st->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) st->i2c.i2c_read_buffer = st->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) mutex_init(&st->platform.risc.mbx_if_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) mutex_init(&st->platform.risc.mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) mutex_init(&st->platform.risc.mem_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) mutex_init(&st->platform.risc.mem_mbx_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) mutex_init(&st->demod_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) st->get_frontend_internal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) st->pid_ctrl_index = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) st->fe[0] = fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) fe->demodulator_priv = st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) /* Ensure the output mode remains at the previous default if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) * not specifically set by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (dib9000_identify(&st->i2c) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) st->tuner_adap.dev.parent = i2c_adap->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) strscpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) sizeof(st->tuner_adap.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) st->tuner_adap.algo = &dib9000_tuner_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) st->tuner_adap.algo_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) i2c_set_adapdata(&st->tuner_adap, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (i2c_add_adapter(&st->tuner_adap) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) st->component_bus.dev.parent = i2c_adap->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) strscpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) sizeof(st->component_bus.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) st->component_bus.algo = &dib9000_component_bus_algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) st->component_bus.algo_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) st->component_bus_speed = 340;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) i2c_set_adapdata(&st->component_bus, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) if (i2c_add_adapter(&st->component_bus) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) goto component_bus_add_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) dib9000_fw_reset(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) return fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) component_bus_add_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) i2c_del_adapter(&st->tuner_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) EXPORT_SYMBOL(dib9000_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) static const struct dvb_frontend_ops dib9000_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) .delsys = { SYS_DVBT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) .name = "DiBcom 9000",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) .frequency_min_hz = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) .frequency_max_hz = 867250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) .frequency_stepsize_hz = 62500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) .caps = FE_CAN_INVERSION_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) .release = dib9000_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) .init = dib9000_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) .sleep = dib9000_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) .set_frontend = dib9000_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) .get_tune_settings = dib9000_fe_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) .get_frontend = dib9000_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) .read_status = dib9000_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) .read_ber = dib9000_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) .read_signal_strength = dib9000_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) .read_snr = dib9000_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) .read_ucblocks = dib9000_read_unc_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) MODULE_LICENSE("GPL");