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, ®Data);
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, ®Data);
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