aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners/xc5000.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-14 20:31:54 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-14 20:31:54 -0400
commit6dc6472581f693b5fc95aebedf67b4960fb85cf0 (patch)
tree06a5a9a08519950575505273eabced331ed51405 /drivers/media/common/tuners/xc5000.c
parentee673eaa72d8d185012b1027a05e25aba18c267f (diff)
parent8acd3a60bcca17c6d89c73cee3ad6057eb83ba1e (diff)
Merge commit 'origin'
Manual fixup of conflicts on: arch/powerpc/include/asm/dcr-regs.h drivers/net/ibm_newemac/core.h
Diffstat (limited to 'drivers/media/common/tuners/xc5000.c')
-rw-r--r--drivers/media/common/tuners/xc5000.c109
1 files changed, 77 insertions, 32 deletions
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index dcddfa803a75..f9c2bb917f54 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -30,7 +30,7 @@
30#include "dvb_frontend.h" 30#include "dvb_frontend.h"
31 31
32#include "xc5000.h" 32#include "xc5000.h"
33#include "xc5000_priv.h" 33#include "tuner-i2c.h"
34 34
35static int debug; 35static int debug;
36module_param(debug, int, 0644); 36module_param(debug, int, 0644);
@@ -40,12 +40,26 @@ static int xc5000_load_fw_on_attach;
40module_param_named(init_fw, xc5000_load_fw_on_attach, int, 0644); 40module_param_named(init_fw, xc5000_load_fw_on_attach, int, 0644);
41MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization."); 41MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization.");
42 42
43static DEFINE_MUTEX(xc5000_list_mutex);
44static LIST_HEAD(hybrid_tuner_instance_list);
45
43#define dprintk(level,fmt, arg...) if (debug >= level) \ 46#define dprintk(level,fmt, arg...) if (debug >= level) \
44 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) 47 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
45 48
46#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" 49#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
47#define XC5000_DEFAULT_FIRMWARE_SIZE 12332 50#define XC5000_DEFAULT_FIRMWARE_SIZE 12332
48 51
52struct xc5000_priv {
53 struct tuner_i2c_props i2c_props;
54 struct list_head hybrid_tuner_instance_list;
55
56 u32 if_khz;
57 u32 freq_hz;
58 u32 bandwidth;
59 u8 video_standard;
60 u8 rf_mode;
61};
62
49/* Misc Defines */ 63/* Misc Defines */
50#define MAX_TV_STANDARD 23 64#define MAX_TV_STANDARD 23
51#define XC_MAX_I2C_WRITE_LENGTH 64 65#define XC_MAX_I2C_WRITE_LENGTH 64
@@ -216,9 +230,12 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
216 230
217 dprintk(1, "%s()\n", __func__); 231 dprintk(1, "%s()\n", __func__);
218 232
219 if (priv->cfg->tuner_callback) { 233 if (fe->callback) {
220 ret = priv->cfg->tuner_callback(priv->devptr, 234 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
221 XC5000_TUNER_RESET, 0); 235 fe->dvb->priv :
236 priv->i2c_props.adap->algo_data,
237 DVB_FRONTEND_COMPONENT_TUNER,
238 XC5000_TUNER_RESET, 0);
222 if (ret) 239 if (ret)
223 printk(KERN_ERR "xc5000: reset failed\n"); 240 printk(KERN_ERR "xc5000: reset failed\n");
224 } else 241 } else
@@ -509,13 +526,13 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
509 u8 buf[2] = { reg >> 8, reg & 0xff }; 526 u8 buf[2] = { reg >> 8, reg & 0xff };
510 u8 bval[2] = { 0, 0 }; 527 u8 bval[2] = { 0, 0 };
511 struct i2c_msg msg[2] = { 528 struct i2c_msg msg[2] = {
512 { .addr = priv->cfg->i2c_address, 529 { .addr = priv->i2c_props.addr,
513 .flags = 0, .buf = &buf[0], .len = 2 }, 530 .flags = 0, .buf = &buf[0], .len = 2 },
514 { .addr = priv->cfg->i2c_address, 531 { .addr = priv->i2c_props.addr,
515 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 }, 532 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
516 }; 533 };
517 534
518 if (i2c_transfer(priv->i2c, msg, 2) != 2) { 535 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
519 printk(KERN_WARNING "xc5000: I2C read failed\n"); 536 printk(KERN_WARNING "xc5000: I2C read failed\n");
520 return -EREMOTEIO; 537 return -EREMOTEIO;
521 } 538 }
@@ -526,10 +543,10 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
526 543
527static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) 544static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
528{ 545{
529 struct i2c_msg msg = { .addr = priv->cfg->i2c_address, 546 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
530 .flags = 0, .buf = buf, .len = len }; 547 .flags = 0, .buf = buf, .len = len };
531 548
532 if (i2c_transfer(priv->i2c, &msg, 1) != 1) { 549 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
533 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", 550 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n",
534 (int)len); 551 (int)len);
535 return -EREMOTEIO; 552 return -EREMOTEIO;
@@ -539,10 +556,10 @@ static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
539 556
540static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) 557static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
541{ 558{
542 struct i2c_msg msg = { .addr = priv->cfg->i2c_address, 559 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
543 .flags = I2C_M_RD, .buf = buf, .len = len }; 560 .flags = I2C_M_RD, .buf = buf, .len = len };
544 561
545 if (i2c_transfer(priv->i2c, &msg, 1) != 1) { 562 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
546 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len); 563 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len);
547 return -EREMOTEIO; 564 return -EREMOTEIO;
548 } 565 }
@@ -559,7 +576,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
559 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", 576 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
560 XC5000_DEFAULT_FIRMWARE); 577 XC5000_DEFAULT_FIRMWARE);
561 578
562 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c->dev); 579 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c_props.adap->dev);
563 if (ret) { 580 if (ret) {
564 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); 581 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
565 ret = XC_RESULT_RESET_FAILURE; 582 ret = XC_RESULT_RESET_FAILURE;
@@ -675,10 +692,10 @@ static int xc5000_set_params(struct dvb_frontend *fe,
675 return -EREMOTEIO; 692 return -EREMOTEIO;
676 } 693 }
677 694
678 ret = xc_set_IF_frequency(priv, priv->cfg->if_khz); 695 ret = xc_set_IF_frequency(priv, priv->if_khz);
679 if (ret != XC_RESULT_SUCCESS) { 696 if (ret != XC_RESULT_SUCCESS) {
680 printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n", 697 printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
681 priv->cfg->if_khz); 698 priv->if_khz);
682 return -EIO; 699 return -EIO;
683 } 700 }
684 701
@@ -897,9 +914,19 @@ static int xc5000_init(struct dvb_frontend *fe)
897 914
898static int xc5000_release(struct dvb_frontend *fe) 915static int xc5000_release(struct dvb_frontend *fe)
899{ 916{
917 struct xc5000_priv *priv = fe->tuner_priv;
918
900 dprintk(1, "%s()\n", __func__); 919 dprintk(1, "%s()\n", __func__);
901 kfree(fe->tuner_priv); 920
921 mutex_lock(&xc5000_list_mutex);
922
923 if (priv)
924 hybrid_tuner_release_state(priv);
925
926 mutex_unlock(&xc5000_list_mutex);
927
902 fe->tuner_priv = NULL; 928 fe->tuner_priv = NULL;
929
903 return 0; 930 return 0;
904} 931}
905 932
@@ -924,29 +951,43 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
924 951
925struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, 952struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
926 struct i2c_adapter *i2c, 953 struct i2c_adapter *i2c,
927 struct xc5000_config *cfg, void *devptr) 954 struct xc5000_config *cfg)
928{ 955{
929 struct xc5000_priv *priv = NULL; 956 struct xc5000_priv *priv = NULL;
957 int instance;
930 u16 id = 0; 958 u16 id = 0;
931 959
932 dprintk(1, "%s()\n", __func__); 960 dprintk(1, "%s(%d-%04x)\n", __func__,
961 i2c ? i2c_adapter_id(i2c) : -1,
962 cfg ? cfg->i2c_address : -1);
933 963
934 priv = kzalloc(sizeof(struct xc5000_priv), GFP_KERNEL); 964 mutex_lock(&xc5000_list_mutex);
935 if (priv == NULL)
936 return NULL;
937 965
938 priv->cfg = cfg; 966 instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
939 priv->bandwidth = BANDWIDTH_6_MHZ; 967 hybrid_tuner_instance_list,
940 priv->i2c = i2c; 968 i2c, cfg->i2c_address, "xc5000");
941 priv->devptr = devptr; 969 switch (instance) {
970 case 0:
971 goto fail;
972 break;
973 case 1:
974 /* new tuner instance */
975 priv->bandwidth = BANDWIDTH_6_MHZ;
976 priv->if_khz = cfg->if_khz;
977
978 fe->tuner_priv = priv;
979 break;
980 default:
981 /* existing tuner instance */
982 fe->tuner_priv = priv;
983 break;
984 }
942 985
943 /* Check if firmware has been loaded. It is possible that another 986 /* Check if firmware has been loaded. It is possible that another
944 instance of the driver has loaded the firmware. 987 instance of the driver has loaded the firmware.
945 */ 988 */
946 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) { 989 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
947 kfree(priv); 990 goto fail;
948 return NULL;
949 }
950 991
951 switch(id) { 992 switch(id) {
952 case XC_PRODUCT_ID_FW_LOADED: 993 case XC_PRODUCT_ID_FW_LOADED:
@@ -967,19 +1008,23 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
967 printk(KERN_ERR 1008 printk(KERN_ERR
968 "xc5000: Device not found at addr 0x%02x (0x%x)\n", 1009 "xc5000: Device not found at addr 0x%02x (0x%x)\n",
969 cfg->i2c_address, id); 1010 cfg->i2c_address, id);
970 kfree(priv); 1011 goto fail;
971 return NULL;
972 } 1012 }
973 1013
1014 mutex_unlock(&xc5000_list_mutex);
1015
974 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops, 1016 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
975 sizeof(struct dvb_tuner_ops)); 1017 sizeof(struct dvb_tuner_ops));
976 1018
977 fe->tuner_priv = priv;
978
979 if (xc5000_load_fw_on_attach) 1019 if (xc5000_load_fw_on_attach)
980 xc5000_init(fe); 1020 xc5000_init(fe);
981 1021
982 return fe; 1022 return fe;
1023fail:
1024 mutex_unlock(&xc5000_list_mutex);
1025
1026 xc5000_release(fe);
1027 return NULL;
983} 1028}
984EXPORT_SYMBOL(xc5000_attach); 1029EXPORT_SYMBOL(xc5000_attach);
985 1030