19a0bf528SMauro Carvalho Chehab   /*
29a0bf528SMauro Carvalho Chehab      Driver for Philips tda1004xh OFDM Frontend
39a0bf528SMauro Carvalho Chehab 
49a0bf528SMauro Carvalho Chehab      (c) 2004 Andrew de Quincey
59a0bf528SMauro Carvalho Chehab 
69a0bf528SMauro Carvalho Chehab      This program is free software; you can redistribute it and/or modify
79a0bf528SMauro Carvalho Chehab      it under the terms of the GNU General Public License as published by
89a0bf528SMauro Carvalho Chehab      the Free Software Foundation; either version 2 of the License, or
99a0bf528SMauro Carvalho Chehab      (at your option) any later version.
109a0bf528SMauro Carvalho Chehab 
119a0bf528SMauro Carvalho Chehab      This program is distributed in the hope that it will be useful,
129a0bf528SMauro Carvalho Chehab      but WITHOUT ANY WARRANTY; without even the implied warranty of
139a0bf528SMauro Carvalho Chehab      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
149a0bf528SMauro Carvalho Chehab 
159a0bf528SMauro Carvalho Chehab      GNU General Public License for more details.
169a0bf528SMauro Carvalho Chehab 
179a0bf528SMauro Carvalho Chehab      You should have received a copy of the GNU General Public License
189a0bf528SMauro Carvalho Chehab      along with this program; if not, write to the Free Software
199a0bf528SMauro Carvalho Chehab      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
209a0bf528SMauro Carvalho Chehab 
219a0bf528SMauro Carvalho Chehab    */
229a0bf528SMauro Carvalho Chehab 
239a0bf528SMauro Carvalho Chehab #ifndef TDA1004X_H
249a0bf528SMauro Carvalho Chehab #define TDA1004X_H
259a0bf528SMauro Carvalho Chehab 
269a0bf528SMauro Carvalho Chehab #include <linux/dvb/frontend.h>
279a0bf528SMauro Carvalho Chehab #include <linux/firmware.h>
289a0bf528SMauro Carvalho Chehab 
299a0bf528SMauro Carvalho Chehab enum tda10046_xtal {
309a0bf528SMauro Carvalho Chehab 	TDA10046_XTAL_4M,
319a0bf528SMauro Carvalho Chehab 	TDA10046_XTAL_16M,
329a0bf528SMauro Carvalho Chehab };
339a0bf528SMauro Carvalho Chehab 
349a0bf528SMauro Carvalho Chehab enum tda10046_agc {
359a0bf528SMauro Carvalho Chehab 	TDA10046_AGC_DEFAULT,		/* original configuration */
369a0bf528SMauro Carvalho Chehab 	TDA10046_AGC_IFO_AUTO_NEG,	/* IF AGC only, automatic, negtive */
379a0bf528SMauro Carvalho Chehab 	TDA10046_AGC_IFO_AUTO_POS,	/* IF AGC only, automatic, positive */
389a0bf528SMauro Carvalho Chehab 	TDA10046_AGC_TDA827X,		/* IF AGC only, special setup for tda827x */
399a0bf528SMauro Carvalho Chehab };
409a0bf528SMauro Carvalho Chehab 
419a0bf528SMauro Carvalho Chehab /* Many (hybrid) boards use GPIO 1 and 3
429a0bf528SMauro Carvalho Chehab 	GPIO1	analog - dvb switch
439a0bf528SMauro Carvalho Chehab 	GPIO3	firmware eeprom address switch
449a0bf528SMauro Carvalho Chehab */
459a0bf528SMauro Carvalho Chehab enum tda10046_gpio {
469a0bf528SMauro Carvalho Chehab 	TDA10046_GPTRI  = 0x00,		/* All GPIOs tristate */
479a0bf528SMauro Carvalho Chehab 	TDA10046_GP00   = 0x40,		/* GPIO3=0, GPIO1=0 */
489a0bf528SMauro Carvalho Chehab 	TDA10046_GP01   = 0x42,		/* GPIO3=0, GPIO1=1 */
499a0bf528SMauro Carvalho Chehab 	TDA10046_GP10   = 0x48,		/* GPIO3=1, GPIO1=0 */
509a0bf528SMauro Carvalho Chehab 	TDA10046_GP11   = 0x4a,		/* GPIO3=1, GPIO1=1 */
519a0bf528SMauro Carvalho Chehab 	TDA10046_GP00_I = 0x80,		/* GPIO3=0, GPIO1=0, invert in sleep mode*/
529a0bf528SMauro Carvalho Chehab 	TDA10046_GP01_I = 0x82,		/* GPIO3=0, GPIO1=1, invert in sleep mode */
539a0bf528SMauro Carvalho Chehab 	TDA10046_GP10_I = 0x88,		/* GPIO3=1, GPIO1=0, invert in sleep mode */
549a0bf528SMauro Carvalho Chehab 	TDA10046_GP11_I = 0x8a,		/* GPIO3=1, GPIO1=1, invert in sleep mode */
559a0bf528SMauro Carvalho Chehab };
569a0bf528SMauro Carvalho Chehab 
579a0bf528SMauro Carvalho Chehab enum tda10046_if {
589a0bf528SMauro Carvalho Chehab 	TDA10046_FREQ_3617,		/* original config, 36,166 MHZ */
599a0bf528SMauro Carvalho Chehab 	TDA10046_FREQ_3613,		/* 36,13 MHZ */
609a0bf528SMauro Carvalho Chehab 	TDA10046_FREQ_045,		/* low IF, 4.0, 4.5, or 5.0 MHZ */
619a0bf528SMauro Carvalho Chehab 	TDA10046_FREQ_052,		/* low IF, 5.1667 MHZ for tda9889 */
629a0bf528SMauro Carvalho Chehab };
639a0bf528SMauro Carvalho Chehab 
649a0bf528SMauro Carvalho Chehab enum tda10046_tsout {
659a0bf528SMauro Carvalho Chehab 	TDA10046_TS_PARALLEL  = 0x00,	/* parallel transport stream, default */
669a0bf528SMauro Carvalho Chehab 	TDA10046_TS_SERIAL    = 0x01,	/* serial transport stream */
679a0bf528SMauro Carvalho Chehab };
689a0bf528SMauro Carvalho Chehab 
699a0bf528SMauro Carvalho Chehab struct tda1004x_config
709a0bf528SMauro Carvalho Chehab {
719a0bf528SMauro Carvalho Chehab 	/* the demodulator's i2c address */
729a0bf528SMauro Carvalho Chehab 	u8 demod_address;
739a0bf528SMauro Carvalho Chehab 
749a0bf528SMauro Carvalho Chehab 	/* does the "inversion" need inverted? */
759a0bf528SMauro Carvalho Chehab 	u8 invert;
769a0bf528SMauro Carvalho Chehab 
779a0bf528SMauro Carvalho Chehab 	/* Does the OCLK signal need inverted? */
789a0bf528SMauro Carvalho Chehab 	u8 invert_oclk;
799a0bf528SMauro Carvalho Chehab 
809a0bf528SMauro Carvalho Chehab 	/* parallel or serial transport stream */
819a0bf528SMauro Carvalho Chehab 	enum tda10046_tsout ts_mode;
829a0bf528SMauro Carvalho Chehab 
839a0bf528SMauro Carvalho Chehab 	/* Xtal frequency, 4 or 16MHz*/
849a0bf528SMauro Carvalho Chehab 	enum tda10046_xtal xtal_freq;
859a0bf528SMauro Carvalho Chehab 
869a0bf528SMauro Carvalho Chehab 	/* IF frequency */
879a0bf528SMauro Carvalho Chehab 	enum tda10046_if if_freq;
889a0bf528SMauro Carvalho Chehab 
899a0bf528SMauro Carvalho Chehab 	/* AGC configuration */
909a0bf528SMauro Carvalho Chehab 	enum tda10046_agc agc_config;
919a0bf528SMauro Carvalho Chehab 
929a0bf528SMauro Carvalho Chehab 	/* setting of GPIO1 and 3 */
939a0bf528SMauro Carvalho Chehab 	enum tda10046_gpio gpio_config;
949a0bf528SMauro Carvalho Chehab 
959a0bf528SMauro Carvalho Chehab 	/* slave address and configuration of the tuner */
969a0bf528SMauro Carvalho Chehab 	u8 tuner_address;
979a0bf528SMauro Carvalho Chehab 	u8 antenna_switch;
989a0bf528SMauro Carvalho Chehab 
999a0bf528SMauro Carvalho Chehab 	/* if the board uses another I2c Bridge (tda8290), its address */
1009a0bf528SMauro Carvalho Chehab 	u8 i2c_gate;
1019a0bf528SMauro Carvalho Chehab 
1029a0bf528SMauro Carvalho Chehab 	/* request firmware for device */
1039a0bf528SMauro Carvalho Chehab 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
1049a0bf528SMauro Carvalho Chehab };
1059a0bf528SMauro Carvalho Chehab 
1069a0bf528SMauro Carvalho Chehab enum tda1004x_demod {
1079a0bf528SMauro Carvalho Chehab 	TDA1004X_DEMOD_TDA10045,
1089a0bf528SMauro Carvalho Chehab 	TDA1004X_DEMOD_TDA10046,
1099a0bf528SMauro Carvalho Chehab };
1109a0bf528SMauro Carvalho Chehab 
1119a0bf528SMauro Carvalho Chehab struct tda1004x_state {
1129a0bf528SMauro Carvalho Chehab 	struct i2c_adapter* i2c;
1139a0bf528SMauro Carvalho Chehab 	const struct tda1004x_config* config;
1149a0bf528SMauro Carvalho Chehab 	struct dvb_frontend frontend;
1159a0bf528SMauro Carvalho Chehab 
1169a0bf528SMauro Carvalho Chehab 	/* private demod data */
1179a0bf528SMauro Carvalho Chehab 	enum tda1004x_demod demod_type;
1189a0bf528SMauro Carvalho Chehab };
1199a0bf528SMauro Carvalho Chehab 
1209a0bf528SMauro Carvalho Chehab #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
1219a0bf528SMauro Carvalho Chehab extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1229a0bf528SMauro Carvalho Chehab 					    struct i2c_adapter* i2c);
1239a0bf528SMauro Carvalho Chehab 
1249a0bf528SMauro Carvalho Chehab extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1259a0bf528SMauro Carvalho Chehab 					    struct i2c_adapter* i2c);
1269a0bf528SMauro Carvalho Chehab #else
1279a0bf528SMauro Carvalho Chehab static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1289a0bf528SMauro Carvalho Chehab 					    struct i2c_adapter* i2c)
1299a0bf528SMauro Carvalho Chehab {
1309a0bf528SMauro Carvalho Chehab 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
1319a0bf528SMauro Carvalho Chehab 	return NULL;
1329a0bf528SMauro Carvalho Chehab }
1339a0bf528SMauro Carvalho Chehab static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1349a0bf528SMauro Carvalho Chehab 					    struct i2c_adapter* i2c)
1359a0bf528SMauro Carvalho Chehab {
1369a0bf528SMauro Carvalho Chehab 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
1379a0bf528SMauro Carvalho Chehab 	return NULL;
1389a0bf528SMauro Carvalho Chehab }
1399a0bf528SMauro Carvalho Chehab #endif // CONFIG_DVB_TDA1004X
1409a0bf528SMauro Carvalho Chehab 
1419a0bf528SMauro Carvalho Chehab static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
1429a0bf528SMauro Carvalho Chehab 	int r = 0;
1439a0bf528SMauro Carvalho Chehab 	u8 buf[] = {reg, val};
1449a0bf528SMauro Carvalho Chehab 	if (fe->ops.write)
1459a0bf528SMauro Carvalho Chehab 		r = fe->ops.write(fe, buf, 2);
1469a0bf528SMauro Carvalho Chehab 	return r;
1479a0bf528SMauro Carvalho Chehab }
1489a0bf528SMauro Carvalho Chehab 
1499a0bf528SMauro Carvalho Chehab #endif // TDA1004X_H
150