^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Socionext MN88443x series demodulator driver for ISDB-S/ISDB-T.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) 2018 Socionext Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <media/dvb_math.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "mn88443x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* ISDB-S registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define ATSIDU_S 0x2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define ATSIDL_S 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define TSSET_S 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define AGCREAD_S 0x5a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define CPMON1_S 0x5e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CPMON1_S_FSYNC BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CPMON1_S_ERRMON BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CPMON1_S_SIGOFF BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CPMON1_S_W2LOCK BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CPMON1_S_W1LOCK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CPMON1_S_DW1LOCK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define TRMON_S 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define BERCNFLG_S 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define BERCNFLG_S_BERVRDY BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define BERCNFLG_S_BERVCHK BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define BERCNFLG_S_BERDRDY BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define BERCNFLG_S_BERDCHK BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CNRDXU_S 0x69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CNRDXL_S 0x6a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CNRDYU_S 0x6b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CNRDYL_S 0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define BERVRDU_S 0x71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define BERVRDL_S 0x72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DOSET1_S 0x73
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Primary ISDB-T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PLLASET1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PLLASET2 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PLLBSET1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PLLBSET2 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PLLSET 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define OUTCSET 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define OUTCSET_CHDRV_8MA 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define OUTCSET_CHDRV_4MA 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PLDWSET 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PLDWSET_NORMAL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PLDWSET_PULLDOWN 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define HIZSET1 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define HIZSET2 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Secondary ISDB-T (for MN884434 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define RCVSET 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define TSSET1_M 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define TSSET2_M 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define TSSET3_M 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define INTACSET 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define HIZSET3 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* ISDB-T registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define TSSET1 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define TSSET1_TSASEL_MASK GENMASK(4, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define TSSET1_TSASEL_ISDBT (0x0 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define TSSET1_TSASEL_ISDBS (0x1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define TSSET1_TSASEL_NONE (0x2 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define TSSET1_TSBSEL_MASK GENMASK(2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define TSSET1_TSBSEL_ISDBS (0x0 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define TSSET1_TSBSEL_ISDBT (0x1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define TSSET1_TSBSEL_NONE (0x2 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define TSSET2 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define TSSET3 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define TSSET3_INTASEL_MASK GENMASK(7, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define TSSET3_INTASEL_T (0x0 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define TSSET3_INTASEL_S (0x1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define TSSET3_INTASEL_NONE (0x2 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define TSSET3_INTBSEL_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define TSSET3_INTBSEL_S (0x0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define TSSET3_INTBSEL_T (0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define TSSET3_INTBSEL_NONE (0x2 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define OUTSET2 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define PWDSET 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define PWDSET_OFDMPD_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define PWDSET_OFDMPD_DOWN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define PWDSET_PSKPD_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define PWDSET_PSKPD_DOWN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define CLKSET1_T 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MDSET_T 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define MDSET_T_MDAUTO_MASK GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define MDSET_T_MDAUTO_AUTO (0xf << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define MDSET_T_MDAUTO_MANUAL (0x0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define MDSET_T_FFTS_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define MDSET_T_FFTS_MODE1 (0x0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define MDSET_T_FFTS_MODE2 (0x1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define MDSET_T_FFTS_MODE3 (0x2 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define MDSET_T_GI_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define MDSET_T_GI_1_32 (0x0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define MDSET_T_GI_1_16 (0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MDSET_T_GI_1_8 (0x2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MDSET_T_GI_1_4 (0x3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MDASET_T 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ADCSET1_T 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define ADCSET1_T_REFSEL_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ADCSET1_T_REFSEL_2V (0x3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define ADCSET1_T_REFSEL_1_5V (0x2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define ADCSET1_T_REFSEL_1V (0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define NCOFREQU_T 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define NCOFREQM_T 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define NCOFREQL_T 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define FADU_T 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define FADM_T 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define FADL_T 0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define AGCSET2_T 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define AGCSET2_T_IFPOLINV_INC BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define AGCSET2_T_RFPOLINV_INC BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define AGCV3_T 0x3e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define MDRD_T 0xa2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define MDRD_T_SEGID_MASK GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define MDRD_T_SEGID_13 (0x0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define MDRD_T_SEGID_1 (0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define MDRD_T_SEGID_3 (0x2 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define MDRD_T_FFTS_MASK GENMASK(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define MDRD_T_FFTS_MODE1 (0x0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define MDRD_T_FFTS_MODE2 (0x1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define MDRD_T_FFTS_MODE3 (0x2 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define MDRD_T_GI_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define MDRD_T_GI_1_32 (0x0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define MDRD_T_GI_1_16 (0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define MDRD_T_GI_1_8 (0x2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define MDRD_T_GI_1_4 (0x3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SSEQRD_T 0xa3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define SSEQRD_T_SSEQSTRD_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SSEQRD_T_SSEQSTRD_RESET (0x0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define SSEQRD_T_SSEQSTRD_TUNING (0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define SSEQRD_T_SSEQSTRD_AGC (0x2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define SSEQRD_T_SSEQSTRD_SEARCH (0x3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define SSEQRD_T_SSEQSTRD_CLOCK_SYNC (0x4 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define SSEQRD_T_SSEQSTRD_FREQ_SYNC (0x8 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define SSEQRD_T_SSEQSTRD_FRAME_SYNC (0x9 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SSEQRD_T_SSEQSTRD_SYNC (0xa << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define SSEQRD_T_SSEQSTRD_LOCK (0xb << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define AGCRDU_T 0xa8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define AGCRDL_T 0xa9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define CNRDU_T 0xbe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define CNRDL_T 0xbf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define BERFLG_T 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define BERFLG_T_BERDRDY BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define BERFLG_T_BERDCHK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define BERFLG_T_BERVRDYA BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define BERFLG_T_BERVCHKA BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define BERFLG_T_BERVRDYB BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define BERFLG_T_BERVCHKB BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define BERFLG_T_BERVRDYC BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define BERFLG_T_BERVCHKC BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define BERRDU_T 0xc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define BERRDM_T 0xc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define BERRDL_T 0xc3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define BERLENRDU_T 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define BERLENRDL_T 0xc5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define ERRFLG_T 0xc6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define ERRFLG_T_BERDOVF BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define ERRFLG_T_BERVOVFA BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define ERRFLG_T_BERVOVFB BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define ERRFLG_T_BERVOVFC BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define ERRFLG_T_NERRFA BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define ERRFLG_T_NERRFB BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define ERRFLG_T_NERRFC BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define ERRFLG_T_NERRF BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define DOSET1_T 0xcf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define CLK_LOW 4000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define CLK_DIRECT 20200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define CLK_MAX 25410000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define S_T_FREQ 8126984 /* 512 / 63 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct mn88443x_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) bool primary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct mn88443x_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) const struct mn88443x_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct dvb_frontend fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct clk *mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u32 if_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Common */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) bool use_clkbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* ISDB-S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct i2c_client *client_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct regmap *regmap_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* ISDB-T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct i2c_client *client_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct regmap *regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int mn88443x_cmn_power_on(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct device *dev = &chip->client_s->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = clk_prepare_enable(chip->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_err(dev, "Failed to prepare and enable mclk: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) gpiod_set_value_cansleep(chip->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) usleep_range(100, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) gpiod_set_value_cansleep(chip->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (chip->spec->primary) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) regmap_write(r_t, OUTCSET, OUTCSET_CHDRV_8MA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) regmap_write(r_t, PLDWSET, PLDWSET_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) regmap_write(r_t, HIZSET1, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) regmap_write(r_t, HIZSET2, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) regmap_write(r_t, HIZSET3, 0x8f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void mn88443x_cmn_power_off(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) gpiod_set_value_cansleep(chip->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) clk_disable_unprepare(chip->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void mn88443x_s_sleep(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) regmap_update_bits(r_t, PWDSET, PWDSET_PSKPD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) PWDSET_PSKPD_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static void mn88443x_s_wake(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) regmap_update_bits(r_t, PWDSET, PWDSET_PSKPD_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void mn88443x_s_tune(struct mn88443x_priv *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct regmap *r_s = chip->regmap_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) regmap_write(r_s, ATSIDU_S, c->stream_id >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) regmap_write(r_s, ATSIDL_S, c->stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) regmap_write(r_s, TSSET_S, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static int mn88443x_s_read_status(struct mn88443x_priv *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct dtv_frontend_properties *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct regmap *r_s = chip->regmap_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) u32 cpmon, tmpu, tmpl, flg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Sync detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) regmap_read(r_s, CPMON1_S, &cpmon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (cpmon & CPMON1_S_FSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (cpmon & CPMON1_S_W2LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Signal strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (*status & FE_HAS_SIGNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u32 agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) regmap_read(r_s, AGCREAD_S, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) agc = tmpu << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) c->strength.stat[0].scale = FE_SCALE_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) c->strength.stat[0].uvalue = agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* C/N rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (*status & FE_HAS_VITERBI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) u32 cnr = 0, x, y, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u64 d_3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) regmap_read(r_s, CNRDXU_S, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) regmap_read(r_s, CNRDXL_S, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) x = (tmpu << 8) | tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) regmap_read(r_s, CNRDYU_S, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) regmap_read(r_s, CNRDYL_S, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) y = (tmpu << 8) | tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* CNR[dB]: 10 * log10(D) - 30.74 / D^3 - 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* D = x^2 / (2^15 * y - x^2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) d = (y << 15) - x * x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (d > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* (2^4 * D)^3 = 2^12 * D^3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* 3.074 * 2^(12 + 24) = 211243671486 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) d_3 = div_u64(16 * x * x, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) d_3 = d_3 * d_3 * d_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (d_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) d_3 = div_u64(211243671486ULL, d_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (d_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* 0.3 * 2^24 = 5033164 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) tmp = (s64)2 * intlog10(x) - intlog10(abs(d)) - d_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) - 5033164;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cnr = div_u64(tmp * 10000, 1 << 24);
^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) if (cnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) c->cnr.stat[0].uvalue = cnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* BER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) regmap_read(r_s, BERCNFLG_S, &flg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if ((*status & FE_HAS_VITERBI) && (flg & BERCNFLG_S_BERVRDY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u32 bit_err, bit_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) regmap_read(r_s, BERVRDU_S, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) regmap_read(r_s, BERVRDL_S, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) bit_err = (tmpu << 8) | tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) bit_cnt = (1 << 13) * 204;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (bit_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) c->post_bit_error.stat[0].uvalue = bit_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) c->post_bit_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) c->post_bit_count.stat[0].uvalue = bit_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void mn88443x_t_sleep(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) regmap_update_bits(r_t, PWDSET, PWDSET_OFDMPD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) PWDSET_OFDMPD_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void mn88443x_t_wake(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) regmap_update_bits(r_t, PWDSET, PWDSET_OFDMPD_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static bool mn88443x_t_is_valid_clk(u32 adckt, u32 if_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (if_freq == DIRECT_IF_57MHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (adckt >= CLK_DIRECT && adckt <= 21000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (adckt >= 25300000 && adckt <= CLK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) } else if (if_freq == DIRECT_IF_44MHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (adckt >= 25000000 && adckt <= CLK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) } else if (if_freq >= LOW_IF_4MHZ && if_freq < DIRECT_IF_44MHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (adckt >= CLK_DIRECT && adckt <= CLK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int mn88443x_t_set_freq(struct mn88443x_priv *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct device *dev = &chip->client_s->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) s64 adckt, nco, ad_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u32 m, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* Clock buffer (but not supported) or XTAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (chip->clk_freq >= CLK_LOW && chip->clk_freq < CLK_DIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) chip->use_clkbuf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) regmap_write(r_t, CLKSET1_T, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) adckt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) chip->use_clkbuf = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) regmap_write(r_t, CLKSET1_T, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) adckt = chip->clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!mn88443x_t_is_valid_clk(adckt, chip->if_freq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dev_err(dev, "Invalid clock, CLK:%d, ADCKT:%lld, IF:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) chip->clk_freq, adckt, chip->if_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Direct IF or Low IF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (chip->if_freq == DIRECT_IF_57MHZ ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) chip->if_freq == DIRECT_IF_44MHZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) nco = adckt * 2 - chip->if_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) nco = -((s64)chip->if_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) nco = div_s64(nco << 24, adckt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ad_t = div_s64(adckt << 22, S_T_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) regmap_write(r_t, NCOFREQU_T, nco >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) regmap_write(r_t, NCOFREQM_T, nco >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) regmap_write(r_t, NCOFREQL_T, nco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) regmap_write(r_t, FADU_T, ad_t >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) regmap_write(r_t, FADM_T, ad_t >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) regmap_write(r_t, FADL_T, ad_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* Level of IF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) m = ADCSET1_T_REFSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) v = ADCSET1_T_REFSEL_1_5V;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) regmap_update_bits(r_t, ADCSET1_T, m, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* Polarity of AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) v = AGCSET2_T_IFPOLINV_INC | AGCSET2_T_RFPOLINV_INC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) regmap_update_bits(r_t, AGCSET2_T, v, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Lower output level of AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) regmap_write(r_t, AGCV3_T, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) regmap_write(r_t, MDSET_T, 0xfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static void mn88443x_t_tune(struct mn88443x_priv *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) u32 m, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) m = MDSET_T_MDAUTO_MASK | MDSET_T_FFTS_MASK | MDSET_T_GI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) v = MDSET_T_MDAUTO_AUTO | MDSET_T_FFTS_MODE3 | MDSET_T_GI_1_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) regmap_update_bits(r_t, MDSET_T, m, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) regmap_write(r_t, MDASET_T, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int mn88443x_t_read_status(struct mn88443x_priv *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct dtv_frontend_properties *c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u32 seqrd, st, flg, tmpu, tmpm, tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* Sync detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) regmap_read(r_t, SSEQRD_T, &seqrd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) st = seqrd & SSEQRD_T_SSEQSTRD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (st >= SSEQRD_T_SSEQSTRD_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (st >= SSEQRD_T_SSEQSTRD_FRAME_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Signal strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (*status & FE_HAS_SIGNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u32 agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) regmap_read(r_t, AGCRDU_T, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) regmap_read(r_t, AGCRDL_T, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) agc = (tmpu << 8) | tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) c->strength.stat[0].scale = FE_SCALE_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) c->strength.stat[0].uvalue = agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* C/N rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (*status & FE_HAS_VITERBI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u32 cnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) regmap_read(r_t, CNRDU_T, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) regmap_read(r_t, CNRDL_T, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (tmpu || tmpl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* CNR[dB]: 10 * (log10(65536 / value) + 0.2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* intlog10(65536) = 80807124, 0.2 * 2^24 = 3355443 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) tmp = (u64)80807124 - intlog10((tmpu << 8) | tmpl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) + 3355443;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) cnr = div_u64(tmp * 10000, 1 << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cnr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) c->cnr.stat[0].uvalue = cnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* BER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) regmap_read(r_t, BERFLG_T, &flg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if ((*status & FE_HAS_VITERBI) && (flg & BERFLG_T_BERVRDYA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u32 bit_err, bit_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) regmap_read(r_t, BERRDU_T, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) regmap_read(r_t, BERRDM_T, &tmpm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) regmap_read(r_t, BERRDL_T, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) bit_err = (tmpu << 16) | (tmpm << 8) | tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) regmap_read(r_t, BERLENRDU_T, &tmpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) regmap_read(r_t, BERLENRDL_T, &tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) bit_cnt = ((tmpu << 8) | tmpl) * 203 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (bit_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) c->post_bit_error.stat[0].uvalue = bit_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) c->post_bit_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) c->post_bit_count.stat[0].uvalue = bit_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int mn88443x_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct mn88443x_priv *chip = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) mn88443x_s_sleep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) mn88443x_t_sleep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int mn88443x_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct mn88443x_priv *chip = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct regmap *r_s = chip->regmap_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct regmap *r_t = chip->regmap_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) u8 tssel = 0, intsel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (c->delivery_system == SYS_ISDBS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mn88443x_s_wake(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mn88443x_t_sleep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) tssel = TSSET1_TSASEL_ISDBS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) intsel = TSSET3_INTASEL_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) } else if (c->delivery_system == SYS_ISDBT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) mn88443x_s_sleep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mn88443x_t_wake(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) mn88443x_t_set_freq(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) tssel = TSSET1_TSASEL_ISDBT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) intsel = TSSET3_INTASEL_T;
^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) regmap_update_bits(r_t, TSSET1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) TSSET1_TSASEL_MASK | TSSET1_TSBSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) tssel | TSSET1_TSBSEL_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) regmap_write(r_t, TSSET2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) regmap_update_bits(r_t, TSSET3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) TSSET3_INTASEL_MASK | TSSET3_INTBSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) intsel | TSSET3_INTBSEL_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) regmap_write(r_t, DOSET1_T, 0x95);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) regmap_write(r_s, DOSET1_S, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (c->delivery_system == SYS_ISDBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) mn88443x_s_tune(chip, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) else if (c->delivery_system == SYS_ISDBT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) mn88443x_t_tune(chip, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (fe->ops.tuner_ops.set_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int mn88443x_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) s->min_delay_ms = 850;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (c->delivery_system == SYS_ISDBS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) s->max_drift = 30000 * 2 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) s->step_size = 30000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) } else if (c->delivery_system == SYS_ISDBT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) s->max_drift = 142857 * 2 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) s->step_size = 142857 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static int mn88443x_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct mn88443x_priv *chip = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (c->delivery_system == SYS_ISDBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return mn88443x_s_read_status(chip, c, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (c->delivery_system == SYS_ISDBT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return mn88443x_t_read_status(chip, c, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static const struct dvb_frontend_ops mn88443x_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .delsys = { SYS_ISDBS, SYS_ISDBT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .name = "Socionext MN88443x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .frequency_min_hz = 470 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .frequency_max_hz = 2071 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .symbol_rate_min = 28860000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .symbol_rate_max = 28860000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .sleep = mn88443x_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .set_frontend = mn88443x_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .get_tune_settings = mn88443x_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .read_status = mn88443x_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static const struct regmap_config regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .cache_type = REGCACHE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static int mn88443x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct mn88443x_config *conf = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct mn88443x_priv *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) chip->spec = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) chip->spec = (struct mn88443x_spec *)id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!chip->spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) chip->mclk = devm_clk_get(dev, "mclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (IS_ERR(chip->mclk) && !conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) dev_err(dev, "Failed to request mclk: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) PTR_ERR(chip->mclk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return PTR_ERR(chip->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ret = of_property_read_u32(dev->of_node, "if-frequency",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) &chip->if_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (ret && !conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_err(dev, "Failed to load IF frequency: %d.\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) chip->reset_gpio = devm_gpiod_get_optional(dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (IS_ERR(chip->reset_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dev_err(dev, "Failed to request reset_gpio: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) PTR_ERR(chip->reset_gpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return PTR_ERR(chip->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) chip->mclk = conf->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) chip->if_freq = conf->if_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) chip->reset_gpio = conf->reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) *conf->fe = &chip->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) chip->client_s = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) chip->regmap_s = devm_regmap_init_i2c(chip->client_s, ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (IS_ERR(chip->regmap_s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return PTR_ERR(chip->regmap_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * Chip has two I2C addresses for each satellite/terrestrial system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * ISDB-T uses address ISDB-S + 4, so we register a dummy client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) chip->client_t = i2c_new_dummy_device(client->adapter, client->addr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (IS_ERR(chip->client_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return PTR_ERR(chip->client_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) chip->regmap_t = devm_regmap_init_i2c(chip->client_t, ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (IS_ERR(chip->regmap_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret = PTR_ERR(chip->regmap_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto err_i2c_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) chip->clk_freq = clk_get_rate(chip->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) memcpy(&chip->fe.ops, &mn88443x_ops, sizeof(mn88443x_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) chip->fe.demodulator_priv = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ret = mn88443x_cmn_power_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto err_i2c_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) mn88443x_s_sleep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mn88443x_t_sleep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) err_i2c_t:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) i2c_unregister_device(chip->client_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static int mn88443x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct mn88443x_priv *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) mn88443x_cmn_power_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) i2c_unregister_device(chip->client_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static const struct mn88443x_spec mn88443x_spec_pri = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .primary = 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) static const struct mn88443x_spec mn88443x_spec_sec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .primary = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static const struct of_device_id mn88443x_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) { .compatible = "socionext,mn884433", .data = &mn88443x_spec_pri, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) { .compatible = "socionext,mn884434-0", .data = &mn88443x_spec_pri, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) { .compatible = "socionext,mn884434-1", .data = &mn88443x_spec_sec, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) MODULE_DEVICE_TABLE(of, mn88443x_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static const struct i2c_device_id mn88443x_i2c_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) { "mn884433", (kernel_ulong_t)&mn88443x_spec_pri },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) { "mn884434-0", (kernel_ulong_t)&mn88443x_spec_pri },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) { "mn884434-1", (kernel_ulong_t)&mn88443x_spec_sec },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) MODULE_DEVICE_TABLE(i2c, mn88443x_i2c_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static struct i2c_driver mn88443x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .name = "mn88443x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .of_match_table = of_match_ptr(mn88443x_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .probe = mn88443x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .remove = mn88443x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .id_table = mn88443x_i2c_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) module_i2c_driver(mn88443x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) MODULE_DESCRIPTION("Socionext MN88443x series demodulator driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) MODULE_LICENSE("GPL v2");