]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | Driver for Philips tda1004xh OFDM Frontend | |
3 | ||
4 | (c) 2004 Andrew de Quincey | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ||
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
20 | ||
21 | */ | |
22 | ||
23 | #ifndef TDA1004X_H | |
24 | #define TDA1004X_H | |
25 | ||
26 | #include <linux/dvb/frontend.h> | |
27 | #include <linux/firmware.h> | |
28 | ||
ecb60deb HH |
29 | enum tda10046_xtal { |
30 | TDA10046_XTAL_4M, | |
31 | TDA10046_XTAL_16M, | |
32 | }; | |
33 | ||
34 | enum tda10046_agc { | |
35 | TDA10046_AGC_DEFAULT, /* original configuration */ | |
36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ | |
f03cbea3 | 37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ |
1bb0e866 HH |
38 | TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ |
39 | }; | |
40 | ||
41 | /* Many (hybrid) boards use GPIO 1 and 3 | |
42 | GPIO1 analog - dvb switch | |
43 | GPIO3 firmware eeprom address switch | |
44 | */ | |
45 | enum tda10046_gpio { | |
46 | TDA10046_GPTRI = 0x00, /* All GPIOs tristate */ | |
47 | TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */ | |
48 | TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */ | |
49 | TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */ | |
50 | TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */ | |
51 | TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/ | |
52 | TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */ | |
53 | TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */ | |
54 | TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */ | |
ecb60deb HH |
55 | }; |
56 | ||
57 | enum tda10046_if { | |
58 | TDA10046_FREQ_3617, /* original config, 36,166 MHZ */ | |
59 | TDA10046_FREQ_3613, /* 36,13 MHZ */ | |
f03cbea3 HH |
60 | TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */ |
61 | TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ | |
ecb60deb HH |
62 | }; |
63 | ||
08cdf94c HH |
64 | enum tda10046_tsout { |
65 | TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */ | |
66 | TDA10046_TS_SERIAL = 0x01, /* serial transport stream */ | |
67 | }; | |
68 | ||
1da177e4 LT |
69 | struct tda1004x_config |
70 | { | |
71 | /* the demodulator's i2c address */ | |
72 | u8 demod_address; | |
73 | ||
74 | /* does the "inversion" need inverted? */ | |
dd102c75 | 75 | u8 invert; |
1da177e4 LT |
76 | |
77 | /* Does the OCLK signal need inverted? */ | |
dd102c75 | 78 | u8 invert_oclk; |
1da177e4 | 79 | |
08cdf94c HH |
80 | /* parallel or serial transport stream */ |
81 | enum tda10046_tsout ts_mode; | |
82 | ||
ecb60deb HH |
83 | /* Xtal frequency, 4 or 16MHz*/ |
84 | enum tda10046_xtal xtal_freq; | |
85 | ||
86 | /* IF frequency */ | |
87 | enum tda10046_if if_freq; | |
88 | ||
89 | /* AGC configuration */ | |
90 | enum tda10046_agc agc_config; | |
1dfb800f | 91 | |
1bb0e866 HH |
92 | /* setting of GPIO1 and 3 */ |
93 | enum tda10046_gpio gpio_config; | |
94 | ||
95 | /* slave address and configuration of the tuner */ | |
96 | u8 tuner_address; | |
1bb0e866 HH |
97 | u8 antenna_switch; |
98 | ||
99 | /* if the board uses another I2c Bridge (tda8290), its address */ | |
100 | u8 i2c_gate; | |
101 | ||
1da177e4 LT |
102 | /* request firmware for device */ |
103 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | |
104 | }; | |
105 | ||
1bb0e866 HH |
106 | enum tda1004x_demod { |
107 | TDA1004X_DEMOD_TDA10045, | |
108 | TDA1004X_DEMOD_TDA10046, | |
109 | }; | |
110 | ||
111 | struct tda1004x_state { | |
112 | struct i2c_adapter* i2c; | |
113 | const struct tda1004x_config* config; | |
114 | struct dvb_frontend frontend; | |
115 | ||
1bb0e866 HH |
116 | /* private demod data */ |
117 | enum tda1004x_demod demod_type; | |
118 | }; | |
119 | ||
7b34be71 | 120 | #if IS_ENABLED(CONFIG_DVB_TDA1004X) |
1da177e4 LT |
121 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
122 | struct i2c_adapter* i2c); | |
123 | ||
124 | extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | |
125 | struct i2c_adapter* i2c); | |
102a342b AQ |
126 | #else |
127 | static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | |
128 | struct i2c_adapter* i2c) | |
129 | { | |
271ddbf7 | 130 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
102a342b AQ |
131 | return NULL; |
132 | } | |
133 | static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | |
134 | struct i2c_adapter* i2c) | |
135 | { | |
271ddbf7 | 136 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
102a342b AQ |
137 | return NULL; |
138 | } | |
139 | #endif // CONFIG_DVB_TDA1004X | |
1da177e4 | 140 | |
c10d14d6 AQ |
141 | static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { |
142 | int r = 0; | |
143 | u8 buf[] = {reg, val}; | |
144 | if (fe->ops.write) | |
145 | r = fe->ops.write(fe, buf, 2); | |
146 | return r; | |
147 | } | |
1da177e4 LT |
148 | |
149 | #endif // TDA1004X_H |