aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kerrison <steve@stevekerrison.com>2011-08-09 06:16:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-03 17:13:41 -0400
commit0db4bf42baae95ddd457b0c4911e851c9169750e (patch)
treed22488cc966eaa498838e91f574d8d65dbe75f35
parent6fb2bdfa068676f436fd333c460549ed64549c5e (diff)
[media] CXD2820R: Replace i2c message translation with repeater gate control
This patch implements an i2c_gate_ctrl op for the cxd2820r. Thanks to Robert Schlabbach for identifying the register address and field to set. The old i2c intercept code that prefixed messages with a passthrough byte has been removed and the PCTV nanoStick T2 290e entry in em28xx-dvb has been updated appropriately. Tested for DVB-T2 use; I would appreciate it if somebody with DVB-C capabilities could test it as well - from inspection I cannot see any problems. This is patch v2. It fixes some schoolboy style errors and removes superfluous i2c entries in cxd2820r.h. Signed-off-by: Steve Kerrison <steve@stevekerrison.com> Acked-by: Antti Palosaari <crope@iki.fi> Tested-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/frontends/cxd2820r.h9
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_c.c1
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_core.c76
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_priv.h1
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t.c1
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t2.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c7
7 files changed, 11 insertions, 85 deletions
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h
index 2906582dc94c..03cab7b547fb 100644
--- a/drivers/media/dvb/frontends/cxd2820r.h
+++ b/drivers/media/dvb/frontends/cxd2820r.h
@@ -93,9 +93,6 @@ extern struct dvb_frontend *cxd2820r_attach(
93 struct i2c_adapter *i2c, 93 struct i2c_adapter *i2c,
94 struct dvb_frontend *fe 94 struct dvb_frontend *fe
95); 95);
96extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
97 struct dvb_frontend *fe
98);
99#else 96#else
100static inline struct dvb_frontend *cxd2820r_attach( 97static inline struct dvb_frontend *cxd2820r_attach(
101 const struct cxd2820r_config *config, 98 const struct cxd2820r_config *config,
@@ -106,12 +103,6 @@ static inline struct dvb_frontend *cxd2820r_attach(
106 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 103 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
107 return NULL; 104 return NULL;
108} 105}
109static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
110 struct dvb_frontend *fe
111)
112{
113 return NULL;
114}
115 106
116#endif 107#endif
117 108
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
index 3c07d400731d..b85f5011e344 100644
--- a/drivers/media/dvb/frontends/cxd2820r_c.c
+++ b/drivers/media/dvb/frontends/cxd2820r_c.c
@@ -335,4 +335,3 @@ int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
335 335
336 return 0; 336 return 0;
337} 337}
338
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
index d416e85589e1..01512670c6a6 100644
--- a/drivers/media/dvb/frontends/cxd2820r_core.c
+++ b/drivers/media/dvb/frontends/cxd2820r_core.c
@@ -727,70 +727,20 @@ static void cxd2820r_release(struct dvb_frontend *fe)
727 struct cxd2820r_priv *priv = fe->demodulator_priv; 727 struct cxd2820r_priv *priv = fe->demodulator_priv;
728 dbg("%s", __func__); 728 dbg("%s", __func__);
729 729
730 if (fe->ops.info.type == FE_OFDM) { 730 if (fe->ops.info.type == FE_OFDM)
731 i2c_del_adapter(&priv->tuner_i2c_adapter);
732 kfree(priv); 731 kfree(priv);
733 }
734 732
735 return; 733 return;
736} 734}
737 735
738static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter) 736static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
739{
740 return I2C_FUNC_I2C;
741}
742
743static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
744 struct i2c_msg msg[], int num)
745{
746 struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
747 int ret;
748 u8 *obuf = kmalloc(msg[0].len + 2, GFP_KERNEL);
749 struct i2c_msg msg2[2] = {
750 {
751 .addr = priv->cfg.i2c_address,
752 .flags = 0,
753 .len = msg[0].len + 2,
754 .buf = obuf,
755 }, {
756 .addr = priv->cfg.i2c_address,
757 .flags = I2C_M_RD,
758 .len = msg[1].len,
759 .buf = msg[1].buf,
760 }
761 };
762
763 if (!obuf)
764 return -ENOMEM;
765
766 obuf[0] = 0x09;
767 obuf[1] = (msg[0].addr << 1);
768 if (num == 2) { /* I2C read */
769 obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
770 msg2[0].len = msg[0].len + 2 - 1; /* '-1' maybe HW bug ? */
771 }
772 memcpy(&obuf[2], msg[0].buf, msg[0].len);
773
774 ret = i2c_transfer(priv->i2c, msg2, num);
775 if (ret < 0)
776 warn("tuner i2c failed ret:%d", ret);
777
778 kfree(obuf);
779
780 return ret;
781}
782
783static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
784 .master_xfer = cxd2820r_tuner_i2c_xfer,
785 .functionality = cxd2820r_tuner_i2c_func,
786};
787
788struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
789{ 737{
790 struct cxd2820r_priv *priv = fe->demodulator_priv; 738 struct cxd2820r_priv *priv = fe->demodulator_priv;
791 return &priv->tuner_i2c_adapter; 739 dbg("%s: %d", __func__, enable);
740
741 /* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */
742 return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
792} 743}
793EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
794 744
795static struct dvb_frontend_ops cxd2820r_ops[2]; 745static struct dvb_frontend_ops cxd2820r_ops[2];
796 746
@@ -831,18 +781,6 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
831 priv->fe[0].demodulator_priv = priv; 781 priv->fe[0].demodulator_priv = priv;
832 priv->fe[1].demodulator_priv = priv; 782 priv->fe[1].demodulator_priv = priv;
833 783
834 /* create tuner i2c adapter */
835 strlcpy(priv->tuner_i2c_adapter.name,
836 "CXD2820R tuner I2C adapter",
837 sizeof(priv->tuner_i2c_adapter.name));
838 priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
839 priv->tuner_i2c_adapter.algo_data = NULL;
840 i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
841 if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
842 err("tuner I2C bus could not be initialized");
843 goto error;
844 }
845
846 return &priv->fe[0]; 784 return &priv->fe[0];
847 785
848 } else { 786 } else {
@@ -883,6 +821,7 @@ static struct dvb_frontend_ops cxd2820r_ops[2] = {
883 .sleep = cxd2820r_sleep, 821 .sleep = cxd2820r_sleep,
884 822
885 .get_tune_settings = cxd2820r_get_tune_settings, 823 .get_tune_settings = cxd2820r_get_tune_settings,
824 .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,
886 825
887 .get_frontend = cxd2820r_get_frontend, 826 .get_frontend = cxd2820r_get_frontend,
888 827
@@ -911,6 +850,7 @@ static struct dvb_frontend_ops cxd2820r_ops[2] = {
911 .sleep = cxd2820r_sleep, 850 .sleep = cxd2820r_sleep,
912 851
913 .get_tune_settings = cxd2820r_get_tune_settings, 852 .get_tune_settings = cxd2820r_get_tune_settings,
853 .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,
914 854
915 .set_frontend = cxd2820r_set_frontend, 855 .set_frontend = cxd2820r_set_frontend,
916 .get_frontend = cxd2820r_get_frontend, 856 .get_frontend = cxd2820r_get_frontend,
diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h
index 0c0ebc9d5c4a..95539134efdb 100644
--- a/drivers/media/dvb/frontends/cxd2820r_priv.h
+++ b/drivers/media/dvb/frontends/cxd2820r_priv.h
@@ -50,7 +50,6 @@ struct cxd2820r_priv {
50 struct i2c_adapter *i2c; 50 struct i2c_adapter *i2c;
51 struct dvb_frontend fe[2]; 51 struct dvb_frontend fe[2];
52 struct cxd2820r_config cfg; 52 struct cxd2820r_config cfg;
53 struct i2c_adapter tuner_i2c_adapter;
54 53
55 struct mutex fe_lock; /* FE lock */ 54 struct mutex fe_lock; /* FE lock */
56 int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */ 55 int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
index 6582564c930c..a04f9c810101 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t.c
+++ b/drivers/media/dvb/frontends/cxd2820r_t.c
@@ -446,4 +446,3 @@ int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
446 446
447 return 0; 447 return 0;
448} 448}
449
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
index c47b35c8acf1..6548588309f7 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t2.c
+++ b/drivers/media/dvb/frontends/cxd2820r_t2.c
@@ -420,4 +420,3 @@ int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
420 420
421 return 0; 421 return 0;
422} 422}
423
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index b3406ebd57d7..b606fc7f842d 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -438,6 +438,7 @@ static struct cxd2820r_config em28xx_cxd2820r_config = {
438 438
439static struct tda18271_config em28xx_cxd2820r_tda18271_config = { 439static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
440 .output_opt = TDA18271_OUTPUT_LT_OFF, 440 .output_opt = TDA18271_OUTPUT_LT_OFF,
441 .gate = TDA18271_GATE_DIGITAL,
441}; 442};
442 443
443/* ------------------------------------------------------------------ */ 444/* ------------------------------------------------------------------ */
@@ -751,11 +752,9 @@ static int em28xx_dvb_init(struct em28xx *dev)
751 dvb->fe[0] = dvb_attach(cxd2820r_attach, 752 dvb->fe[0] = dvb_attach(cxd2820r_attach,
752 &em28xx_cxd2820r_config, &dev->i2c_adap, NULL); 753 &em28xx_cxd2820r_config, &dev->i2c_adap, NULL);
753 if (dvb->fe[0]) { 754 if (dvb->fe[0]) {
754 struct i2c_adapter *i2c_tuner;
755 i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]);
756 /* FE 0 attach tuner */ 755 /* FE 0 attach tuner */
757 if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, 756 if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
758 i2c_tuner, &em28xx_cxd2820r_tda18271_config)) { 757 &dev->i2c_adap, &em28xx_cxd2820r_tda18271_config)) {
759 dvb_frontend_detach(dvb->fe[0]); 758 dvb_frontend_detach(dvb->fe[0]);
760 result = -EINVAL; 759 result = -EINVAL;
761 goto out_free; 760 goto out_free;
@@ -766,7 +765,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
766 dvb->fe[1]->id = 1; 765 dvb->fe[1]->id = 1;
767 /* FE 1 attach tuner */ 766 /* FE 1 attach tuner */
768 if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60, 767 if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60,
769 i2c_tuner, &em28xx_cxd2820r_tda18271_config)) { 768 &dev->i2c_adap, &em28xx_cxd2820r_tda18271_config)) {
770 dvb_frontend_detach(dvb->fe[1]); 769 dvb_frontend_detach(dvb->fe[1]);
771 /* leave FE 0 still active */ 770 /* leave FE 0 still active */
772 } 771 }