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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "si21xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define	REVISION_REG			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define	SYSTEM_MODE_REG			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define	TS_CTRL_REG_1			0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define	TS_CTRL_REG_2			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define	PIN_CTRL_REG_1			0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define	PIN_CTRL_REG_2			0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define	LOCK_STATUS_REG_1		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define	LOCK_STATUS_REG_2		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define	ACQ_STATUS_REG			0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define	ACQ_CTRL_REG_1			0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define	ACQ_CTRL_REG_2			0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define	PLL_DIVISOR_REG			0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define	COARSE_TUNE_REG			0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define	FINE_TUNE_REG_L			0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define	FINE_TUNE_REG_H			0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define	ANALOG_AGC_POWER_LEVEL_REG	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define	CFO_ESTIMATOR_CTRL_REG_1	0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define	CFO_ESTIMATOR_CTRL_REG_2	0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define	CFO_ESTIMATOR_CTRL_REG_3	0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define	SYM_RATE_ESTIMATE_REG_L		0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define	SYM_RATE_ESTIMATE_REG_M		0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define	SYM_RATE_ESTIMATE_REG_H		0x33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define	CFO_ESTIMATOR_OFFSET_REG_L	0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define	CFO_ESTIMATOR_OFFSET_REG_H	0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define	CFO_ERROR_REG_L			0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define	CFO_ERROR_REG_H			0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define	SYM_RATE_ESTIMATOR_CTRL_REG	0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define	SYM_RATE_REG_L			0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define	SYM_RATE_REG_M			0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define	SYM_RATE_REG_H			0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define	SYM_RATE_ESTIMATOR_MAXIMUM_REG	0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define	SYM_RATE_ESTIMATOR_MINIMUM_REG	0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define	C_N_ESTIMATOR_CTRL_REG		0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define	C_N_ESTIMATOR_THRSHLD_REG	0x7d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define	C_N_ESTIMATOR_LEVEL_REG_L	0x7e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define	C_N_ESTIMATOR_LEVEL_REG_H	0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define	BLIND_SCAN_CTRL_REG		0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define	LSA_CTRL_REG_1			0x8D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define	SPCTRM_TILT_CORR_THRSHLD_REG	0x8f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define	ONE_DB_BNDWDTH_THRSHLD_REG	0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define	TWO_DB_BNDWDTH_THRSHLD_REG	0x91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define	THREE_DB_BNDWDTH_THRSHLD_REG	0x92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define	INBAND_POWER_THRSHLD_REG	0x93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define	REF_NOISE_LVL_MRGN_THRSHLD_REG	0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define	VIT_SRCH_CTRL_REG_1		0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define	VIT_SRCH_CTRL_REG_2		0xa1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define	VIT_SRCH_CTRL_REG_3		0xa2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define	VIT_SRCH_STATUS_REG		0xa3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define	VITERBI_BER_COUNT_REG_L		0xab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define	REED_SOLOMON_CTRL_REG		0xb0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define	REED_SOLOMON_ERROR_COUNT_REG_L	0xb1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define	PRBS_CTRL_REG			0xb5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define	LNB_CTRL_REG_1			0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define	LNB_CTRL_REG_2			0xc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define	LNB_CTRL_REG_3			0xc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define	LNB_CTRL_REG_4			0xc3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define	LNB_CTRL_STATUS_REG		0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define	LNB_FIFO_REGS_0			0xc5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define	LNB_FIFO_REGS_1			0xc6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define	LNB_FIFO_REGS_2			0xc7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define	LNB_FIFO_REGS_3			0xc8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define	LNB_FIFO_REGS_4			0xc9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define	LNB_FIFO_REGS_5			0xca
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define	LNB_SUPPLY_CTRL_REG_1		0xcb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define	LNB_SUPPLY_CTRL_REG_2		0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define	LNB_SUPPLY_CTRL_REG_3		0xcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define	LNB_SUPPLY_CTRL_REG_4		0xce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define	LNB_SUPPLY_STATUS_REG		0xcf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define FAIL	-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define PASS	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define ALLOWABLE_FS_COUNT	10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define STATUS_BER		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define STATUS_UCBLOCKS		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define dprintk(args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		if (debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			printk(KERN_DEBUG "si21xx: " args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	ACTIVE_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	ACTIVE_LOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	BYTE_WIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	BIT_WIDE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	CLK_GAPPED_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	CLK_CONTINUOUS_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	RISING_EDGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	FALLING_EDGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	MSB_FIRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	LSB_FIRST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	SERIAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	PARALLEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct si21xx_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	const struct si21xx_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct dvb_frontend frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	u8 initialised:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	int errmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int fs;			/*Sampling rate of the ADC in MHz*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*	register default initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static u8 serit_sp1511lhb_inittab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	0x01, 0x28,	/* set i2c_inc_disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	0x20, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	0x27, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	0xe0, 0x45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	0xe1, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	0xfe, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	0x01, 0x28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	0x89, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	0x04, 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	0x05, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	0x06, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	0x20, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	0x24, 0x88,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	0x29, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	0x2a, 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	0x2c, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	0x2d, 0x19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	0x2e, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	0x2f, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	0x30, 0x19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	0x34, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	0x35, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	0x45, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	0x46, 0x45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	0x47, 0xd0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	0x48, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	0x49, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	0x4a, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	0x4c, 0xfd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	0x4f, 0x2e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	0x50, 0x2e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	0x51, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	0x52, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	0x56, 0x92,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	0x59, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	0x5a, 0x2d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	0x5b, 0x33,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	0x5c, 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	0x5f, 0x76,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	0x62, 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	0x63, 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	0x64, 0xf3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	0x65, 0xf3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	0x79, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	0x6a, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	0x6b, 0x0a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	0x6c, 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	0x6d, 0x27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	0x71, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	0x75, 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	0x78, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	0x79, 0xb5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	0x7c, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	0x7d, 0x1a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	0x87, 0x55,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	0x88, 0x72,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	0x8f, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	0x90, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	0x94, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	0xa0, 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	0xa1, 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	0xa4, 0xcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	0xa5, 0x66,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	0xa6, 0x66,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	0xa7, 0x7b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	0xa8, 0x7b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	0xa9, 0x7b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	0xaa, 0x9a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	0xed, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	0xad, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	0xae, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	0xcc, 0xab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	0x01, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	0xff, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*	low level read/writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int si21_writeregs(struct si21xx_state *state, u8 reg1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 							u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	u8 buf[60];/* = { reg1, data };*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				.addr = state->config->demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 				.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				.buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 				.len = len + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (len > sizeof(buf) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	msg.buf[0] =  reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	memcpy(msg.buf + 1, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	ret = i2c_transfer(state->i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			__func__, reg1, data[0], ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	return (ret != 1) ? -EREMOTEIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	u8 buf[] = { reg, data };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				.addr = state->config->demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				.buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 				.len = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	ret = i2c_transfer(state->i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			__func__, reg, data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return (ret != 1) ? -EREMOTEIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (len != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return si21_writereg(state, buf[0], buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static u8 si21_readreg(struct si21xx_state *state, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	u8 b0[] = { reg };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	u8 b1[] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			.addr = state->config->demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			.buf = b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			.len = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			.addr = state->config->demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			.flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			.buf = b1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			.len = 1
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	ret = i2c_transfer(state->i2c, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (ret != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			__func__, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	return b1[0];
^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 int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			.addr = state->config->demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			.buf = &reg1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			.len = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			.addr = state->config->demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			.flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			.buf = b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			.len = len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	ret = i2c_transfer(state->i2c, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (ret != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return ret == 2 ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	unsigned long start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		if (jiffies - start > timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			dprintk("%s: timeout!!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	u32 sym_rate, data_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	u8 sym_rate_bytes[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	dprintk("%s : srate = %i\n", __func__ , srate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if ((srate < 1000000) || (srate > 45000000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	data_rate = srate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	sym_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	for (i = 0; i < 4; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		sym_rate /= 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 								state->fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		data_rate /= 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	for (i = 0; i < 3; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 					struct dvb_diseqc_master_cmd *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	u8 lnb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	u8 LNB_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	status = PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	LNB_CTRL_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	/*fill the FIFO*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	LNB_CTRL_1 = (lnb_status & 0x70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	LNB_CTRL_1 |= m->msg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	LNB_CTRL_1 |= 0x80;	/* begin LNB signaling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 				    enum fe_sec_mini_cmd burst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	if (si21xx_wait_diseqc_idle(state, 100) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	val = (0x80 | si21_readreg(state, 0xc1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	if (si21_writereg(state, LNB_CTRL_REG_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	if (si21xx_wait_diseqc_idle(state, 100) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	if (si21_writereg(state, LNB_CTRL_REG_1, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /*	30.06.2008 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	switch (tone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	case SEC_TONE_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	case SEC_TONE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	dprintk("%s: %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	switch (volt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	case SEC_VOLTAGE_18:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	case SEC_VOLTAGE_13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int si21xx_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	u8 reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	u8 reg2[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	for (i = 0; ; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		reg1 = serit_sp1511lhb_inittab[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		val = serit_sp1511lhb_inittab[i+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		if (reg1 == 0xff && val == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		si21_writeregs(state, reg1, &val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	/*DVB QPSK SYSTEM MODE REG*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	reg1 = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	/*transport stream config*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	mode = PARALLEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	sdata_form = LSB_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	clk_edge = FALLING_EDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	clk_mode = CLK_GAPPED_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	strt_len = BYTE_WIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	sync_pol = ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	val_pol = ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	err_pol = ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	sclk_rate = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	parity = 0x00 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	data_delay = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	clk_delay = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	pclk_smooth = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	reg2[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		PARALLEL + (LSB_FIRST << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		+ (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		+ (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		+ (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	reg2[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	/*	sclk_rate + (parity << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		+ (data_delay << 3) + (clk_delay << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		+ (pclk_smooth << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		dprintk(" %s : TS Set Error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	u8 regs_read[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	u8 reg_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	u8 lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	reg_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	for (i = 0; i < 7; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	*status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	if (signal > 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		*status |= FE_HAS_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	if (lock & 0x2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		*status |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (lock & 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		*status |= FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (lock & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		*status |= FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	if ((lock & 0x7b) == 0x7b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		*status |= FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	/*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 						(u8*)agclevel, 0x01);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	u16 signal = (3 * si21_readreg(state, 0x27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 					si21_readreg(state, 0x28));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		si21_readreg(state, 0x27),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		si21_readreg(state, 0x28), (int) signal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	signal  <<= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	*strength = signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	if (state->errmode != STATUS_BER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	*ber = (si21_readreg(state, 0x1d) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 				si21_readreg(state, 0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 					si21_readreg(state, 0x25));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	xsnr = 3 * (xsnr - 0xa100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	*snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	if (state->errmode != STATUS_UCBLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		*ucblocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		*ucblocks = (si21_readreg(state, 0x1d) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 					si21_readreg(state, 0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /*	initiates a channel acquisition sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	using the specified symbol rate and code rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 			     enum fe_code_rate crate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	u8 coderates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 				0x0, 0x01, 0x02, 0x04, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 				0x8, 0x10, 0x20, 0x00, 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	u8 coderate_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	u8 start_acq = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	u8 reg, regs[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	status = PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	coderate_ptr = coderates[crate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	si21xx_set_symbolrate(fe, symbrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	/* write code rates to use in the Viterbi search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	status |= si21_writeregs(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 				VIT_SRCH_CTRL_REG_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 				&coderate_ptr, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	/* clear acq_start bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	reg &= ~start_acq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	/* use new Carrier Frequency Offset Estimator (QuickLock) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	regs[0] = 0xCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	regs[1] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	regs[2] = 0xCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	status |= si21_writeregs(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 				TWO_DB_BNDWDTH_THRSHLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 				&regs[0], 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	reg = 0x56;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	status |= si21_writeregs(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 				LSA_CTRL_REG_1, &reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	reg = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	status |= si21_writeregs(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 				BLIND_SCAN_CTRL_REG, &reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	/* start automatic acq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	status |= si21_writeregs(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 				ACQ_CTRL_REG_2, &start_acq, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int si21xx_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	/* freq		Channel carrier frequency in KHz (i.e. 1550000 KHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	 datarate	Channel symbol rate in Sps (i.e. 22500000 Sps)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	/* in MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	unsigned char coarse_tune_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	int fine_tune_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	unsigned char sample_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	/* boolean */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	bool inband_interferer_ind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	/* INTERMEDIATE VALUES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	int icoarse_tune_freq; /* MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	int ifine_tune_freq; /* MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	unsigned int band_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	unsigned int band_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	unsigned int x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	unsigned int x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	/* allowable sample rates for ADC in MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 					196, 204, 205, 206, 207
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	/* in MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	int if_limit_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	int if_limit_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	int lnb_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	int lnb_uncertanity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	int rf_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	int data_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	unsigned char regs[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	dprintk("%s : FE_SET_FRONTEND\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	if (c->delivery_system != SYS_DVBS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 			dprintk("%s: unsupported delivery system selected (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 				__func__, c->delivery_system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		inband_interferer_div2[i] = inband_interferer_div4[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	if_limit_high = -700000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	if_limit_low = -100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	/* in MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	lnb_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	lnb_uncertanity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	rf_freq = 10 * c->frequency ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	data_rate = c->symbol_rate / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	status = PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 					+ (data_rate * 135)) / 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 					+ (data_rate * 135)) / 200;
^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) 	icoarse_tune_freq = 100000 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 				(((rf_freq - lnb_lo) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 					(if_limit_low + if_limit_high) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 								/ 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 		x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 					(afs[i] * 2500) + afs[i] * 2500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 							(afs[i] * 2500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		if (((band_low < x1) && (x1 < band_high)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 					((band_low < x2) && (x2 < band_high)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 					inband_interferer_div4[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 					(afs[i] * 5000) + afs[i] * 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 					(afs[i] * 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		if (((band_low < x1) && (x1 < band_high)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 					((band_low < x2) && (x2 < band_high)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 					inband_interferer_div2[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	inband_interferer_ind = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			inband_interferer_ind = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	if (inband_interferer_ind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 			if (!inband_interferer_div2[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 				sample_rate = (u8) afs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			if ((inband_interferer_div2[i] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 			     !inband_interferer_div4[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 				sample_rate = (u8) afs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	if (sample_rate > 207 || sample_rate < 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 		sample_rate = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 					((sample_rate) * 1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	regs[0] = sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	regs[1] = coarse_tune_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	regs[2] = fine_tune_freq & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	regs[3] = fine_tune_freq >> 8 & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	state->fs = sample_rate;/*ADC MHz*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static int si21xx_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	u8 regdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	regdata |= 1 << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	state->initialised = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static void si21xx_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	struct si21xx_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static const struct dvb_frontend_ops si21xx_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	.delsys = { SYS_DVBS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	.info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 		.name			= "SL SI21XX DVB-S",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		.frequency_min_hz	=  950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		.frequency_max_hz	= 2150 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 		.frequency_stepsize_hz	=  125 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 		.symbol_rate_min	= 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 		.symbol_rate_max	= 45000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		.symbol_rate_tolerance	= 500,	/* ppm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 		FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		FE_CAN_FEC_AUTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	.release = si21xx_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	.init = si21xx_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	.sleep = si21xx_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 	.write = si21_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	.read_status = si21_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	.read_ber = si21_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 	.read_signal_strength = si21_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	.read_snr = si21_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	.read_ucblocks = si21_read_ucblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 	.diseqc_send_master_cmd = si21xx_send_diseqc_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	.diseqc_send_burst = si21xx_send_diseqc_burst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 	.set_tone = si21xx_set_tone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	.set_voltage = si21xx_set_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	.set_frontend = si21xx_set_frontend,
^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) struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 						struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 	struct si21xx_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 	int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 	/* allocate memory for the internal state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 	state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 	if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 	/* setup the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	state->config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 	state->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	state->initialised = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 	state->errmode = STATUS_BER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 	/* check if the demod is there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	id = si21_readreg(state, SYSTEM_MODE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	id = si21_readreg(state, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	/* register 0x00 contains:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 		0x34 for SI2107
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 		0x24 for SI2108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 		0x14 for SI2109
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 		0x04 for SI2110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	if (id != 0x04 && id != 0x14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	/* create dvb_frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	memcpy(&state->frontend.ops, &si21xx_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 					sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	state->frontend.demodulator_priv = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 	return &state->frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) EXPORT_SYMBOL(si21xx_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) MODULE_AUTHOR("Igor M. Liplianin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) MODULE_LICENSE("GPL");