^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 = ®1,
^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, ®1, 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, ®, 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, ®, 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) ®s[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, ®, 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, ®, 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, ®s[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, ®data, 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, ®data, 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");