diff options
author | Steve Kerrison <steve@stevekerrison.com> | 2011-08-09 06:16:21 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-09-03 17:13:41 -0400 |
commit | 0db4bf42baae95ddd457b0c4911e851c9169750e (patch) | |
tree | d22488cc966eaa498838e91f574d8d65dbe75f35 | |
parent | 6fb2bdfa068676f436fd333c460549ed64549c5e (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.h | 9 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cxd2820r_c.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cxd2820r_core.c | 76 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cxd2820r_priv.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cxd2820r_t.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cxd2820r_t2.c | 1 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 7 |
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 | ); |
96 | extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter( | ||
97 | struct dvb_frontend *fe | ||
98 | ); | ||
99 | #else | 96 | #else |
100 | static inline struct dvb_frontend *cxd2820r_attach( | 97 | static 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 | } |
109 | static 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 | ||
738 | static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter) | 736 | static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
739 | { | ||
740 | return I2C_FUNC_I2C; | ||
741 | } | ||
742 | |||
743 | static 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 | |||
783 | static struct i2c_algorithm cxd2820r_tuner_i2c_algo = { | ||
784 | .master_xfer = cxd2820r_tuner_i2c_xfer, | ||
785 | .functionality = cxd2820r_tuner_i2c_func, | ||
786 | }; | ||
787 | |||
788 | struct 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 | } |
793 | EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter); | ||
794 | 744 | ||
795 | static struct dvb_frontend_ops cxd2820r_ops[2]; | 745 | static 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 | ||
439 | static struct tda18271_config em28xx_cxd2820r_tda18271_config = { | 439 | static 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 | } |