djh - merge from tip
authorDevin Heitmueller <dheitmueller@kernellabs.com>
Sun Oct 04 21:38:39 2009 -0400 (2 years ago)
changeset 13062ffe6a0ea1f63
parent 130446b7617d4a0be
parent 1306144f6f73b3899
child 130638173144cbebd
djh - merge from tip
linux/Documentation/video4linux/CARDLIST.tuner
linux/drivers/media/common/tuners/tuner-types.c
linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
linux/drivers/media/dvb/frontends/dib7000p.c
linux/drivers/media/video/tuner-core.c
linux/include/media/tuner.h
       1 --- a/linux/Documentation/video4linux/CARDLIST.tuner	Sat Sep 26 13:45:03 2009 -0300
       2 +++ b/linux/Documentation/video4linux/CARDLIST.tuner	Sun Oct 04 21:38:39 2009 -0400
       3 @@ -81,3 +81,4 @@
       4  tuner=81 - Partsnic (Daewoo) PTI-5NF05
       5  tuner=82 - Philips CU1216L
       6  tuner=83 - NXP TDA18271
       7 +tuner=84 - Xceive 4000 tuner
     1.1 --- a/linux/drivers/media/common/tuners/Kconfig	Sat Sep 26 13:45:03 2009 -0300
     1.2 +++ b/linux/drivers/media/common/tuners/Kconfig	Sun Oct 04 21:38:39 2009 -0400
     1.3 @@ -23,6 +23,7 @@
     1.4  	depends on VIDEO_MEDIA && I2C
     1.5  	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
     1.6  	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
     1.7 +	select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
     1.8  	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
     1.9  	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
    1.10  	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
    1.11 @@ -151,6 +152,15 @@
    1.12  	  This device is only used inside a SiP called together with a
    1.13  	  demodulator for now.
    1.14  
    1.15 +config MEDIA_TUNER_XC4000
    1.16 +	tristate "Xceive XC4000 silicon tuner"
    1.17 +	depends on VIDEO_MEDIA && I2C
    1.18 +	default m if MEDIA_TUNER_CUSTOMISE
    1.19 +	help
    1.20 +	  A driver for the silicon tuner XC4000 from Xceive.
    1.21 +	  This device is only used inside a SiP called together with a
    1.22 +	  demodulator for now.
    1.23 +
    1.24  config MEDIA_TUNER_MXL5005S
    1.25  	tristate "MaxLinear MSL5005S silicon tuner"
    1.26  	depends on VIDEO_MEDIA && I2C
     2.1 --- a/linux/drivers/media/common/tuners/Makefile	Sat Sep 26 13:45:03 2009 -0300
     2.2 +++ b/linux/drivers/media/common/tuners/Makefile	Sun Oct 04 21:38:39 2009 -0400
     2.3 @@ -16,6 +16,7 @@
     2.4  obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
     2.5  obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
     2.6  obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
     2.7 +obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
     2.8  obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
     2.9  obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
    2.10  obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
     3.1 --- a/linux/drivers/media/common/tuners/tuner-types.c	Sat Sep 26 13:45:03 2009 -0300
     3.2 +++ b/linux/drivers/media/common/tuners/tuner-types.c	Sun Oct 04 21:38:39 2009 -0400
     3.3 @@ -1763,6 +1763,10 @@
     3.4  		.name   = "Xceive 5000 tuner",
     3.5  		/* see xc5000.c for details */
     3.6  	},
     3.7 +	[TUNER_XC4000] = { /* Xceive 4000 */
     3.8 +		.name   = "Xceive 4000 tuner",
     3.9 +		/* see xc4000.c for details */
    3.10 +	},
    3.11  	[TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
    3.12  		.name   = "TCL tuner MF02GIP-5N-E",
    3.13  		.params = tuner_tcl_mf02gip_5n_params,
     4.1 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c	Sat Sep 26 13:45:03 2009 -0300
     4.2 +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c	Sun Oct 04 21:38:39 2009 -0400
     4.3 @@ -16,6 +16,7 @@
     4.4  #include "mt2266.h"
     4.5  #include "tuner-xc2028.h"
     4.6  #include "xc5000.h"
     4.7 +#include "xc4000.h"
     4.8  #include "s5h1411.h"
     4.9  #include "dib0070.h"
    4.10  #include "lgdt3305.h"
    4.11 @@ -1778,6 +1779,173 @@
    4.12  		== NULL ? -ENODEV : 0;
    4.13  }
    4.14  
    4.15 +static int dib0700_xc4000_tuner_callback(void *priv, int component,
    4.16 +					 int command, int arg)
    4.17 +{
    4.18 +	struct dvb_usb_adapter *adap = priv;
    4.19 +
    4.20 +	if (command == XC4000_TUNER_RESET) {
    4.21 +		/* Reset the tuner */
    4.22 +		dib7000p_set_gpio(adap->fe, 8, 0, 0);
    4.23 +		msleep(10);
    4.24 +		dib7000p_set_gpio(adap->fe, 8, 0, 1);
    4.25 +	} else {
    4.26 +		err("xc4000: unknown tuner callback command: %d\n", command);
    4.27 +		return -EINVAL;
    4.28 +	}
    4.29 +
    4.30 +	return 0;
    4.31 +}
    4.32 +
    4.33 +/* validation:
    4.34 +   band
    4.35 +   setup 0x4b=0x64
    4.36 +   inv_gain 0x4c=0x02c8
    4.37 +   time_stabaliz 0x4d=0x0015
    4.38 +   alpha_level 0 (0x64=0x0076)
    4.39 +   thlock 0x76 (0x64=0x0076)
    4.40 +   wbd_inv 0x01 (0x69=0x1b33)
    4.41 +   wbd_ref 0x0b33 (0x69=1b33)
    4.42 +   wbd_sel 0x00 (0x6a=0400)
    4.43 +   wbd_alpha 0x02 (0x6a=0x400)
    4.44 +   agc1_max 0x00 (0x6b=0x0000)
    4.45 +   agc1_min 0x00 (0x6c=0x0000)
    4.46 +   agc2_max 0x9b26 (0x6d=0x9b26)
    4.47 +   agc2_min 0x26ca (0x6e=0x26ca)
    4.48 +   agc1_pt1 0x00 (0x6f=0x0000)
    4.49 +   agc1_pt2 0x00 (0x6f=0x0000)
    4.50 +   agc1_pt3 0x00 (0x70=0x0000)
    4.51 +   agc1_slope1 0x00 (0x71=0x0000)
    4.52 +   agc1_slope2 0x00 (0x71=0x0000)
    4.53 +   agc2_pt1 0x00 (0x72=0x0080)
    4.54 +   agc2_pt2 0x80 (0x72=0x0080)
    4.55 +   agc2_slope1 0x1d (0x73=0x1d1d)
    4.56 +   agc2_slope2 0x1d (0x73=0x1d1d)
    4.57 +   alpha_mant 0x11 (0x65=023b)
    4.58 +   alpha_exp 0x1b (0x65=023b)
    4.59 +   beta_mant 0x17 (0x66=05f3)
    4.60 +   beta_exp 0x33 (0x66=05f3)
    4.61 +   perform_agc_softsplit 0x00 (0x6a=0x400)
    4.62 +
    4.63 + */
    4.64 +static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
    4.65 +	.band_caps = BAND_UHF | BAND_VHF,
    4.66 +	.setup = 0x64,
    4.67 +	.inv_gain = 0x02c8,
    4.68 +	.time_stabiliz = 0x15,
    4.69 +	.alpha_level = 0x00,
    4.70 +	.thlock = 0x76,
    4.71 +	.wbd_inv = 0x01,
    4.72 +	.wbd_ref = 0x0b33,
    4.73 +	.wbd_sel = 0x00,
    4.74 +	.wbd_alpha = 0x02,
    4.75 +	.agc1_max = 0x00,
    4.76 +	.agc1_min = 0x00,
    4.77 +	.agc2_max = 0x9b26,
    4.78 +	.agc2_min = 0x26ca,
    4.79 +	.agc1_pt1 = 0x00,
    4.80 +	.agc1_pt2 = 0x00,
    4.81 +	.agc1_pt3 = 0x00,
    4.82 +	.agc1_slope1 = 0x00,
    4.83 +	.agc1_slope2 = 0x00,
    4.84 +	.agc2_pt1 = 0x00,
    4.85 +	.agc2_pt2 = 0x80,
    4.86 +	.agc2_slope1 = 0x1d,
    4.87 +	.agc2_slope2 = 0x1d,
    4.88 +	.alpha_exp = 0x1b,
    4.89 +	.beta_mant = 0x17,
    4.90 +	.beta_exp = 0x33,
    4.91 +	.perform_agc_softsplit = 0x00,
    4.92 +};
    4.93 +
    4.94 +/* FIXME: none of these inputs are validated yet */
    4.95 +static struct dib7000p_config pctv_340e_config = {
    4.96 +	.output_mpeg2_in_188_bytes = 1, // validated L3317: 0x00eb=0x0066
    4.97 +
    4.98 +	.agc_config_count = 1,
    4.99 +	.agc = &stk7700p_7000p_xc4000_agc_config,
   4.100 +	.bw  = &stk7700p_pll_config,
   4.101 +
   4.102 +	.gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
   4.103 +	.gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
   4.104 +	.gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
   4.105 +};
   4.106 +
   4.107 +/* PCTV 340e GPIOs map:
   4.108 +   dib0700:
   4.109 +   GPIO2  - CX25843 sleep
   4.110 +   GPIO3  - CS5340 reset
   4.111 +   GPIO5  - IRD
   4.112 +   GPIO6  - Power Supply
   4.113 +   GPIO8  - LNA (1=off 0=on)
   4.114 +   GPIO10 - CX25843 reset
   4.115 +   dib7000:
   4.116 +   GPIO8  - xc4000 reset
   4.117 + */
   4.118 +static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
   4.119 +{
   4.120 +	struct dib0700_state *st = adap->dev->priv;
   4.121 +
   4.122 +	/* Power Supply on */
   4.123 +	dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0);
   4.124 +	msleep(50);
   4.125 +	dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1);
   4.126 +	msleep(100); /* Allow power supply to settle before probing */
   4.127 +
   4.128 +	/* cx25843 reset */
   4.129 +	dib0700_set_gpio(adap->dev, GPIO10,  GPIO_OUT, 0);
   4.130 +	msleep(1); /* cx25843 datasheet say 350us required */
   4.131 +	dib0700_set_gpio(adap->dev, GPIO10,  GPIO_OUT, 1);
   4.132 +
   4.133 +	/* LNA off for now */
   4.134 +	dib0700_set_gpio(adap->dev, GPIO8,  GPIO_OUT, 1);
   4.135 +
   4.136 +	/* Put the CX25843 to sleep for now since we're in digital mode */
   4.137 +	dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
   4.138 +
   4.139 +	/* FIXME: not verified yet */
   4.140 +	dib0700_ctrl_clock(adap->dev, 72, 1);
   4.141 +
   4.142 +	msleep(500);
   4.143 +
   4.144 +	if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
   4.145 +		/* Demodulator not found for some reason? */
   4.146 +		return -ENODEV;
   4.147 +	}
   4.148 +
   4.149 +	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
   4.150 +			      &pctv_340e_config);
   4.151 +	st->is_dib7000pc = 1;
   4.152 +
   4.153 +	return adap->fe == NULL ? -ENODEV : 0;
   4.154 +}
   4.155 +
   4.156 +
   4.157 +static struct xc4000_config dib7000p_xc4000_tunerconfig = {
   4.158 +	.i2c_address      = 0x61,
   4.159 +	.if_khz           = 5400,
   4.160 +};
   4.161 +
   4.162 +static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
   4.163 +{
   4.164 +	struct i2c_adapter *tun_i2c;
   4.165 +
   4.166 +	/* The xc4000 is not on the main i2c bus */
   4.167 +	tun_i2c = dib7000p_get_i2c_master(adap->fe,
   4.168 +					  DIBX000_I2C_INTERFACE_TUNER, 1);
   4.169 +	if (tun_i2c == NULL) {
   4.170 +		printk("Could not reach tuner i2c bus\n");
   4.171 +		return 0;
   4.172 +	}
   4.173 +
   4.174 +	/* Setup the reset callback */
   4.175 +	adap->fe->callback = dib0700_xc4000_tuner_callback;
   4.176 +
   4.177 +	return dvb_attach(xc4000_attach, adap->fe, tun_i2c,
   4.178 +			  &dib7000p_xc4000_tunerconfig)
   4.179 +		== NULL ? -ENODEV : 0;
   4.180 +}
   4.181 +
   4.182  static struct lgdt3305_config hcw_lgdt3305_config = {
   4.183  	.i2c_addr           = 0x0e,
   4.184  	.mpeg_mode          = LGDT3305_MPEG_PARALLEL,
   4.185 @@ -1917,6 +2085,8 @@
   4.186  	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
   4.187  	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
   4.188  	{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
   4.189 +	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E) },
   4.190 +/* 65 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E_SE) },
   4.191  	{ 0 }		/* Terminating entry */
   4.192  };
   4.193  MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
   4.194 @@ -2474,6 +2644,35 @@
   4.195  		.rc_key_map       = dib0700_rc_keys,
   4.196  		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
   4.197  		.rc_query         = dib0700_rc_query
   4.198 +	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
   4.199 +		.num_adapters = 1,
   4.200 +		.adapter = {
   4.201 +			{
   4.202 +				.frontend_attach  = pctv340e_frontend_attach,
   4.203 +				.tuner_attach     = xc4000_tuner_attach,
   4.204 +
   4.205 +				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
   4.206 +
   4.207 +				.size_of_priv = sizeof(struct
   4.208 +						dib0700_adapter_state),
   4.209 +			},
   4.210 +		},
   4.211 +
   4.212 +		.num_device_descs = 2,
   4.213 +		.devices = {
   4.214 +			{   "Pinnacle PCTV 340e HD Pro USB Stick",
   4.215 +				{ &dib0700_usb_id_table[54], NULL },
   4.216 +				{ NULL },
   4.217 +			},
   4.218 +			{   "Pinnacle PCTV Hybrid Stick Solo",
   4.219 +				{ &dib0700_usb_id_table[55], NULL },
   4.220 +				{ NULL },
   4.221 +			},
   4.222 +		},
   4.223 +		.rc_interval      = DEFAULT_RC_INTERVAL,
   4.224 +		.rc_key_map       = dib0700_rc_keys,
   4.225 +		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
   4.226 +		.rc_query         = dib0700_rc_query
   4.227  	},
   4.228  };
   4.229  
     5.1 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	Sat Sep 26 13:45:03 2009 -0300
     5.2 +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	Sun Oct 04 21:38:39 2009 -0400
     5.3 @@ -204,6 +204,8 @@
     5.4  #define USB_PID_PINNACLE_PCTV73A			0x0243
     5.5  #define USB_PID_PINNACLE_PCTV73ESE			0x0245
     5.6  #define USB_PID_PINNACLE_PCTV282E			0x0248
     5.7 +#define USB_PID_PINNACLE_PCTV340E			0x023d
     5.8 +#define USB_PID_PINNACLE_PCTV340E_SE			0x023e
     5.9  #define USB_PID_PIXELVIEW_SBTVD				0x5010
    5.10  #define USB_PID_PCTV_200E				0x020e
    5.11  #define USB_PID_PCTV_400E				0x020f
     6.1 --- a/linux/drivers/media/dvb/frontends/dib7000p.c	Sat Sep 26 13:45:03 2009 -0300
     6.2 +++ b/linux/drivers/media/dvb/frontends/dib7000p.c	Sun Oct 04 21:38:39 2009 -0400
     6.3 @@ -1401,6 +1401,11 @@
     6.4  	if (dib7000p_identify(st) != 0)
     6.5  		goto error;
     6.6  
     6.7 +	/* FIXME: make sure the dev.parent field is initialized, or else
     6.8 +	   request_firmware() will hit an OOPS (this should be moved somewhere
     6.9 +	   more common) */
    6.10 +	st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
    6.11 +
    6.12  	dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
    6.13  
    6.14  	dib7000p_demod_reset(st);
     7.1 --- a/linux/drivers/media/video/tuner-core.c	Sat Sep 26 13:45:03 2009 -0300
     7.2 +++ b/linux/drivers/media/video/tuner-core.c	Sun Oct 04 21:38:39 2009 -0400
     7.3 @@ -30,6 +30,7 @@
     7.4  #include "tuner-simple.h"
     7.5  #include "tda9887.h"
     7.6  #include "xc5000.h"
     7.7 +#include "xc4000.h"
     7.8  #include "tda18271.h"
     7.9  
    7.10  #define UNSET (-1U)
    7.11 @@ -325,6 +326,7 @@
    7.12  }
    7.13  
    7.14  static struct xc5000_config xc5000_cfg;
    7.15 +static struct xc4000_config xc4000_cfg;
    7.16  
    7.17  static void set_type(struct i2c_client *c, unsigned int type,
    7.18  		     unsigned int new_mode_mask, unsigned int new_config,
    7.19 @@ -435,6 +437,16 @@
    7.20  			goto attach_failed;
    7.21  		break;
    7.22  	}
    7.23 +	case TUNER_XC4000:
    7.24 +	{
    7.25 +		xc4000_cfg.i2c_address	  = t->i2c->addr;
    7.26 +		/* if_khz will be set when the digital dvb_attach() occurs */
    7.27 +		xc4000_cfg.if_khz	  = 0;
    7.28 +		if (!dvb_attach(xc4000_attach,
    7.29 +				&t->fe, t->i2c->adapter, &xc4000_cfg))
    7.30 +			goto attach_failed;
    7.31 +		break;
    7.32 +	}
    7.33  	case TUNER_NXP_TDA18271:
    7.34  	{
    7.35  		struct tda18271_config cfg = {
    7.36 @@ -472,12 +484,12 @@
    7.37  	if (t->mode_mask == T_UNINITIALIZED)
    7.38  		t->mode_mask = new_mode_mask;
    7.39  
    7.40 -	/* xc2028/3028 and xc5000 requires a firmware to be set-up later
    7.41 +	/* xc2028/3028 and xc5000/xc4000 requires a firmware to be set-up later
    7.42  	   trying to set a frequency here will just fail
    7.43  	   FIXME: better to move set_freq to the tuner code. This is needed
    7.44  	   on analog tuners for PLL to properly work
    7.45  	 */
    7.46 -	if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000)
    7.47 +	if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000 && t->type != TUNER_XC4000)
    7.48  		set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
    7.49  			    t->radio_freq : t->tv_freq);
    7.50  
     8.1 --- a/linux/include/media/tuner.h	Sat Sep 26 13:45:03 2009 -0300
     8.2 +++ b/linux/include/media/tuner.h	Sun Oct 04 21:38:39 2009 -0400
     8.3 @@ -129,6 +129,7 @@
     8.4  #define TUNER_PARTSNIC_PTI_5NF05	81
     8.5  #define TUNER_PHILIPS_CU1216L           82
     8.6  #define TUNER_NXP_TDA18271		83
     8.7 +#define TUNER_XC4000			84	/* Xceive Silicon Tuner */
     8.8  
     8.9  /* tv card specific */
    8.10  #define TDA9887_PRESENT 		(1<<0)
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/linux/drivers/media/common/tuners/xc4000.c	Sun Oct 04 21:38:39 2009 -0400
     9.3 @@ -0,0 +1,1618 @@
     9.4 +/*
     9.5 + *  Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
     9.6 + *
     9.7 + *  Copyright (c) 2007 Xceive Corporation
     9.8 + *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
     9.9 + *  Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
    9.10 + *  Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
    9.11 + *
    9.12 + *  This program is free software; you can redistribute it and/or modify
    9.13 + *  it under the terms of the GNU General Public License as published by
    9.14 + *  the Free Software Foundation; either version 2 of the License, or
    9.15 + *  (at your option) any later version.
    9.16 + *
    9.17 + *  This program is distributed in the hope that it will be useful,
    9.18 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.19 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.20 + *
    9.21 + *  GNU General Public License for more details.
    9.22 + *
    9.23 + *  You should have received a copy of the GNU General Public License
    9.24 + *  along with this program; if not, write to the Free Software
    9.25 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    9.26 + */
    9.27 +
    9.28 +#include <linux/module.h>
    9.29 +#include <linux/moduleparam.h>
    9.30 +#include <linux/videodev2.h>
    9.31 +#include <linux/delay.h>
    9.32 +#include <linux/dvb/frontend.h>
    9.33 +#include <linux/i2c.h>
    9.34 +#include <asm/unaligned.h>
    9.35 +
    9.36 +#include "dvb_frontend.h"
    9.37 +
    9.38 +#include "xc4000.h"
    9.39 +#include "tuner-i2c.h"
    9.40 +#include "tuner-xc2028-types.h"
    9.41 +
    9.42 +static int debug=1;
    9.43 +module_param(debug, int, 0644);
    9.44 +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
    9.45 +
    9.46 +static int no_poweroff;
    9.47 +module_param(no_poweroff, int, 0644);
    9.48 +MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
    9.49 +	"\t\t1 keep device energized and with tuner ready all the times.\n"
    9.50 +	"\t\tFaster, but consumes more power and keeps the device hotter");
    9.51 +
    9.52 +static DEFINE_MUTEX(xc4000_list_mutex);
    9.53 +static LIST_HEAD(hybrid_tuner_instance_list);
    9.54 +
    9.55 +#define dprintk(level, fmt, arg...) if (debug >= level) \
    9.56 +	printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
    9.57 +
    9.58 +#define XC4000_DEFAULT_FIRMWARE "xc4000-02.fw"
    9.59 +#define XC4000_DEFAULT_FIRMWARE_SIZE 18643
    9.60 +
    9.61 +
    9.62 +/* struct for storing firmware table */
    9.63 +struct firmware_description {
    9.64 +	unsigned int  type;
    9.65 +	v4l2_std_id   id;
    9.66 +	__u16         int_freq;
    9.67 +	unsigned char *ptr;
    9.68 +	unsigned int  size;
    9.69 +};
    9.70 +
    9.71 +struct firmware_properties {
    9.72 +	unsigned int	type;
    9.73 +	v4l2_std_id	id;
    9.74 +	v4l2_std_id	std_req;
    9.75 +	__u16		int_freq;
    9.76 +	unsigned int	scode_table;
    9.77 +	int 		scode_nr;
    9.78 +};
    9.79 +
    9.80 +struct xc4000_priv {
    9.81 +	struct tuner_i2c_props i2c_props;
    9.82 +	struct list_head hybrid_tuner_instance_list;
    9.83 +	struct firmware_description *firm;
    9.84 +	int			firm_size;
    9.85 +	__u16			firm_version;
    9.86 +	u32 if_khz;
    9.87 +	u32 freq_hz;
    9.88 +	u32 bandwidth;
    9.89 +	u8  video_standard;
    9.90 +	u8  rf_mode;
    9.91 +//	struct xc2028_ctrl	ctrl;
    9.92 +	struct firmware_properties cur_fw;
    9.93 +	__u16			hwmodel;
    9.94 +	__u16			hwvers;
    9.95 +};
    9.96 +
    9.97 +/* Misc Defines */
    9.98 +#define MAX_TV_STANDARD			23
    9.99 +#define XC_MAX_I2C_WRITE_LENGTH		64
   9.100 +
   9.101 +/* Signal Types */
   9.102 +#define XC_RF_MODE_AIR			0
   9.103 +#define XC_RF_MODE_CABLE		1
   9.104 +
   9.105 +/* Result codes */
   9.106 +#define XC_RESULT_SUCCESS		0
   9.107 +#define XC_RESULT_RESET_FAILURE		1
   9.108 +#define XC_RESULT_I2C_WRITE_FAILURE	2
   9.109 +#define XC_RESULT_I2C_READ_FAILURE	3
   9.110 +#define XC_RESULT_OUT_OF_RANGE		5
   9.111 +
   9.112 +/* Product id */
   9.113 +#define XC_PRODUCT_ID_FW_NOT_LOADED	0x2000
   9.114 +#define XC_PRODUCT_ID_FW_LOADED 	0x0FA0
   9.115 +
   9.116 +/* Registers (Write-only) */
   9.117 +#define XREG_INIT         0x00
   9.118 +#define XREG_VIDEO_MODE   0x01
   9.119 +#define XREG_AUDIO_MODE   0x02
   9.120 +#define XREG_RF_FREQ      0x03
   9.121 +#define XREG_D_CODE       0x04
   9.122 +#define XREG_DIRECTSITTING_MODE 0x05
   9.123 +#define XREG_SEEK_MODE    0x06
   9.124 +#define XREG_POWER_DOWN   0x08
   9.125 +#define XREG_SIGNALSOURCE 0x0A
   9.126 +#define XREG_AMPLITUDE    0x10
   9.127 +
   9.128 +/* Registers (Read-only) */
   9.129 +#define XREG_ADC_ENV      0x00
   9.130 +#define XREG_QUALITY      0x01
   9.131 +#define XREG_FRAME_LINES  0x02
   9.132 +#define XREG_HSYNC_FREQ   0x03
   9.133 +#define XREG_LOCK         0x04
   9.134 +#define XREG_FREQ_ERROR   0x05
   9.135 +#define XREG_SNR          0x06
   9.136 +#define XREG_VERSION      0x07
   9.137 +#define XREG_PRODUCT_ID   0x08
   9.138 +
   9.139 +/*
   9.140 +   Basic firmware description. This will remain with
   9.141 +   the driver for documentation purposes.
   9.142 +
   9.143 +   This represents an I2C firmware file encoded as a
   9.144 +   string of unsigned char. Format is as follows:
   9.145 +
   9.146 +   char[0  ]=len0_MSB  -> len = len_MSB * 256 + len_LSB
   9.147 +   char[1  ]=len0_LSB  -> length of first write transaction
   9.148 +   char[2  ]=data0 -> first byte to be sent
   9.149 +   char[3  ]=data1
   9.150 +   char[4  ]=data2
   9.151 +   char[   ]=...
   9.152 +   char[M  ]=dataN  -> last byte to be sent
   9.153 +   char[M+1]=len1_MSB  -> len = len_MSB * 256 + len_LSB
   9.154 +   char[M+2]=len1_LSB  -> length of second write transaction
   9.155 +   char[M+3]=data0
   9.156 +   char[M+4]=data1
   9.157 +   ...
   9.158 +   etc.
   9.159 +
   9.160 +   The [len] value should be interpreted as follows:
   9.161 +
   9.162 +   len= len_MSB _ len_LSB
   9.163 +   len=1111_1111_1111_1111   : End of I2C_SEQUENCE
   9.164 +   len=0000_0000_0000_0000   : Reset command: Do hardware reset
   9.165 +   len=0NNN_NNNN_NNNN_NNNN   : Normal transaction: number of bytes = {1:32767)
   9.166 +   len=1WWW_WWWW_WWWW_WWWW   : Wait command: wait for {1:32767} ms
   9.167 +
   9.168 +   For the RESET and WAIT commands, the two following bytes will contain
   9.169 +   immediately the length of the following transaction.
   9.170 +
   9.171 +*/
   9.172 +struct XC_TV_STANDARD {
   9.173 +	char *Name;
   9.174 +	u16 AudioMode;
   9.175 +	u16 VideoMode;
   9.176 +};
   9.177 +
   9.178 +/* Tuner standards */
   9.179 +#define MN_NTSC_PAL_BTSC	0
   9.180 +#define MN_NTSC_PAL_A2		1
   9.181 +#define MN_NTSC_PAL_EIAJ	2
   9.182 +#define MN_NTSC_PAL_Mono	3
   9.183 +#define BG_PAL_A2		4
   9.184 +#define BG_PAL_NICAM		5
   9.185 +#define BG_PAL_MONO		6
   9.186 +#define I_PAL_NICAM		7
   9.187 +#define I_PAL_NICAM_MONO	8
   9.188 +#define DK_PAL_A2		9
   9.189 +#define DK_PAL_NICAM		10
   9.190 +#define DK_PAL_MONO		11
   9.191 +#define DK_SECAM_A2DK1		12
   9.192 +#define DK_SECAM_A2LDK3 	13
   9.193 +#define DK_SECAM_A2MONO 	14
   9.194 +#define L_SECAM_NICAM		15
   9.195 +#define LC_SECAM_NICAM		16
   9.196 +#if 0
   9.197 +#define DTV6			17
   9.198 +#define DTV8			18
   9.199 +#define DTV7_8			19
   9.200 +#define DTV7			20
   9.201 +#endif
   9.202 +#define FM_Radio_INPUT2 	21
   9.203 +#define FM_Radio_INPUT1 	22
   9.204 +
   9.205 +/* WAS :
   9.206 +static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
   9.207 +	{"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
   9.208 +	{"M/N-NTSC/PAL-A2",   0x0600, 0x8020},
   9.209 +	{"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
   9.210 +	{"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
   9.211 +	{"B/G-PAL-A2",        0x0A00, 0x8049},
   9.212 +	{"B/G-PAL-NICAM",     0x0C04, 0x8049},
   9.213 +	{"B/G-PAL-MONO",      0x0878, 0x8059},
   9.214 +	{"I-PAL-NICAM",       0x1080, 0x8009},
   9.215 +	{"I-PAL-NICAM-MONO",  0x0E78, 0x8009},
   9.216 +	{"D/K-PAL-A2",        0x1600, 0x8009},
   9.217 +	{"D/K-PAL-NICAM",     0x0E80, 0x8009},
   9.218 +	{"D/K-PAL-MONO",      0x1478, 0x8009},
   9.219 +	{"D/K-SECAM-A2 DK1",  0x1200, 0x8009},
   9.220 +	{"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
   9.221 +	{"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
   9.222 +	{"L-SECAM-NICAM",     0x8E82, 0x0009},
   9.223 +	{"L'-SECAM-NICAM",    0x8E82, 0x4009},
   9.224 +	{"DTV6",              0x00C0, 0x8002},
   9.225 +	{"DTV8",              0x00C0, 0x800B},
   9.226 +	{"DTV7/8",            0x00C0, 0x801B},
   9.227 +	{"DTV7",              0x00C0, 0x8007},
   9.228 +	{"FM Radio-INPUT2",   0x9802, 0x9002},
   9.229 +	{"FM Radio-INPUT1",   0x0208, 0x9002}
   9.230 +};*/
   9.231 +
   9.232 +static struct XC_TV_STANDARD XC4000_Standard[MAX_TV_STANDARD] = {
   9.233 +	{"M/N-NTSC/PAL-BTSC", 0x0000, 0x8020},
   9.234 +	{"M/N-NTSC/PAL-A2",   0x0000, 0x8020},
   9.235 +	{"M/N-NTSC/PAL-EIAJ", 0x0040, 0x8020},
   9.236 +	{"M/N-NTSC/PAL-Mono", 0x0078, 0x8020},
   9.237 +	{"B/G-PAL-A2",        0x0000, 0x8059},
   9.238 +	{"B/G-PAL-NICAM",     0x0004, 0x8059},
   9.239 +	{"B/G-PAL-MONO",      0x0078, 0x8059},
   9.240 +	{"I-PAL-NICAM",       0x0080, 0x8049},
   9.241 +	{"I-PAL-NICAM-MONO",  0x0078, 0x8049},
   9.242 +	{"D/K-PAL-A2",        0x0000, 0x8049},
   9.243 +	{"D/K-PAL-NICAM",     0x0080, 0x8049},
   9.244 +	{"D/K-PAL-MONO",      0x0078, 0x8049},
   9.245 +	{"D/K-SECAM-A2 DK1",  0x0000, 0x8049},
   9.246 +	{"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049},
   9.247 +	{"D/K-SECAM-A2 MONO", 0x0078, 0x8049},
   9.248 +	{"L-SECAM-NICAM",     0x8080, 0x0009},
   9.249 +	{"L'-SECAM-NICAM",    0x8080, 0x4009},
   9.250 +	{"DTV6",              0x00C0, 0x8002},
   9.251 +	{"DTV8",              0x00C0, 0x800B},
   9.252 +	{"DTV7/8",            0x00C0, 0x801B},
   9.253 +	{"DTV7",              0x00C0, 0x8007},
   9.254 +	{"FM Radio-INPUT2",   0x0008, 0x9800},
   9.255 +	{"FM Radio-INPUT1",   0x0008, 0x9000}
   9.256 +};
   9.257 +
   9.258 +static int xc4000_is_firmware_loaded(struct dvb_frontend *fe);
   9.259 +static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
   9.260 +static int xc4000_TunerReset(struct dvb_frontend *fe);
   9.261 +
   9.262 +static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
   9.263 +{
   9.264 +	struct i2c_msg msg = { .addr = priv->i2c_props.addr,
   9.265 +			       .flags = 0, .buf = buf, .len = len };
   9.266 +	if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
   9.267 +		printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n", len);
   9.268 +		if (len == 4) {
   9.269 +			printk("bytes %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
   9.270 +		}
   9.271 +		return XC_RESULT_I2C_WRITE_FAILURE;
   9.272 +	}
   9.273 +	return XC_RESULT_SUCCESS;
   9.274 +}
   9.275 +
   9.276 +/* This routine is never used because the only time we read data from the
   9.277 +   i2c bus is when we read registers, and we want that to be an atomic i2c
   9.278 +   transaction in case we are on a multi-master bus */
   9.279 +#if 0
   9.280 +static int xc_read_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
   9.281 +{
   9.282 +	struct i2c_msg msg = { .addr = priv->i2c_props.addr,
   9.283 +		.flags = I2C_M_RD, .buf = buf, .len = len };
   9.284 +
   9.285 +	if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
   9.286 +		printk(KERN_ERR "xc4000 I2C read failed (len=%i)\n", len);
   9.287 +		return -EREMOTEIO;
   9.288 +	}
   9.289 +	return 0;
   9.290 +}
   9.291 +#endif
   9.292 +
   9.293 +static void xc_wait(int wait_ms)
   9.294 +{
   9.295 +	msleep(wait_ms);
   9.296 +}
   9.297 +
   9.298 +static int xc4000_TunerReset(struct dvb_frontend *fe)
   9.299 +{
   9.300 +	struct xc4000_priv *priv = fe->tuner_priv;
   9.301 +	int ret;
   9.302 +
   9.303 +	dprintk(1, "%s()\n", __func__);
   9.304 +
   9.305 +	if (fe->callback) {
   9.306 +		ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
   9.307 +					   fe->dvb->priv :
   9.308 +					   priv->i2c_props.adap->algo_data,
   9.309 +					   DVB_FRONTEND_COMPONENT_TUNER,
   9.310 +					   XC4000_TUNER_RESET, 0);
   9.311 +		if (ret) {
   9.312 +			printk(KERN_ERR "xc4000: reset failed\n");
   9.313 +			return XC_RESULT_RESET_FAILURE;
   9.314 +		}
   9.315 +	} else {
   9.316 +		printk(KERN_ERR "xc4000: no tuner reset callback function, fatal\n");
   9.317 +		return XC_RESULT_RESET_FAILURE;
   9.318 +	}
   9.319 +	return XC_RESULT_SUCCESS;
   9.320 +}
   9.321 +
   9.322 +static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
   9.323 +{
   9.324 +	u8 buf[4];
   9.325 +	int result;
   9.326 +
   9.327 +	buf[0] = (regAddr >> 8) & 0xFF;
   9.328 +	buf[1] = regAddr & 0xFF;
   9.329 +	buf[2] = (i2cData >> 8) & 0xFF;
   9.330 +	buf[3] = i2cData & 0xFF;
   9.331 +	result = xc_send_i2c_data(priv, buf, 4);
   9.332 +
   9.333 +	return result;
   9.334 +}
   9.335 +
   9.336 +static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
   9.337 +{
   9.338 +	struct xc4000_priv *priv = fe->tuner_priv;
   9.339 +
   9.340 +	int i, nbytes_to_send, result;
   9.341 +	unsigned int len, pos, index;
   9.342 +	u8 buf[XC_MAX_I2C_WRITE_LENGTH];
   9.343 +
   9.344 +	index = 0;
   9.345 +	while ((i2c_sequence[index] != 0xFF) ||
   9.346 +		(i2c_sequence[index + 1] != 0xFF)) {
   9.347 +		len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
   9.348 +		if (len == 0x0000) {
   9.349 +			/* RESET command */
   9.350 +			result = xc4000_TunerReset(fe);
   9.351 +			index += 2;
   9.352 +			if (result != XC_RESULT_SUCCESS)
   9.353 +				return result;
   9.354 +		} else if (len & 0x8000) {
   9.355 +			/* WAIT command */
   9.356 +			xc_wait(len & 0x7FFF);
   9.357 +			index += 2;
   9.358 +		} else {
   9.359 +			/* Send i2c data whilst ensuring individual transactions
   9.360 +			 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
   9.361 +			 */
   9.362 +			index += 2;
   9.363 +			buf[0] = i2c_sequence[index];
   9.364 +			buf[1] = i2c_sequence[index + 1];
   9.365 +			pos = 2;
   9.366 +			while (pos < len) {
   9.367 +				if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
   9.368 +					nbytes_to_send =
   9.369 +						XC_MAX_I2C_WRITE_LENGTH;
   9.370 +				else
   9.371 +					nbytes_to_send = (len - pos + 2);
   9.372 +				for (i = 2; i < nbytes_to_send; i++) {
   9.373 +					buf[i] = i2c_sequence[index + pos +
   9.374 +						i - 2];
   9.375 +				}
   9.376 +				result = xc_send_i2c_data(priv, buf,
   9.377 +					nbytes_to_send);
   9.378 +
   9.379 +				if (result != XC_RESULT_SUCCESS)
   9.380 +					return result;
   9.381 +
   9.382 +				pos += nbytes_to_send - 2;
   9.383 +			}
   9.384 +			index += len;
   9.385 +		}
   9.386 +	}
   9.387 +	return XC_RESULT_SUCCESS;
   9.388 +}
   9.389 +
   9.390 +static int xc_SetTVStandard(struct xc4000_priv *priv,
   9.391 +	u16 VideoMode, u16 AudioMode)
   9.392 +{
   9.393 +	int ret;
   9.394 +	dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
   9.395 +	dprintk(1, "%s() Standard = %s\n",
   9.396 +		__func__,
   9.397 +		XC4000_Standard[priv->video_standard].Name);
   9.398 +
   9.399 +	ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
   9.400 +	if (ret == XC_RESULT_SUCCESS)
   9.401 +		ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
   9.402 +
   9.403 +	return ret;
   9.404 +}
   9.405 +
   9.406 +static int xc_SetSignalSource(struct xc4000_priv *priv, u16 rf_mode)
   9.407 +{
   9.408 +	dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
   9.409 +		rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
   9.410 +
   9.411 +	if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
   9.412 +		rf_mode = XC_RF_MODE_CABLE;
   9.413 +		printk(KERN_ERR
   9.414 +			"%s(), Invalid mode, defaulting to CABLE",
   9.415 +			__func__);
   9.416 +	}
   9.417 +	return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
   9.418 +}
   9.419 +
   9.420 +static const struct dvb_tuner_ops xc4000_tuner_ops;
   9.421 +
   9.422 +static int xc_set_RF_frequency(struct xc4000_priv *priv, u32 freq_hz)
   9.423 +{
   9.424 +	u16 freq_code;
   9.425 +
   9.426 +	dprintk(1, "%s(%u)\n", __func__, freq_hz);
   9.427 +
   9.428 +	if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
   9.429 +		(freq_hz < xc4000_tuner_ops.info.frequency_min))
   9.430 +		return XC_RESULT_OUT_OF_RANGE;
   9.431 +
   9.432 +	freq_code = (u16)(freq_hz / 15625);
   9.433 +
   9.434 +	/* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
   9.435 +	   FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
   9.436 +	   only be used for fast scanning for channel lock) */
   9.437 +	return xc_write_reg(priv, XREG_RF_FREQ, freq_code); /* WAS: XREG_FINERFREQ */
   9.438 +}
   9.439 +
   9.440 +#if 0
   9.441 +/* We'll probably need these for analog support */
   9.442 +static int xc_set_Xtal_frequency(struct xc4000_priv *priv, u32 xtalFreqInKHz)
   9.443 +{
   9.444 +	u16 xtalRatio = (32000 * 0x8000)/xtalFreqInKHz;
   9.445 +	return xc_write_reg(priv, XREG_XTALFREQ, xtalRatio);
   9.446 +}
   9.447 +#endif
   9.448 +
   9.449 +static int xc_get_ADC_Envelope(struct xc4000_priv *priv, u16 *adc_envelope)
   9.450 +{
   9.451 +	return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
   9.452 +}
   9.453 +
   9.454 +static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
   9.455 +{
   9.456 +	int result;
   9.457 +	u16 regData;
   9.458 +	u32 tmp;
   9.459 +
   9.460 +	result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
   9.461 +	if (result != XC_RESULT_SUCCESS)
   9.462 +		return result;
   9.463 +
   9.464 +	tmp = (u32)regData;
   9.465 +	(*freq_error_hz) = (tmp * 15625) / 1000;
   9.466 +	return result;
   9.467 +}
   9.468 +
   9.469 +static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
   9.470 +{
   9.471 +	return xc4000_readreg(priv, XREG_LOCK, lock_status);
   9.472 +}
   9.473 +
   9.474 +static int xc_get_version(struct xc4000_priv *priv,
   9.475 +	u8 *hw_majorversion, u8 *hw_minorversion,
   9.476 +	u8 *fw_majorversion, u8 *fw_minorversion)
   9.477 +{
   9.478 +	u16 data;
   9.479 +	int result;
   9.480 +
   9.481 +	result = xc4000_readreg(priv, XREG_VERSION, &data);
   9.482 +	if (result != XC_RESULT_SUCCESS)
   9.483 +		return result;
   9.484 +
   9.485 +	(*hw_majorversion) = (data >> 12) & 0x0F;
   9.486 +	(*hw_minorversion) = (data >>  8) & 0x0F;
   9.487 +	(*fw_majorversion) = (data >>  4) & 0x0F;
   9.488 +	(*fw_minorversion) = data & 0x0F;
   9.489 +
   9.490 +	return 0;
   9.491 +}
   9.492 +
   9.493 +/* WAS THERE
   9.494 +static int xc_get_buildversion(struct xc4000_priv *priv, u16 *buildrev)
   9.495 +{
   9.496 +	return xc4000_readreg(priv, XREG_BUILD, buildrev);
   9.497 +}*/
   9.498 +
   9.499 +static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
   9.500 +{
   9.501 +	u16 regData;
   9.502 +	int result;
   9.503 +
   9.504 +	result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
   9.505 +	if (result != XC_RESULT_SUCCESS)
   9.506 +		return result;
   9.507 +
   9.508 +	(*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
   9.509 +	return result;
   9.510 +}
   9.511 +
   9.512 +static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
   9.513 +{
   9.514 +	return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
   9.515 +}
   9.516 +
   9.517 +static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
   9.518 +{
   9.519 +	return xc4000_readreg(priv, XREG_QUALITY, quality);
   9.520 +}
   9.521 +
   9.522 +static u16 WaitForLock(struct xc4000_priv *priv)
   9.523 +{
   9.524 +	u16 lockState = 0;
   9.525 +	int watchDogCount = 40;
   9.526 +
   9.527 +	while ((lockState == 0) && (watchDogCount > 0)) {
   9.528 +		xc_get_lock_status(priv, &lockState);
   9.529 +		if (lockState != 1) {
   9.530 +			xc_wait(5);
   9.531 +			watchDogCount--;
   9.532 +		}
   9.533 +	}
   9.534 +	return lockState;
   9.535 +}
   9.536 +
   9.537 +#define XC_TUNE_ANALOG  0
   9.538 +#define XC_TUNE_DIGITAL 1
   9.539 +static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
   9.540 +{
   9.541 +	int found = 0;
   9.542 +
   9.543 +	dprintk(1, "%s(%u)\n", __func__, freq_hz);
   9.544 +
   9.545 +	if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
   9.546 +		return 0;
   9.547 +
   9.548 +	if (mode == XC_TUNE_ANALOG) {
   9.549 +		if (WaitForLock(priv) == 1)
   9.550 +			found = 1;
   9.551 +	}
   9.552 +
   9.553 +	return found;
   9.554 +}
   9.555 +
   9.556 +static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
   9.557 +{
   9.558 +	u8 buf[2] = { reg >> 8, reg & 0xff };
   9.559 +	u8 bval[2] = { 0, 0 };
   9.560 +	struct i2c_msg msg[2] = {
   9.561 +		{ .addr = priv->i2c_props.addr,
   9.562 +			.flags = 0, .buf = &buf[0], .len = 2 },
   9.563 +		{ .addr = priv->i2c_props.addr,
   9.564 +			.flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
   9.565 +	};
   9.566 +
   9.567 +	if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
   9.568 +		printk(KERN_WARNING "xc4000: I2C read failed\n");
   9.569 +		return -EREMOTEIO;
   9.570 +	}
   9.571 +
   9.572 +	*val = (bval[0] << 8) | bval[1];
   9.573 +	return XC_RESULT_SUCCESS;
   9.574 +}
   9.575 +
   9.576 +#define dump_firm_type(t) 	dump_firm_type_and_int_freq(t, 0)
   9.577 +static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
   9.578 +{
   9.579 +	 if (type & BASE)
   9.580 +		printk("BASE ");
   9.581 +	 if (type & INIT1)
   9.582 +		printk("INIT1 ");
   9.583 +	 if (type & F8MHZ)
   9.584 +		printk("F8MHZ ");
   9.585 +	 if (type & MTS)
   9.586 +		printk("MTS ");
   9.587 +	 if (type & D2620)
   9.588 +		printk("D2620 ");
   9.589 +	 if (type & D2633)
   9.590 +		printk("D2633 ");
   9.591 +	 if (type & DTV6)
   9.592 +		printk("DTV6 ");
   9.593 +	 if (type & QAM)
   9.594 +		printk("QAM ");
   9.595 +	 if (type & DTV7)
   9.596 +		printk("DTV7 ");
   9.597 +	 if (type & DTV78)
   9.598 +		printk("DTV78 ");
   9.599 +	 if (type & DTV8)
   9.600 +		printk("DTV8 ");
   9.601 +	 if (type & FM)
   9.602 +		printk("FM ");
   9.603 +	 if (type & INPUT1)
   9.604 +		printk("INPUT1 ");
   9.605 +	 if (type & LCD)
   9.606 +		printk("LCD ");
   9.607 +	 if (type & NOGD)
   9.608 +		printk("NOGD ");
   9.609 +	 if (type & MONO)
   9.610 +		printk("MONO ");
   9.611 +	 if (type & ATSC)
   9.612 +		printk("ATSC ");
   9.613 +	 if (type & IF)
   9.614 +		printk("IF ");
   9.615 +	 if (type & LG60)
   9.616 +		printk("LG60 ");
   9.617 +	 if (type & ATI638)
   9.618 +		printk("ATI638 ");
   9.619 +	 if (type & OREN538)
   9.620 +		printk("OREN538 ");
   9.621 +	 if (type & OREN36)
   9.622 +		printk("OREN36 ");
   9.623 +	 if (type & TOYOTA388)
   9.624 +		printk("TOYOTA388 ");
   9.625 +	 if (type & TOYOTA794)
   9.626 +		printk("TOYOTA794 ");
   9.627 +	 if (type & DIBCOM52)
   9.628 +		printk("DIBCOM52 ");
   9.629 +	 if (type & ZARLINK456)
   9.630 +		printk("ZARLINK456 ");
   9.631 +	 if (type & CHINA)
   9.632 +		printk("CHINA ");
   9.633 +	 if (type & F6MHZ)
   9.634 +		printk("F6MHZ ");
   9.635 +	 if (type & INPUT2)
   9.636 +		printk("INPUT2 ");
   9.637 +	 if (type & SCODE)
   9.638 +		printk("SCODE ");
   9.639 +	 if (type & HAS_IF)
   9.640 +		printk("HAS_IF_%d ", int_freq);
   9.641 +}
   9.642 +
   9.643 +static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
   9.644 +			 v4l2_std_id *id)
   9.645 +{
   9.646 +	struct xc4000_priv *priv = fe->tuner_priv;
   9.647 +	int                 i, best_i = -1, best_nr_matches = 0;
   9.648 +	unsigned int        type_mask = 0;
   9.649 +
   9.650 +	printk("%s called, want type=", __func__);
   9.651 +	if (debug) {
   9.652 +		dump_firm_type(type);
   9.653 +		printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
   9.654 +	}
   9.655 +
   9.656 +	if (!priv->firm) {
   9.657 +		printk("Error! firmware not loaded\n");
   9.658 +		return -EINVAL;
   9.659 +	}
   9.660 +
   9.661 +	if (((type & ~SCODE) == 0) && (*id == 0))
   9.662 +		*id = V4L2_STD_PAL;
   9.663 +
   9.664 +	if (type & BASE)
   9.665 +		type_mask = BASE_TYPES;
   9.666 +	else if (type & SCODE) {
   9.667 +		type &= SCODE_TYPES;
   9.668 +		type_mask = SCODE_TYPES & ~HAS_IF;
   9.669 +	} else if (type & DTV_TYPES)
   9.670 +		type_mask = DTV_TYPES;
   9.671 +	else if (type & STD_SPECIFIC_TYPES)
   9.672 +		type_mask = STD_SPECIFIC_TYPES;
   9.673 +
   9.674 +	type &= type_mask;
   9.675 +
   9.676 +	if (!(type & SCODE))
   9.677 +		type_mask = ~0;
   9.678 +
   9.679 +	/* Seek for exact match */
   9.680 +	for (i = 0; i < priv->firm_size; i++) {
   9.681 +		if ((type == (priv->firm[i].type & type_mask)) &&
   9.682 +		    (*id == priv->firm[i].id))
   9.683 +			goto found;
   9.684 +	}
   9.685 +
   9.686 +	/* Seek for generic video standard match */
   9.687 +	for (i = 0; i < priv->firm_size; i++) {
   9.688 +		v4l2_std_id match_mask;
   9.689 +		int nr_matches;
   9.690 +
   9.691 +		if (type != (priv->firm[i].type & type_mask))
   9.692 +			continue;
   9.693 +
   9.694 +		match_mask = *id & priv->firm[i].id;
   9.695 +		if (!match_mask)
   9.696 +			continue;
   9.697 +
   9.698 +		if ((*id & match_mask) == *id)
   9.699 +			goto found; /* Supports all the requested standards */
   9.700 +
   9.701 +		nr_matches = hweight64(match_mask);
   9.702 +		if (nr_matches > best_nr_matches) {
   9.703 +			best_nr_matches = nr_matches;
   9.704 +			best_i = i;
   9.705 +		}
   9.706 +	}
   9.707 +
   9.708 +	if (best_nr_matches > 0) {
   9.709 +		printk("Selecting best matching firmware (%d bits) for "
   9.710 +			  "type=", best_nr_matches);
   9.711 +//		dump_firm_type(type);
   9.712 +		printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
   9.713 +		i = best_i;
   9.714 +		goto found;
   9.715 +	}
   9.716 +
   9.717 +	/*FIXME: Would make sense to seek for type "hint" match ? */
   9.718 +
   9.719 +	i = -ENOENT;
   9.720 +	goto ret;
   9.721 +
   9.722 +found:
   9.723 +	*id = priv->firm[i].id;
   9.724 +
   9.725 +ret:
   9.726 +	printk("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
   9.727 +	if (debug) {
   9.728 +		dump_firm_type(type);
   9.729 +		printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
   9.730 +		if (i < 0)
   9.731 +			dump_stack();
   9.732 +	}
   9.733 +	return i;
   9.734 +}
   9.735 +
   9.736 +static int load_firmware(struct dvb_frontend *fe, unsigned int type,
   9.737 +			 v4l2_std_id *id)
   9.738 +{
   9.739 +	struct xc4000_priv *priv = fe->tuner_priv;
   9.740 +	int                pos, rc;
   9.741 +	unsigned char      *p;
   9.742 +
   9.743 +	printk("%s called\n", __func__);
   9.744 +
   9.745 +	pos = seek_firmware(fe, type, id);
   9.746 +	if (pos < 0)
   9.747 +		return pos;
   9.748 +
   9.749 +	printk("Loading firmware for type=");
   9.750 +//	dump_firm_type(priv->firm[pos].type);
   9.751 +	printk("(%x), id %016llx.\n", priv->firm[pos].type,
   9.752 +	       (unsigned long long)*id);
   9.753 +
   9.754 +	p = priv->firm[pos].ptr;
   9.755 +	printk("firmware length = %d\n", priv->firm[pos].size);
   9.756 +
   9.757 +	rc = xc_load_i2c_sequence(fe, p);
   9.758 +
   9.759 +	return rc;
   9.760 +}
   9.761 +
   9.762 +static int xc4000_fwupload(struct dvb_frontend *fe)
   9.763 +{
   9.764 +	struct xc4000_priv *priv = fe->tuner_priv;
   9.765 +	const struct firmware *fw   = NULL;
   9.766 +	const unsigned char   *p, *endp;
   9.767 +	int                   rc = 0;
   9.768 +	int		      n, n_array;
   9.769 +	char		      name[33];
   9.770 +	char		      *fname;
   9.771 +
   9.772 +	printk("%s called\n", __func__);
   9.773 +
   9.774 +	fname = XC4000_DEFAULT_FIRMWARE;
   9.775 +
   9.776 +	printk("Reading firmware %s\n",  fname);
   9.777 +	rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
   9.778 +	if (rc < 0) {
   9.779 +		if (rc == -ENOENT)
   9.780 +			printk("Error: firmware %s not found.\n",
   9.781 +				   fname);
   9.782 +		else
   9.783 +			printk("Error %d while requesting firmware %s \n",
   9.784 +				   rc, fname);
   9.785 +
   9.786 +		return rc;
   9.787 +	}
   9.788 +	p = fw->data;
   9.789 +	endp = p + fw->size;
   9.790 +
   9.791 +	if (fw->size < sizeof(name) - 1 + 2 + 2) {
   9.792 +		printk("Error: firmware file %s has invalid size!\n",
   9.793 +			  fname);
   9.794 +		goto corrupt;
   9.795 +	}
   9.796 +
   9.797 +	memcpy(name, p, sizeof(name) - 1);
   9.798 +	name[sizeof(name) - 1] = 0;
   9.799 +	p += sizeof(name) - 1;
   9.800 +
   9.801 +	priv->firm_version = get_unaligned_le16(p);
   9.802 +	p += 2;
   9.803 +
   9.804 +	n_array = get_unaligned_le16(p);
   9.805 +	p += 2;
   9.806 +
   9.807 +	printk("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
   9.808 +		   n_array, fname, name,
   9.809 +		   priv->firm_version >> 8, priv->firm_version & 0xff);
   9.810 +
   9.811 +	priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
   9.812 +	if (priv->firm == NULL) {
   9.813 +		printk("Not enough memory to load firmware file.\n");
   9.814 +		rc = -ENOMEM;
   9.815 +		goto err;
   9.816 +	}
   9.817 +	priv->firm_size = n_array;
   9.818 +
   9.819 +	n = -1;
   9.820 +	while (p < endp) {
   9.821 +		__u32 type, size;
   9.822 +		v4l2_std_id id;
   9.823 +		__u16 int_freq = 0;
   9.824 +
   9.825 +		n++;
   9.826 +		if (n >= n_array) {
   9.827 +			printk("More firmware images in file than "
   9.828 +				  "were expected!\n");
   9.829 +			goto corrupt;
   9.830 +		}
   9.831 +
   9.832 +		/* Checks if there's enough bytes to read */
   9.833 +		if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
   9.834 +			goto header;
   9.835 +
   9.836 +		type = get_unaligned_le32(p);
   9.837 +		p += sizeof(type);
   9.838 +
   9.839 +		id = get_unaligned_le64(p);
   9.840 +		p += sizeof(id);
   9.841 +
   9.842 +		if (type & HAS_IF) {
   9.843 +			int_freq = get_unaligned_le16(p);
   9.844 +			p += sizeof(int_freq);
   9.845 +			if (endp - p < sizeof(size))
   9.846 +				goto header;
   9.847 +		}
   9.848 +
   9.849 +		size = get_unaligned_le32(p);
   9.850 +		p += sizeof(size);
   9.851 +
   9.852 +		if (!size || size > endp - p) {
   9.853 +			printk("Firmware type ");
   9.854 +//			dump_firm_type(type);
   9.855 +			printk("(%x), id %llx is corrupted "
   9.856 +			       "(size=%d, expected %d)\n",
   9.857 +			       type, (unsigned long long)id,
   9.858 +			       (unsigned)(endp - p), size);
   9.859 +			goto corrupt;
   9.860 +		}
   9.861 +
   9.862 +		priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
   9.863 +		if (priv->firm[n].ptr == NULL) {
   9.864 +			printk("Not enough memory to load firmware file.\n");
   9.865 +			rc = -ENOMEM;
   9.866 +			goto err;
   9.867 +		}
   9.868 +
   9.869 +		if (debug) {
   9.870 +			printk("Reading firmware type ");
   9.871 +			dump_firm_type_and_int_freq(type, int_freq);
   9.872 +			printk("(%x), id %llx, size=%d.\n",
   9.873 +			       type, (unsigned long long)id, size);
   9.874 +		}
   9.875 +
   9.876 +		memcpy(priv->firm[n].ptr, p, size);
   9.877 +		priv->firm[n].type = type;
   9.878 +		priv->firm[n].id   = id;
   9.879 +		priv->firm[n].size = size;
   9.880 +		priv->firm[n].int_freq = int_freq;
   9.881 +
   9.882 +		p += size;
   9.883 +	}
   9.884 +
   9.885 +	if (n + 1 != priv->firm_size) {
   9.886 +		printk("Firmware file is incomplete!\n");
   9.887 +		goto corrupt;
   9.888 +	}
   9.889 +
   9.890 +	goto done;
   9.891 +
   9.892 +header:
   9.893 +	printk("Firmware header is incomplete!\n");
   9.894 +corrupt:
   9.895 +	rc = -EINVAL;
   9.896 +	printk("Error: firmware file is corrupted!\n");
   9.897 +
   9.898 +err:
   9.899 +	printk("Releasing partially loaded firmware file.\n");
   9.900 +//	free_firmware(priv);
   9.901 +
   9.902 +done:
   9.903 +	release_firmware(fw);
   9.904 +	if (rc == 0)
   9.905 +		printk("Firmware files loaded.\n");
   9.906 +
   9.907 +	return rc;
   9.908 +}
   9.909 +
   9.910 +static int load_scode(struct dvb_frontend *fe, unsigned int type,
   9.911 +			 v4l2_std_id *id, __u16 int_freq, int scode)
   9.912 +{
   9.913 +	struct xc4000_priv *priv = fe->tuner_priv;
   9.914 +	int                pos, rc;
   9.915 +	unsigned char	   *p;
   9.916 +	u8 scode_buf[13];
   9.917 +	u8 indirect_mode[5];
   9.918 +
   9.919 +	dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
   9.920 +
   9.921 +	if (!int_freq) {
   9.922 +		pos = seek_firmware(fe, type, id);
   9.923 +		if (pos < 0)
   9.924 +			return pos;
   9.925 +	} else {
   9.926 +		for (pos = 0; pos < priv->firm_size; pos++) {
   9.927 +			if ((priv->firm[pos].int_freq == int_freq) &&
   9.928 +			    (priv->firm[pos].type & HAS_IF))
   9.929 +				break;
   9.930 +		}
   9.931 +		if (pos == priv->firm_size)
   9.932 +			return -ENOENT;
   9.933 +	}
   9.934 +
   9.935 +	p = priv->firm[pos].ptr;
   9.936 +
   9.937 +	if (priv->firm[pos].type & HAS_IF) {
   9.938 +		if (priv->firm[pos].size != 12 * 16 || scode >= 16)
   9.939 +			return -EINVAL;
   9.940 +		p += 12 * scode;
   9.941 +	} else {
   9.942 +		/* 16 SCODE entries per file; each SCODE entry is 12 bytes and
   9.943 +		 * has a 2-byte size header in the firmware format. */
   9.944 +		if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
   9.945 +		    le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
   9.946 +			return -EINVAL;
   9.947 +		p += 14 * scode + 2;
   9.948 +	}
   9.949 +
   9.950 +	tuner_info("Loading SCODE for type=");
   9.951 +	dump_firm_type_and_int_freq(priv->firm[pos].type,
   9.952 +				    priv->firm[pos].int_freq);
   9.953 +	printk("(%x), id %016llx.\n", priv->firm[pos].type,
   9.954 +	       (unsigned long long)*id);
   9.955 +
   9.956 +	scode_buf[0] = 0x00;
   9.957 +	memcpy(&scode_buf[1], p, 12);
   9.958 +
   9.959 +	/* Enter direct-mode */
   9.960 +	rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
   9.961 +	if (rc < 0) {
   9.962 +		printk("failed to put device into direct mode!\n");
   9.963 +		return -EIO;
   9.964 +	}
   9.965 +
   9.966 +	rc = xc_send_i2c_data(priv, scode_buf, 13);
   9.967 +	if (rc != XC_RESULT_SUCCESS) {
   9.968 +		/* Even if the send failed, make sure we set back to indirect
   9.969 +		   mode */
   9.970 +		printk("Failed to set scode %d\n", rc);
   9.971 +	}
   9.972 +
   9.973 +	/* Switch back to indirect-mode */
   9.974 +	memset(indirect_mode, 0, sizeof(indirect_mode));
   9.975 +	indirect_mode[4] = 0x88;
   9.976 +	xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
   9.977 +	msleep(10);
   9.978 +
   9.979 +	return 0;
   9.980 +}
   9.981 +
   9.982 +static int check_firmware(struct dvb_frontend *fe, unsigned int type,
   9.983 +			  v4l2_std_id std, __u16 int_freq)
   9.984 +{
   9.985 +	struct xc4000_priv         *priv = fe->tuner_priv;
   9.986 +	struct firmware_properties new_fw;
   9.987 +	int			   rc = 0, is_retry = 0;
   9.988 +	u16			   version, hwmodel;
   9.989 +	v4l2_std_id		   std0;
   9.990 +	u8 		   	   hw_major, hw_minor, fw_major, fw_minor;
   9.991 +
   9.992 +	dprintk(1, "%s called\n", __func__);
   9.993 +
   9.994 +	if (!priv->firm) {
   9.995 +		rc = xc4000_fwupload(fe);
   9.996 +		if (rc < 0)
   9.997 +			return rc;
   9.998 +	}
   9.999 +
  9.1000 +#ifdef DJH_DEBUG
  9.1001 +	if (priv->ctrl.mts && !(type & FM))
  9.1002 +		type |= MTS;
  9.1003 +#endif
  9.1004 +
  9.1005 +retry:
  9.1006 +	new_fw.type = type;
  9.1007 +	new_fw.id = std;
  9.1008 +	new_fw.std_req = std;
  9.1009 +//	new_fw.scode_table = SCODE | priv->ctrl.scode_table;
  9.1010 +	new_fw.scode_table = SCODE;
  9.1011 +	new_fw.scode_nr = 0;
  9.1012 +	new_fw.int_freq = int_freq;
  9.1013 +
  9.1014 +	dprintk(1, "checking firmware, user requested type=");
  9.1015 +	if (debug) {
  9.1016 +		dump_firm_type(new_fw.type);
  9.1017 +		printk("(%x), id %016llx, ", new_fw.type,
  9.1018 +		       (unsigned long long)new_fw.std_req);
  9.1019 +		if (!int_freq) {
  9.1020 +			printk("scode_tbl ");
  9.1021 +#ifdef DJH_DEBUG
  9.1022 +			dump_firm_type(priv->ctrl.scode_table);
  9.1023 +			printk("(%x), ", priv->ctrl.scode_table);
  9.1024 +#endif
  9.1025 +		} else
  9.1026 +			printk("int_freq %d, ", new_fw.int_freq);
  9.1027 +		printk("scode_nr %d\n", new_fw.scode_nr);
  9.1028 +	}
  9.1029 +
  9.1030 +	/* No need to reload base firmware if it matches */
  9.1031 +	if (((BASE | new_fw.type) & BASE_TYPES) ==
  9.1032 +	    (priv->cur_fw.type & BASE_TYPES)) {
  9.1033 +		dprintk(1, "BASE firmware not changed.\n");
  9.1034 +		goto skip_base;
  9.1035 +	}
  9.1036 +
  9.1037 +	/* Updating BASE - forget about all currently loaded firmware */
  9.1038 +	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
  9.1039 +
  9.1040 +	/* Reset is needed before loading firmware */
  9.1041 +	rc = xc4000_TunerReset(fe);
  9.1042 +	if (rc < 0)
  9.1043 +		goto fail;
  9.1044 +
  9.1045 +	/* BASE firmwares are all std0 */
  9.1046 +	std0 = 0;
  9.1047 +	rc = load_firmware(fe, BASE | new_fw.type, &std0);
  9.1048 +	if (rc < 0) {
  9.1049 +		printk("Error %d while loading base firmware\n", rc);
  9.1050 +		goto fail;
  9.1051 +	}
  9.1052 +
  9.1053 +	/* Load INIT1, if needed */
  9.1054 +	dprintk(1, "Load init1 firmware, if exists\n");
  9.1055 +
  9.1056 +	rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
  9.1057 +	if (rc == -ENOENT)
  9.1058 +		rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
  9.1059 +				   &std0);
  9.1060 +	if (rc < 0 && rc != -ENOENT) {
  9.1061 +		tuner_err("Error %d while loading init1 firmware\n",
  9.1062 +			  rc);
  9.1063 +		goto fail;
  9.1064 +	}
  9.1065 +
  9.1066 +	printk("Done with init1\n");
  9.1067 +
  9.1068 +skip_base:
  9.1069 +	/*
  9.1070 +	 * No need to reload standard specific firmware if base firmware
  9.1071 +	 * was not reloaded and requested video standards have not changed.
  9.1072 +	 */
  9.1073 +	if (priv->cur_fw.type == (BASE | new_fw.type) &&
  9.1074 +	    priv->cur_fw.std_req == std) {
  9.1075 +		dprintk(1, "Std-specific firmware already loaded.\n");
  9.1076 +		goto skip_std_specific;
  9.1077 +	}
  9.1078 +
  9.1079 +	/* Reloading std-specific firmware forces a SCODE update */
  9.1080 +	priv->cur_fw.scode_table = 0;
  9.1081 +
  9.1082 +	/* Load the standard firmware */
  9.1083 +	rc = load_firmware(fe, new_fw.type, &new_fw.id);
  9.1084 +
  9.1085 +	if (rc < 0)
  9.1086 +		goto fail;
  9.1087 +
  9.1088 +skip_std_specific:
  9.1089 +	if (priv->cur_fw.scode_table == new_fw.scode_table &&
  9.1090 +	    priv->cur_fw.scode_nr == new_fw.scode_nr) {
  9.1091 +		dprintk(1, "SCODE firmware already loaded.\n");
  9.1092 +		goto check_device;
  9.1093 +	}
  9.1094 +
  9.1095 +	if (new_fw.type & FM)
  9.1096 +		goto check_device;
  9.1097 +
  9.1098 +	/* Load SCODE firmware, if exists */
  9.1099 +	rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
  9.1100 +			new_fw.int_freq, new_fw.scode_nr);
  9.1101 +	if (rc != XC_RESULT_SUCCESS)
  9.1102 +		dprintk(1, "load scode failed %d\n", rc);
  9.1103 +
  9.1104 +check_device:
  9.1105 +	rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
  9.1106 +
  9.1107 +	if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major, 
  9.1108 +			   &fw_minor) != XC_RESULT_SUCCESS) {
  9.1109 +		printk("Unable to read tuner registers.\n");
  9.1110 +		goto fail;
  9.1111 +	}
  9.1112 +
  9.1113 +	dprintk(1, "Device is Xceive %d version %d.%d, "
  9.1114 +		"firmware version %d.%d\n",
  9.1115 +		hwmodel, hw_major, hw_minor, fw_major, fw_minor);
  9.1116 +
  9.1117 +	/* Check firmware version against what we downloaded. */
  9.1118 +#ifdef DJH_DEBUG
  9.1119 +	if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
  9.1120 +		printk("Incorrect readback of firmware version %x.\n",
  9.1121 +		       (version & 0xff));
  9.1122 +		goto fail;
  9.1123 +	}
  9.1124 +#endif
  9.1125 +
  9.1126 +	/* Check that the tuner hardware model remains consistent over time. */
  9.1127 +	if (priv->hwmodel == 0 && hwmodel == 4000) {
  9.1128 +		priv->hwmodel = hwmodel;
  9.1129 +		priv->hwvers  = version & 0xff00;
  9.1130 +	} else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
  9.1131 +		   priv->hwvers != (version & 0xff00)) {
  9.1132 +		printk("Read invalid device hardware information - tuner "
  9.1133 +			  "hung?\n");
  9.1134 +		goto fail;
  9.1135 +	}
  9.1136 +
  9.1137 +	memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
  9.1138 +
  9.1139 +	/*
  9.1140 +	 * By setting BASE in cur_fw.type only after successfully loading all
  9.1141 +	 * firmwares, we can:
  9.1142 +	 * 1. Identify that BASE firmware with type=0 has been loaded;
  9.1143 +	 * 2. Tell whether BASE firmware was just changed the next time through.
  9.1144 +	 */
  9.1145 +	priv->cur_fw.type |= BASE;
  9.1146 +
  9.1147 +	return 0;
  9.1148 +
  9.1149 +fail:
  9.1150 +	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
  9.1151 +	if (!is_retry) {
  9.1152 +		msleep(50);
  9.1153 +		is_retry = 1;
  9.1154 +		dprintk(1, "Retrying firmware load\n");
  9.1155 +		goto retry;
  9.1156 +	}
  9.1157 +
  9.1158 +	if (rc == -ENOENT)
  9.1159 +		rc = -EINVAL;
  9.1160 +	return rc;
  9.1161 +}
  9.1162 +
  9.1163 +static void xc_debug_dump(struct xc4000_priv *priv)
  9.1164 +{
  9.1165 +	u16 adc_envelope;
  9.1166 +	u32 freq_error_hz = 0;
  9.1167 +	u16 lock_status;
  9.1168 +	u32 hsync_freq_hz = 0;
  9.1169 +	u16 frame_lines;
  9.1170 +	u16 quality;
  9.1171 +	u8 hw_majorversion = 0, hw_minorversion = 0;
  9.1172 +	u8 fw_majorversion = 0, fw_minorversion = 0;
  9.1173 +//	u16 fw_buildversion = 0;
  9.1174 +
  9.1175 +	/* Wait for stats to stabilize.
  9.1176 +	 * Frame Lines needs two frame times after initial lock
  9.1177 +	 * before it is valid.
  9.1178 +	 */
  9.1179 +	xc_wait(100);
  9.1180 +
  9.1181 +	xc_get_ADC_Envelope(priv,  &adc_envelope);
  9.1182 +	dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
  9.1183 +
  9.1184 +	xc_get_frequency_error(priv, &freq_error_hz);
  9.1185 +	dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
  9.1186 +
  9.1187 +	xc_get_lock_status(priv,  &lock_status);
  9.1188 +	dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
  9.1189 +		lock_status);
  9.1190 +
  9.1191 +	xc_get_version(priv,  &hw_majorversion, &hw_minorversion,
  9.1192 +		&fw_majorversion, &fw_minorversion);
  9.1193 +// WAS:
  9.1194 +//	xc_get_buildversion(priv,  &fw_buildversion);
  9.1195 +//	dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
  9.1196 +//		hw_majorversion, hw_minorversion,
  9.1197 +//		fw_majorversion, fw_minorversion, fw_buildversion);
  9.1198 +// NOW:
  9.1199 +	dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
  9.1200 +		hw_majorversion, hw_minorversion,
  9.1201 +		fw_majorversion, fw_minorversion);
  9.1202 +
  9.1203 +	xc_get_hsync_freq(priv,  &hsync_freq_hz);
  9.1204 +	dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
  9.1205 +
  9.1206 +	xc_get_frame_lines(priv,  &frame_lines);
  9.1207 +	dprintk(1, "*** Frame lines = %d\n", frame_lines);
  9.1208 +
  9.1209 +	xc_get_quality(priv,  &quality);
  9.1210 +	dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
  9.1211 +}
  9.1212 +
  9.1213 +static int xc4000_set_params(struct dvb_frontend *fe,
  9.1214 +	struct dvb_frontend_parameters *params)
  9.1215 +{
  9.1216 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1217 +	int ret;
  9.1218 +
  9.1219 +	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
  9.1220 +
  9.1221 +	/* FIXME: setup proper parameters */
  9.1222 +	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) {
  9.1223 +		return -EREMOTEIO;
  9.1224 +	}
  9.1225 +
  9.1226 +	if (fe->ops.info.type == FE_ATSC) {
  9.1227 +		dprintk(1, "%s() ATSC\n", __func__);
  9.1228 +		switch (params->u.vsb.modulation) {
  9.1229 +		case VSB_8:
  9.1230 +		case VSB_16:
  9.1231 +			dprintk(1, "%s() VSB modulation\n", __func__);
  9.1232 +			priv->rf_mode = XC_RF_MODE_AIR;
  9.1233 +			priv->freq_hz = params->frequency - 1750000;
  9.1234 +			priv->bandwidth = BANDWIDTH_6_MHZ;
  9.1235 +			priv->video_standard = DTV6;
  9.1236 +			break;
  9.1237 +		case QAM_64:
  9.1238 +		case QAM_256:
  9.1239 +		case QAM_AUTO:
  9.1240 +			dprintk(1, "%s() QAM modulation\n", __func__);
  9.1241 +			priv->rf_mode = XC_RF_MODE_CABLE;
  9.1242 +			priv->freq_hz = params->frequency - 1750000;
  9.1243 +			priv->bandwidth = BANDWIDTH_6_MHZ;
  9.1244 +			priv->video_standard = DTV6;
  9.1245 +			break;
  9.1246 +		default:
  9.1247 +			return -EINVAL;
  9.1248 +		}
  9.1249 +	} else if (fe->ops.info.type == FE_OFDM) {
  9.1250 +		dprintk(1, "%s() OFDM\n", __func__);
  9.1251 +		switch (params->u.ofdm.bandwidth) {
  9.1252 +		case BANDWIDTH_6_MHZ:
  9.1253 +			priv->bandwidth = BANDWIDTH_6_MHZ;
  9.1254 +			priv->video_standard = DTV6;
  9.1255 +			priv->freq_hz = params->frequency - 1750000;
  9.1256 +			break;
  9.1257 +		case BANDWIDTH_7_MHZ:
  9.1258 +			printk(KERN_ERR "xc4000 bandwidth 7MHz not supported\n");
  9.1259 +			return -EINVAL;
  9.1260 +		case BANDWIDTH_8_MHZ:
  9.1261 +			priv->bandwidth = BANDWIDTH_8_MHZ;
  9.1262 +			priv->video_standard = DTV8;
  9.1263 +			priv->freq_hz = params->frequency - 2750000;
  9.1264 +			break;
  9.1265 +		default:
  9.1266 +			printk(KERN_ERR "xc4000 bandwidth not set!\n");
  9.1267 +			return -EINVAL;
  9.1268 +		}
  9.1269 +		priv->rf_mode = XC_RF_MODE_AIR;
  9.1270 +	} else {
  9.1271 +		printk(KERN_ERR "xc4000 modulation type not supported!\n");
  9.1272 +		return -EINVAL;
  9.1273 +	}
  9.1274 +
  9.1275 +	dprintk(1, "%s() frequency=%d (compensated)\n",
  9.1276 +		__func__, priv->freq_hz);
  9.1277 +
  9.1278 +	ret = xc_SetSignalSource(priv, priv->rf_mode);
  9.1279 +	if (ret != XC_RESULT_SUCCESS) {
  9.1280 +		printk(KERN_ERR
  9.1281 +			"xc4000: xc_SetSignalSource(%d) failed\n",
  9.1282 +			priv->rf_mode);
  9.1283 +		return -EREMOTEIO;
  9.1284 +	}
  9.1285 +
  9.1286 +	/* DJH debug */
  9.1287 +	priv->video_standard = 18;
  9.1288 +
  9.1289 +	ret = xc_SetTVStandard(priv,
  9.1290 +		XC4000_Standard[priv->video_standard].VideoMode,
  9.1291 +		XC4000_Standard[priv->video_standard].AudioMode);
  9.1292 +	if (ret != XC_RESULT_SUCCESS) {
  9.1293 +		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
  9.1294 +		/* DJH - do not return when it fails... */
  9.1295 +		//return -EREMOTEIO;
  9.1296 +	}
  9.1297 +#ifdef DJH_DEBUG
  9.1298 +	ret = xc_set_IF_frequency(priv, priv->if_khz);
  9.1299 +	if (ret != XC_RESULT_SUCCESS) {
  9.1300 +		printk(KERN_ERR "xc4000: xc_Set_IF_frequency(%d) failed\n",
  9.1301 +		       priv->if_khz);
  9.1302 +		return -EIO;
  9.1303 +	}
  9.1304 +#endif
  9.1305 +	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
  9.1306 +
  9.1307 +	if (debug)
  9.1308 +		xc_debug_dump(priv);
  9.1309 +
  9.1310 +	return 0;
  9.1311 +}
  9.1312 +
  9.1313 +static int xc4000_is_firmware_loaded(struct dvb_frontend *fe)
  9.1314 +{
  9.1315 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1316 +	int ret;
  9.1317 +	u16 id;
  9.1318 +
  9.1319 +	ret = xc4000_readreg(priv, XREG_PRODUCT_ID, &id);
  9.1320 +	if (ret == XC_RESULT_SUCCESS) {
  9.1321 +		if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
  9.1322 +			ret = XC_RESULT_RESET_FAILURE;
  9.1323 +		else
  9.1324 +			ret = XC_RESULT_SUCCESS;
  9.1325 +	}
  9.1326 +
  9.1327 +	dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
  9.1328 +		ret == XC_RESULT_SUCCESS ? "True" : "False", id);
  9.1329 +	return ret;
  9.1330 +}
  9.1331 +
  9.1332 +static int xc4000_set_analog_params(struct dvb_frontend *fe,
  9.1333 +	struct analog_parameters *params)
  9.1334 +{
  9.1335 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1336 +	int ret;
  9.1337 +
  9.1338 +	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
  9.1339 +		__func__, params->frequency);
  9.1340 +
  9.1341 +	/* FIXME: setup proper parameters */
  9.1342 +	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) {
  9.1343 +		return -EREMOTEIO;
  9.1344 +	}
  9.1345 +
  9.1346 +	/* Fix me: it could be air. */
  9.1347 +	priv->rf_mode = params->mode;
  9.1348 +	if (params->mode > XC_RF_MODE_CABLE)
  9.1349 +		priv->rf_mode = XC_RF_MODE_CABLE;
  9.1350 +
  9.1351 +	/* params->frequency is in units of 62.5khz */
  9.1352 +	priv->freq_hz = params->frequency * 62500;
  9.1353 +
  9.1354 +	/* FIX ME: Some video standards may have several possible audio
  9.1355 +		   standards. We simply default to one of them here.
  9.1356 +	 */
  9.1357 +	if (params->std & V4L2_STD_MN) {
  9.1358 +		/* default to BTSC audio standard */
  9.1359 +		priv->video_standard = MN_NTSC_PAL_BTSC;
  9.1360 +		goto tune_channel;
  9.1361 +	}
  9.1362 +
  9.1363 +	if (params->std & V4L2_STD_PAL_BG) {
  9.1364 +		/* default to NICAM audio standard */
  9.1365 +		priv->video_standard = BG_PAL_NICAM;
  9.1366 +		goto tune_channel;
  9.1367 +	}
  9.1368 +
  9.1369 +	if (params->std & V4L2_STD_PAL_I) {
  9.1370 +		/* default to NICAM audio standard */
  9.1371 +		priv->video_standard = I_PAL_NICAM;
  9.1372 +		goto tune_channel;
  9.1373 +	}
  9.1374 +
  9.1375 +	if (params->std & V4L2_STD_PAL_DK) {
  9.1376 +		/* default to NICAM audio standard */
  9.1377 +		priv->video_standard = DK_PAL_NICAM;
  9.1378 +		goto tune_channel;
  9.1379 +	}
  9.1380 +
  9.1381 +	if (params->std & V4L2_STD_SECAM_DK) {
  9.1382 +		/* default to A2 DK1 audio standard */
  9.1383 +		priv->video_standard = DK_SECAM_A2DK1;
  9.1384 +		goto tune_channel;
  9.1385 +	}
  9.1386 +
  9.1387 +	if (params->std & V4L2_STD_SECAM_L) {
  9.1388 +		priv->video_standard = L_SECAM_NICAM;
  9.1389 +		goto tune_channel;
  9.1390 +	}
  9.1391 +
  9.1392 +	if (params->std & V4L2_STD_SECAM_LC) {
  9.1393 +		priv->video_standard = LC_SECAM_NICAM;
  9.1394 +		goto tune_channel;
  9.1395 +	}
  9.1396 +
  9.1397 +tune_channel:
  9.1398 +	ret = xc_SetSignalSource(priv, priv->rf_mode);
  9.1399 +	if (ret != XC_RESULT_SUCCESS) {
  9.1400 +		printk(KERN_ERR
  9.1401 +			"xc4000: xc_SetSignalSource(%d) failed\n",
  9.1402 +			priv->rf_mode);
  9.1403 +		return -EREMOTEIO;
  9.1404 +	}
  9.1405 +
  9.1406 +	ret = xc_SetTVStandard(priv,
  9.1407 +		XC4000_Standard[priv->video_standard].VideoMode,
  9.1408 +		XC4000_Standard[priv->video_standard].AudioMode);
  9.1409 +	if (ret != XC_RESULT_SUCCESS) {
  9.1410 +		printk(KERN_ERR "xc4000: xc_SetTVStandard failed\n");
  9.1411 +		return -EREMOTEIO;
  9.1412 +	}
  9.1413 +
  9.1414 +	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
  9.1415 +
  9.1416 +	if (debug)
  9.1417 +		xc_debug_dump(priv);
  9.1418 +
  9.1419 +	return 0;
  9.1420 +}
  9.1421 +
  9.1422 +static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
  9.1423 +{
  9.1424 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1425 +	dprintk(1, "%s()\n", __func__);
  9.1426 +	*freq = priv->freq_hz;
  9.1427 +	return 0;
  9.1428 +}
  9.1429 +
  9.1430 +static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
  9.1431 +{
  9.1432 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1433 +	dprintk(1, "%s()\n", __func__);
  9.1434 +
  9.1435 +	*bw = priv->bandwidth;
  9.1436 +	return 0;
  9.1437 +}
  9.1438 +
  9.1439 +static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
  9.1440 +{
  9.1441 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1442 +	u16 lock_status = 0;
  9.1443 +
  9.1444 +	xc_get_lock_status(priv, &lock_status);
  9.1445 +
  9.1446 +	dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
  9.1447 +
  9.1448 +	*status = lock_status;
  9.1449 +
  9.1450 +	return 0;
  9.1451 +}
  9.1452 +
  9.1453 +static int xc4000_sleep(struct dvb_frontend *fe)
  9.1454 +{
  9.1455 +	/* FIXME: djh disable this for now... */
  9.1456 +	return XC_RESULT_SUCCESS;
  9.1457 +#if 0
  9.1458 +	int ret;
  9.1459 +
  9.1460 +	dprintk(1, "%s()\n", __func__);
  9.1461 +
  9.1462 +	/* Avoid firmware reload on slow devices */
  9.1463 +	if (no_poweroff)
  9.1464 +		return 0;
  9.1465 +
  9.1466 +	/* According to Xceive technical support, the "powerdown" register
  9.1467 +	   was removed in newer versions of the firmware.  The "supported"
  9.1468 +	   way to sleep the tuner is to pull the reset pin low for 10ms */
  9.1469 +	ret = xc4000_TunerReset(fe);
  9.1470 +	if (ret != XC_RESULT_SUCCESS) {
  9.1471 +		printk(KERN_ERR
  9.1472 +			"xc4000: %s() unable to shutdown tuner\n",
  9.1473 +			__func__);
  9.1474 +		return -EREMOTEIO;
  9.1475 +	} else
  9.1476 +		return XC_RESULT_SUCCESS;
  9.1477 +#endif
  9.1478 +}
  9.1479 +
  9.1480 +static int xc4000_init(struct dvb_frontend *fe)
  9.1481 +{
  9.1482 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1483 +	dprintk(1, "%s()\n", __func__);
  9.1484 +
  9.1485 +	if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS) {
  9.1486 +		printk(KERN_ERR "xc4000: Unable to initialise tuner\n");
  9.1487 +		return -EREMOTEIO;
  9.1488 +	}
  9.1489 +
  9.1490 +	if (debug)
  9.1491 +		xc_debug_dump(priv);
  9.1492 +
  9.1493 +	return 0;
  9.1494 +}
  9.1495 +
  9.1496 +static int xc4000_release(struct dvb_frontend *fe)
  9.1497 +{
  9.1498 +	struct xc4000_priv *priv = fe->tuner_priv;
  9.1499 +
  9.1500 +	dprintk(1, "%s()\n", __func__);
  9.1501 +
  9.1502 +	mutex_lock(&xc4000_list_mutex);
  9.1503 +
  9.1504 +	if (priv)
  9.1505 +		hybrid_tuner_release_state(priv);
  9.1506 +
  9.1507 +	mutex_unlock(&xc4000_list_mutex);
  9.1508 +
  9.1509 +	fe->tuner_priv = NULL;
  9.1510 +
  9.1511 +	return 0;
  9.1512 +}
  9.1513 +
  9.1514 +static const struct dvb_tuner_ops xc4000_tuner_ops = {
  9.1515 +	.info = {
  9.1516 +		.name           = "Xceive XC4000",
  9.1517 +		.frequency_min  =    1000000,
  9.1518 +		.frequency_max  = 1023000000,
  9.1519 +		.frequency_step =      50000,
  9.1520 +	},
  9.1521 +
  9.1522 +	.release	   = xc4000_release,
  9.1523 +	.init		   = xc4000_init,
  9.1524 +	.sleep		   = xc4000_sleep,
  9.1525 +
  9.1526 +	.set_params	   = xc4000_set_params,
  9.1527 +	.set_analog_params = xc4000_set_analog_params,
  9.1528 +	.get_frequency	   = xc4000_get_frequency,
  9.1529 +	.get_bandwidth	   = xc4000_get_bandwidth,
  9.1530 +	.get_status	   = xc4000_get_status
  9.1531 +};
  9.1532 +
  9.1533 +struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
  9.1534 +				   struct i2c_adapter *i2c,
  9.1535 +				   struct xc4000_config *cfg)
  9.1536 +{
  9.1537 +	struct xc4000_priv *priv = NULL;
  9.1538 +	int instance;
  9.1539 +	u16 id = 0;
  9.1540 +
  9.1541 +	dprintk(1, "%s(%d-%04x)\n", __func__,
  9.1542 +		i2c ? i2c_adapter_id(i2c) : -1,
  9.1543 +		cfg ? cfg->i2c_address : -1);
  9.1544 +
  9.1545 +	mutex_lock(&xc4000_list_mutex);
  9.1546 +
  9.1547 +	instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
  9.1548 +					      hybrid_tuner_instance_list,
  9.1549 +					      i2c, cfg->i2c_address, "xc4000");
  9.1550 +	switch (instance) {
  9.1551 +	case 0:
  9.1552 +		goto fail;
  9.1553 +		break;
  9.1554 +	case 1:
  9.1555 +		/* new tuner instance */
  9.1556 +		priv->bandwidth = BANDWIDTH_6_MHZ;
  9.1557 +		fe->tuner_priv = priv;
  9.1558 +		break;
  9.1559 +	default:
  9.1560 +		/* existing tuner instance */
  9.1561 +		fe->tuner_priv = priv;
  9.1562 +		break;
  9.1563 +	}
  9.1564 +
  9.1565 +	if (priv->if_khz == 0) {
  9.1566 +		/* If the IF hasn't been set yet, use the value provided by
  9.1567 +		   the caller (occurs in hybrid devices where the analog
  9.1568 +		   call to xc4000_attach occurs before the digital side) */
  9.1569 +		priv->if_khz = cfg->if_khz;
  9.1570 +	}
  9.1571 +
  9.1572 +	/* Check if firmware has been loaded. It is possible that another
  9.1573 +	   instance of the driver has loaded the firmware.
  9.1574 +	 */
  9.1575 +
  9.1576 +	if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
  9.1577 +			goto fail;
  9.1578 +
  9.1579 +	switch (id) {
  9.1580 +	case XC_PRODUCT_ID_FW_LOADED:
  9.1581 +		printk(KERN_INFO
  9.1582 +			"xc4000: Successfully identified at address 0x%02x\n",
  9.1583 +			cfg->i2c_address);
  9.1584 +		printk(KERN_INFO
  9.1585 +			"xc4000: Firmware has been loaded previously\n");
  9.1586 +		break;
  9.1587 +	case XC_PRODUCT_ID_FW_NOT_LOADED:
  9.1588 +		printk(KERN_INFO
  9.1589 +			"xc4000: Successfully identified at address 0x%02x\n",
  9.1590 +			cfg->i2c_address);
  9.1591 +		printk(KERN_INFO
  9.1592 +			"xc4000: Firmware has not been loaded previously\n");
  9.1593 +		break;
  9.1594 +	default:
  9.1595 +		printk(KERN_ERR
  9.1596 +			"xc4000: Device not found at addr 0x%02x (0x%x)\n",
  9.1597 +			cfg->i2c_address, id);
  9.1598 +		goto fail;
  9.1599 +	}
  9.1600 +
  9.1601 +	mutex_unlock(&xc4000_list_mutex);
  9.1602 +
  9.1603 +	memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
  9.1604 +		sizeof(struct dvb_tuner_ops));
  9.1605 +
  9.1606 +	/* FIXME: For now, load the firmware at startup.  We will remove this
  9.1607 +	   before the code goes to production... */
  9.1608 +	check_firmware(fe, DTV8, 0, priv->if_khz);
  9.1609 +
  9.1610 +	return fe;
  9.1611 +fail:
  9.1612 +	mutex_unlock(&xc4000_list_mutex);
  9.1613 +
  9.1614 +	xc4000_release(fe);
  9.1615 +	return NULL;
  9.1616 +}
  9.1617 +EXPORT_SYMBOL(xc4000_attach);
  9.1618 +
  9.1619 +MODULE_AUTHOR("Steven Toth, Davide Ferri");
  9.1620 +MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
  9.1621 +MODULE_LICENSE("GPL");
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/linux/drivers/media/common/tuners/xc4000.h	Sun Oct 04 21:38:39 2009 -0400
    10.3 @@ -0,0 +1,61 @@
    10.4 +/*
    10.5 + *  Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
    10.6 + *
    10.7 + *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
    10.8 + *
    10.9 + *  This program is free software; you can redistribute it and/or modify
   10.10 + *  it under the terms of the GNU General Public License as published by
   10.11 + *  the Free Software Foundation; either version 2 of the License, or
   10.12 + *  (at your option) any later version.
   10.13 + *
   10.14 + *  This program is distributed in the hope that it will be useful,
   10.15 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.16 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.17 + *
   10.18 + *  GNU General Public License for more details.
   10.19 + *
   10.20 + *  You should have received a copy of the GNU General Public License
   10.21 + *  along with this program; if not, write to the Free Software
   10.22 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   10.23 + */
   10.24 +
   10.25 +#ifndef __XC4000_H__
   10.26 +#define __XC4000_H__
   10.27 +
   10.28 +#include <linux/firmware.h>
   10.29 +
   10.30 +struct dvb_frontend;
   10.31 +struct i2c_adapter;
   10.32 +
   10.33 +struct xc4000_config {
   10.34 +	u8   i2c_address;
   10.35 +	u32  if_khz;
   10.36 +};
   10.37 +
   10.38 +/* xc4000 callback command */
   10.39 +#define XC4000_TUNER_RESET		0
   10.40 +
   10.41 +/* For each bridge framework, when it attaches either analog or digital,
   10.42 + * it has to store a reference back to its _core equivalent structure,
   10.43 + * so that it can service the hardware by steering gpio's etc.
   10.44 + * Each bridge implementation is different so cast devptr accordingly.
   10.45 + * The xc4000 driver cares not for this value, other than ensuring
   10.46 + * it's passed back to a bridge during tuner_callback().
   10.47 + */
   10.48 +
   10.49 +#if defined(CONFIG_MEDIA_TUNER_XC4000) || \
   10.50 +    (defined(CONFIG_MEDIA_TUNER_XC4000_MODULE) && defined(MODULE))
   10.51 +extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
   10.52 +					  struct i2c_adapter *i2c,
   10.53 +					  struct xc4000_config *cfg);
   10.54 +#else
   10.55 +static inline struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
   10.56 +						 struct i2c_adapter *i2c,
   10.57 +						 struct xc4000_config *cfg)
   10.58 +{
   10.59 +	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
   10.60 +	return NULL;
   10.61 +}
   10.62 +#endif
   10.63 +
   10.64 +#endif