aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2008-01-05 14:50:14 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:05:05 -0500
commit27c685a4b09b5e391023d769cddb97e4fcb3b9e1 (patch)
treeaf296caf5de933e90f7c82170f0cc2e57dd062f0
parentdfc1c08aab447d49230dacb390d3f2263584d28f (diff)
V4L/DVB (7042): xc5000: Tuner analog support
From Zhang: This an updated patch that adds analog support for the xc5000 tuner driver. it was tested on a Pinnacle PCTV HD 800i card (patches to follow). Patch commited as-is, cleanup to follow ... Steve. Signed-off-by: Chaogui Zhang <czhang1974@gmail.com> Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--Documentation/video4linux/CARDLIST.tuner1
-rw-r--r--drivers/media/dvb/frontends/xc5000.c213
-rw-r--r--drivers/media/dvb/frontends/xc5000.h12
-rw-r--r--drivers/media/video/tuner-core.c20
-rw-r--r--drivers/media/video/tuner-types.c4
-rw-r--r--include/media/tuner.h1
6 files changed, 213 insertions, 38 deletions
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 2211c8eac643..0e2394695bb8 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -73,3 +73,4 @@ tuner=71 - Xceive xc2028/xc3028 tuner
73tuner=72 - Thomson FE6600 73tuner=72 - Thomson FE6600
74tuner=73 - Samsung TCPG 6121P30A 74tuner=73 - Samsung TCPG 6121P30A
75tuner=75 - Philips TEA5761 FM Radio 75tuner=75 - Philips TEA5761 FM Radio
76tuner=76 - Xceive 5000 tuner
diff --git a/drivers/media/dvb/frontends/xc5000.c b/drivers/media/dvb/frontends/xc5000.c
index a036530ee4b4..28048d5307a2 100644
--- a/drivers/media/dvb/frontends/xc5000.c
+++ b/drivers/media/dvb/frontends/xc5000.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <linux/videodev2.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/dvb/frontend.h> 27#include <linux/dvb/frontend.h>
27#include <linux/i2c.h> 28#include <linux/i2c.h>
@@ -56,6 +57,10 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
56#define XC_RESULT_I2C_READ_FAILURE 3 57#define XC_RESULT_I2C_READ_FAILURE 3
57#define XC_RESULT_OUT_OF_RANGE 5 58#define XC_RESULT_OUT_OF_RANGE 5
58 59
60/* Product id */
61#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
62#define XC_PRODUCT_ID_FW_LOADED 0x1388
63
59/* Registers */ 64/* Registers */
60#define XREG_INIT 0x00 65#define XREG_INIT 0x00
61#define XREG_VIDEO_MODE 0x01 66#define XREG_VIDEO_MODE 0x01
@@ -122,7 +127,29 @@ typedef struct {
122} XC_TV_STANDARD; 127} XC_TV_STANDARD;
123 128
124/* Tuner standards */ 129/* Tuner standards */
125#define DTV6 17 130#define MN_NTSC_PAL_BTSC 0
131#define MN_NTSC_PAL_A2 1
132#define MN_NTSC_PAL_EIAJ 2
133#define MN_NTSC_PAL_Mono 3
134#define BG_PAL_A2 4
135#define BG_PAL_NICAM 5
136#define BG_PAL_MONO 6
137#define I_PAL_NICAM 7
138#define I_PAL_NICAM_MONO 8
139#define DK_PAL_A2 9
140#define DK_PAL_NICAM 10
141#define DK_PAL_MONO 11
142#define DK_SECAM_A2DK1 12
143#define DK_SECAM_A2LDK3 13
144#define DK_SECAM_A2MONO 14
145#define L_SECAM_NICAM 15
146#define LC_SECAM_NICAM 16
147#define DTV6 17
148#define DTV8 18
149#define DTV7_8 19
150#define DTV7 20
151#define FM_Radio_INPUT2 21
152#define FM_Radio_INPUT1 22
126 153
127XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { 154XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
128 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, 155 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
@@ -184,12 +211,13 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
184 211
185 dprintk(1, "%s()\n", __FUNCTION__); 212 dprintk(1, "%s()\n", __FUNCTION__);
186 213
187 if (priv->cfg->tuner_reset) { 214 if (priv->cfg->tuner_callback) {
188 ret = priv->cfg->tuner_reset(fe); 215 ret = priv->cfg->tuner_callback(priv->cfg->video_dev,
216 XC5000_TUNER_RESET, 0);
189 if (ret) 217 if (ret)
190 printk(KERN_ERR "xc5000: reset failed\n"); 218 printk(KERN_ERR "xc5000: reset failed\n");
191 } else 219 } else
192 printk(KERN_ERR "xc5000: no tuner reset function, fatal\n"); 220 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
193} 221}
194 222
195static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) 223static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
@@ -259,7 +287,6 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[])
259 287
260 index=0; 288 index=0;
261 while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) { 289 while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) {
262
263 len = i2c_sequence[index]* 256 + i2c_sequence[index+1]; 290 len = i2c_sequence[index]* 256 + i2c_sequence[index+1];
264 if (len == 0x0000) { 291 if (len == 0x0000) {
265 /* RESET command */ 292 /* RESET command */
@@ -311,7 +338,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
311 u16 VideoMode, u16 AudioMode) 338 u16 VideoMode, u16 AudioMode)
312{ 339{
313 int ret; 340 int ret;
314 dprintk(1, "%s(%d,%d)\n", __FUNCTION__, VideoMode, AudioMode); 341 dprintk(1, "%s(0x%04x,0x%04x)\n", __FUNCTION__, VideoMode, AudioMode);
315 dprintk(1, "%s() Standard = %s\n", 342 dprintk(1, "%s() Standard = %s\n",
316 __FUNCTION__, 343 __FUNCTION__,
317 XC5000_Standard[priv->video_standard].Name); 344 XC5000_Standard[priv->video_standard].Name);
@@ -325,7 +352,11 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
325 352
326static int xc_shutdown(struct xc5000_priv *priv) 353static int xc_shutdown(struct xc5000_priv *priv)
327{ 354{
328 return xc_write_reg(priv, XREG_POWER_DOWN, 0); 355 return 0;
356 /* Fixme: cannot bring tuner back alive once shutdown
357 * without reloading the driver modules.
358 * return xc_write_reg(priv, XREG_POWER_DOWN, 0);
359 */
329} 360}
330 361
331static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) 362static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
@@ -349,7 +380,7 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
349{ 380{
350 u16 freq_code; 381 u16 freq_code;
351 382
352 dprintk(1, "%s(%d)\n", __FUNCTION__, freq_hz); 383 dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz);
353 384
354 if ((freq_hz > xc5000_tuner_ops.info.frequency_max) || 385 if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
355 (freq_hz < xc5000_tuner_ops.info.frequency_min)) 386 (freq_hz < xc5000_tuner_ops.info.frequency_min))
@@ -457,7 +488,7 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz)
457{ 488{
458 int found = 0; 489 int found = 0;
459 490
460 dprintk(1, "%s(%d)\n", __FUNCTION__, freq_hz); 491 dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz);
461 492
462 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) 493 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
463 return 0; 494 return 0;
@@ -480,7 +511,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
480 }; 511 };
481 512
482 if (i2c_transfer(priv->i2c, msg, 2) != 2) { 513 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
483 printk(KERN_WARNING "xc5000 I2C read failed\n"); 514 printk(KERN_WARNING "xc5000: I2C read failed\n");
484 return -EREMOTEIO; 515 return -EREMOTEIO;
485 } 516 }
486 517
@@ -494,7 +525,7 @@ static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
494 .flags = 0, .buf = buf, .len = len }; 525 .flags = 0, .buf = buf, .len = len };
495 526
496 if (i2c_transfer(priv->i2c, &msg, 1) != 1) { 527 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
497 printk(KERN_ERR "xc5000 I2C write failed (len=%i)\n", 528 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n",
498 (int)len); 529 (int)len);
499 return -EREMOTEIO; 530 return -EREMOTEIO;
500 } 531 }
@@ -519,16 +550,11 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
519 const struct firmware *fw; 550 const struct firmware *fw;
520 int ret; 551 int ret;
521 552
522 if (!priv->cfg->request_firmware) {
523 printk(KERN_ERR "xc5000: no firmware callback, fatal\n");
524 return -EIO;
525 }
526
527 /* request the firmware, this will block and timeout */ 553 /* request the firmware, this will block and timeout */
528 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", 554 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
529 XC5000_DEFAULT_FIRMWARE); 555 XC5000_DEFAULT_FIRMWARE);
530 556
531 ret = priv->cfg->request_firmware(fe, &fw, XC5000_DEFAULT_FIRMWARE); 557 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c->dev);
532 if (ret) { 558 if (ret) {
533 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); 559 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
534 ret = XC_RESULT_RESET_FAILURE; 560 ret = XC_RESULT_RESET_FAILURE;
@@ -601,7 +627,6 @@ static int xc5000_set_params(struct dvb_frontend *fe,
601 627
602 dprintk(1, "%s() frequency=%d (Hz)\n", __FUNCTION__, params->frequency); 628 dprintk(1, "%s() frequency=%d (Hz)\n", __FUNCTION__, params->frequency);
603 629
604
605 switch(params->u.vsb.modulation) { 630 switch(params->u.vsb.modulation) {
606 case VSB_8: 631 case VSB_8:
607 case VSB_16: 632 case VSB_16:
@@ -658,6 +683,93 @@ static int xc5000_set_params(struct dvb_frontend *fe,
658 return 0; 683 return 0;
659} 684}
660 685
686static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
687
688static int xc5000_set_analog_params(struct dvb_frontend *fe,
689 struct analog_parameters *params)
690{
691 struct xc5000_priv *priv = fe->tuner_priv;
692 int ret;
693
694 if(priv->fwloaded == 0)
695 xc_load_fw_and_init_tuner(fe);
696
697 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
698 __FUNCTION__, params->frequency);
699
700 priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */
701
702 /* params->frequency is in units of 62.5khz */
703 priv->freq_hz = params->frequency * 62500;
704
705 /* FIX ME: Some video standards may have several possible audio
706 standards. We simply default to one of them here.
707 */
708 if(params->std & V4L2_STD_MN) {
709 /* default to BTSC audio standard */
710 priv->video_standard = MN_NTSC_PAL_BTSC;
711 goto tune_channel;
712 }
713
714 if(params->std & V4L2_STD_PAL_BG) {
715 /* default to NICAM audio standard */
716 priv->video_standard = BG_PAL_NICAM;
717 goto tune_channel;
718 }
719
720 if(params->std & V4L2_STD_PAL_I) {
721 /* default to NICAM audio standard */
722 priv->video_standard = I_PAL_NICAM;
723 goto tune_channel;
724 }
725
726 if(params->std & V4L2_STD_PAL_DK) {
727 /* default to NICAM audio standard */
728 priv->video_standard = DK_PAL_NICAM;
729 goto tune_channel;
730 }
731
732 if(params->std & V4L2_STD_SECAM_DK) {
733 /* default to A2 DK1 audio standard */
734 priv->video_standard = DK_SECAM_A2DK1;
735 goto tune_channel;
736 }
737
738 if(params->std & V4L2_STD_SECAM_L) {
739 priv->video_standard = L_SECAM_NICAM;
740 goto tune_channel;
741 }
742
743 if(params->std & V4L2_STD_SECAM_LC) {
744 priv->video_standard = LC_SECAM_NICAM;
745 goto tune_channel;
746 }
747
748tune_channel:
749 ret = xc_SetSignalSource(priv, priv->rf_mode);
750 if (ret != XC_RESULT_SUCCESS) {
751 printk(KERN_ERR
752 "xc5000: xc_SetSignalSource(%d) failed\n",
753 priv->rf_mode);
754 return -EREMOTEIO;
755 }
756
757 ret = xc_SetTVStandard(priv,
758 XC5000_Standard[priv->video_standard].VideoMode,
759 XC5000_Standard[priv->video_standard].AudioMode);
760 if (ret != XC_RESULT_SUCCESS) {
761 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
762 return -EREMOTEIO;
763 }
764
765 xc_tune_channel(priv, priv->freq_hz);
766
767 if (debug)
768 xc_debug_dump(priv);
769
770 return 0;
771}
772
661static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) 773static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
662{ 774{
663 struct xc5000_priv *priv = fe->tuner_priv; 775 struct xc5000_priv *priv = fe->tuner_priv;
@@ -670,6 +782,7 @@ static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
670{ 782{
671 struct xc5000_priv *priv = fe->tuner_priv; 783 struct xc5000_priv *priv = fe->tuner_priv;
672 dprintk(1, "%s()\n", __FUNCTION__); 784 dprintk(1, "%s()\n", __FUNCTION__);
785
673 *bw = priv->bandwidth; 786 *bw = priv->bandwidth;
674 return 0; 787 return 0;
675} 788}
@@ -691,13 +804,12 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
691static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) 804static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
692{ 805{
693 struct xc5000_priv *priv = fe->tuner_priv; 806 struct xc5000_priv *priv = fe->tuner_priv;
694 int ret; 807 int ret = 0;
695 808
696 if (priv->fwloaded == 0) { 809 if (priv->fwloaded == 0) {
697 ret = xc5000_fwupload(fe); 810 ret = xc5000_fwupload(fe);
698 if (ret != XC_RESULT_SUCCESS) 811 if (ret != XC_RESULT_SUCCESS)
699 return ret; 812 return ret;
700
701 priv->fwloaded = 1; 813 priv->fwloaded = 1;
702 } 814 }
703 815
@@ -720,9 +832,27 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
720static int xc5000_sleep(struct dvb_frontend *fe) 832static int xc5000_sleep(struct dvb_frontend *fe)
721{ 833{
722 struct xc5000_priv *priv = fe->tuner_priv; 834 struct xc5000_priv *priv = fe->tuner_priv;
835 int ret;
836
723 dprintk(1, "%s()\n", __FUNCTION__); 837 dprintk(1, "%s()\n", __FUNCTION__);
724 838
725 return xc_shutdown(priv); 839 /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized
840 * once shutdown without reloading the driver. Maybe I am not
841 * doing something right.
842 *
843 */
844
845 ret = xc_shutdown(priv);
846 if(ret != XC_RESULT_SUCCESS) {
847 printk(KERN_ERR
848 "xc5000: %s() unable to shutdown tuner\n",
849 __FUNCTION__);
850 return -EREMOTEIO;
851 }
852 else {
853 /* priv->fwloaded = 0; */
854 return XC_RESULT_SUCCESS;
855 }
726} 856}
727 857
728static int xc5000_init(struct dvb_frontend *fe) 858static int xc5000_init(struct dvb_frontend *fe)
@@ -757,14 +887,15 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
757 .frequency_step = 50000, 887 .frequency_step = 50000,
758 }, 888 },
759 889
760 .release = xc5000_release, 890 .release = xc5000_release,
761 .init = xc5000_init, 891 .init = xc5000_init,
762 .sleep = xc5000_sleep, 892 .sleep = xc5000_sleep,
763 893
764 .set_params = xc5000_set_params, 894 .set_params = xc5000_set_params,
765 .get_frequency = xc5000_get_frequency, 895 .set_analog_params = xc5000_set_analog_params,
766 .get_bandwidth = xc5000_get_bandwidth, 896 .get_frequency = xc5000_get_frequency,
767 .get_status = xc5000_get_status 897 .get_bandwidth = xc5000_get_bandwidth,
898 .get_status = xc5000_get_status
768}; 899};
769 900
770struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, 901struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
@@ -783,14 +914,33 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
783 priv->cfg = cfg; 914 priv->cfg = cfg;
784 priv->bandwidth = BANDWIDTH_6_MHZ; 915 priv->bandwidth = BANDWIDTH_6_MHZ;
785 priv->i2c = i2c; 916 priv->i2c = i2c;
786 priv->fwloaded = 0;
787 917
918 /* Check if firmware has been loaded. It is possible that another
919 instance of the driver has loaded the firmware.
920 */
788 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) { 921 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) {
789 kfree(priv); 922 kfree(priv);
790 return NULL; 923 return NULL;
791 } 924 }
792 925
793 if ((id != 0x2000) && (id != 0x1388)) { 926 switch(id) {
927 case XC_PRODUCT_ID_FW_LOADED:
928 printk(KERN_INFO
929 "xc5000: Successfully identified at address 0x%02x\n",
930 cfg->i2c_address);
931 printk(KERN_INFO
932 "xc5000: Firmware has been loaded previously\n");
933 priv->fwloaded = 1;
934 break;
935 case XC_PRODUCT_ID_FW_NOT_LOADED:
936 printk(KERN_INFO
937 "xc5000: Successfully identified at address 0x%02x\n",
938 cfg->i2c_address);
939 printk(KERN_INFO
940 "xc5000: Firmware has not been loaded previously\n");
941 priv->fwloaded = 0;
942 break;
943 default:
794 printk(KERN_ERR 944 printk(KERN_ERR
795 "xc5000: Device not found at addr 0x%02x (0x%x)\n", 945 "xc5000: Device not found at addr 0x%02x (0x%x)\n",
796 cfg->i2c_address, id); 946 cfg->i2c_address, id);
@@ -798,9 +948,6 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
798 return NULL; 948 return NULL;
799 } 949 }
800 950
801 printk(KERN_INFO "xc5000: successfully identified at address 0x%02x\n",
802 cfg->i2c_address);
803
804 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops, 951 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
805 sizeof(struct dvb_tuner_ops)); 952 sizeof(struct dvb_tuner_ops));
806 953
diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/dvb/frontends/xc5000.h
index 941b31948133..85b2d438fa41 100644
--- a/drivers/media/dvb/frontends/xc5000.h
+++ b/drivers/media/dvb/frontends/xc5000.h
@@ -28,13 +28,15 @@ struct dvb_frontend;
28struct i2c_adapter; 28struct i2c_adapter;
29 29
30struct xc5000_config { 30struct xc5000_config {
31 u8 i2c_address; 31 u8 i2c_address;
32 u32 if_khz; 32 u32 if_khz;
33 int (*request_firmware)(struct dvb_frontend *fe, 33 void *video_dev;
34 const struct firmware **fw, char *name); 34 int (*tuner_callback) (void *dev, int command, int arg);
35 int (*tuner_reset)(struct dvb_frontend* fe);
36}; 35};
37 36
37/* xc5000 callback command */
38#define XC5000_TUNER_RESET 0
39
38#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE) 40#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE)
39extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, 41extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
40 struct i2c_adapter *i2c, 42 struct i2c_adapter *i2c,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 35976e6cb1b8..16cdeeafeb6c 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -27,6 +27,7 @@
27#include "tuner-xc2028.h" 27#include "tuner-xc2028.h"
28#include "tuner-simple.h" 28#include "tuner-simple.h"
29#include "tda9887.h" 29#include "tda9887.h"
30#include "xc5000.h"
30 31
31#define UNSET (-1U) 32#define UNSET (-1U)
32 33
@@ -329,6 +330,8 @@ static void attach_tda829x(struct tuner *t)
329 tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); 330 tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
330} 331}
331 332
333static struct xc5000_config xc5000_cfg;
334
332static void set_type(struct i2c_client *c, unsigned int type, 335static void set_type(struct i2c_client *c, unsigned int type,
333 unsigned int new_mode_mask, unsigned int new_config, 336 unsigned int new_mode_mask, unsigned int new_config,
334 int (*tuner_callback) (void *dev, int command,int arg)) 337 int (*tuner_callback) (void *dev, int command,int arg))
@@ -428,6 +431,23 @@ static void set_type(struct i2c_client *c, unsigned int type,
428 case TUNER_TDA9887: 431 case TUNER_TDA9887:
429 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 432 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr);
430 break; 433 break;
434 case TUNER_XC5000:
435 xc5000_cfg.i2c_address = t->i2c->addr;
436 xc5000_cfg.if_khz = 5380;
437 xc5000_cfg.video_dev = c->adapter->algo_data;
438 xc5000_cfg.tuner_callback = t->tuner_callback;
439 if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) {
440 t->type = TUNER_ABSENT;
441 t->mode_mask = T_UNINITIALIZED;
442 return;
443 }
444 {
445 struct dvb_tuner_ops *xc_tuner_ops;
446 xc_tuner_ops = &t->fe.ops.tuner_ops;
447 if(xc_tuner_ops->init != NULL)
448 xc_tuner_ops->init(&t->fe);
449 }
450 break;
431 default: 451 default:
432 attach_simple_tuner(t); 452 attach_simple_tuner(t);
433 break; 453 break;
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
index e2cd05a05802..883047f9c28c 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/video/tuner-types.c
@@ -1475,6 +1475,10 @@ struct tunertype tuners[] = {
1475 .name = "Philips TEA5761 FM Radio", 1475 .name = "Philips TEA5761 FM Radio",
1476 /* see tea5767.c for details */ 1476 /* see tea5767.c for details */
1477 }, 1477 },
1478 [TUNER_XC5000] = { /* Xceive 5000 */
1479 .name = "Xceive 5000 tuner",
1480 /* see xc5000.c for details */
1481 },
1478}; 1482};
1479 1483
1480unsigned const int tuner_count = ARRAY_SIZE(tuners); 1484unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 97be269afbee..1bf24a6ed8f1 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -121,6 +121,7 @@
121#define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */ 121#define TUNER_SAMSUNG_TCPG_6121P30A 73 /* Hauppauge PVR-500 PAL */
122#define TUNER_TDA9887 74 /* This tuner should be used only internally */ 122#define TUNER_TDA9887 74 /* This tuner should be used only internally */
123#define TUNER_TEA5761 75 /* Only FM Radio Tuner */ 123#define TUNER_TEA5761 75 /* Only FM Radio Tuner */
124#define TUNER_XC5000 76 /* Xceive Silicon Tuner */
124 125
125/* tv card specific */ 126/* tv card specific */
126#define TDA9887_PRESENT (1<<0) 127#define TDA9887_PRESENT (1<<0)