Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");