aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-04-05 11:18:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-08 05:56:47 -0400
commit48a8a03b5806179f12dd6994a6957f797c13675f (patch)
tree63c7bf1f777bfa446859228375e37a14975eb33a
parenta9bd87c232b87014b20fdf52416f80c5c1e869fc (diff)
[media] cx88: kernel bz#9476: Fix tone setting for Nova-S+ model 92001
Hauppauge Nova-S-Plus DVB-S model 92001 does not lock on horizontal polarisation. According with the info provided at the BZ, model 92002 does. The difference is that, on model 92001, the tone select is done via isl6421, while, on other devices, this is done via cx24123 code. This patch adds a way to override the demod's set_tone at isl6421 driver. In order to avoid regressions, the override is enabled only for cx88 Nova S plus model 92001. For all other models and devices, the set_tone is provided by the demod driver. Patch originally proposed at bz@9476[1] by Michel Meyers and John Donoghue but applying the original patch would break support for all other devices based on isl6421. [1] https://bugzilla.kernel.org/show_bug.cgi?id=9476 Tested-by: Adam Sampson <ats@offog.org> Tested-by: Hans-Peter Jansen <hpj@urpla.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c4
-rw-r--r--drivers/media/dvb-frontends/isl6421.c28
-rw-r--r--drivers/media/dvb-frontends/isl6421.h4
-rw-r--r--drivers/media/pci/cx88/cx88-cards.c1
-rw-r--r--drivers/media/pci/cx88/cx88-dvb.c16
-rw-r--r--drivers/media/pci/cx88/cx88.h1
-rw-r--r--drivers/media/pci/saa7134/saa7134-dvb.c8
7 files changed, 50 insertions, 12 deletions
diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
index 850a6c606750..7e14e90d2922 100644
--- a/drivers/media/common/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
@@ -325,7 +325,7 @@ static int skystar2_rev27_attach(struct flexcop_device *fc,
325 /* enable no_base_addr - no repeated start when reading */ 325 /* enable no_base_addr - no repeated start when reading */
326 fc->fc_i2c_adap[2].no_base_addr = 1; 326 fc->fc_i2c_adap[2].no_base_addr = 1;
327 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 327 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
328 0x08, 1, 1)) { 328 0x08, 1, 1, false)) {
329 err("ISL6421 could NOT be attached"); 329 err("ISL6421 could NOT be attached");
330 goto fail_isl; 330 goto fail_isl;
331 } 331 }
@@ -391,7 +391,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
391 391
392 fc->fc_i2c_adap[2].no_base_addr = 1; 392 fc->fc_i2c_adap[2].no_base_addr = 1;
393 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 393 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
394 0x08, 0, 0)) { 394 0x08, 0, 0, false)) {
395 err("ISL6421 could NOT be attached"); 395 err("ISL6421 could NOT be attached");
396 fc->fc_i2c_adap[2].no_base_addr = 0; 396 fc->fc_i2c_adap[2].no_base_addr = 0;
397 return 0; 397 return 0;
diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c
index 0cb3f0f74c9c..c77002fcc8e2 100644
--- a/drivers/media/dvb-frontends/isl6421.c
+++ b/drivers/media/dvb-frontends/isl6421.c
@@ -89,6 +89,30 @@ static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
89 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; 89 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
90} 90}
91 91
92static int isl6421_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
93{
94 struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
95 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
96 .buf = &isl6421->config,
97 .len = sizeof(isl6421->config) };
98
99 switch (tone) {
100 case SEC_TONE_ON:
101 isl6421->config |= ISL6421_ENT1;
102 break;
103 case SEC_TONE_OFF:
104 isl6421->config &= ~ISL6421_ENT1;
105 break;
106 default:
107 return -EINVAL;
108 }
109
110 isl6421->config |= isl6421->override_or;
111 isl6421->config &= isl6421->override_and;
112
113 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
114}
115
92static void isl6421_release(struct dvb_frontend *fe) 116static void isl6421_release(struct dvb_frontend *fe)
93{ 117{
94 /* power off */ 118 /* power off */
@@ -100,7 +124,7 @@ static void isl6421_release(struct dvb_frontend *fe)
100} 124}
101 125
102struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, 126struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
103 u8 override_set, u8 override_clear) 127 u8 override_set, u8 override_clear, bool override_tone)
104{ 128{
105 struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); 129 struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
106 if (!isl6421) 130 if (!isl6421)
@@ -131,6 +155,8 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter
131 /* override frontend ops */ 155 /* override frontend ops */
132 fe->ops.set_voltage = isl6421_set_voltage; 156 fe->ops.set_voltage = isl6421_set_voltage;
133 fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; 157 fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
158 if (override_tone)
159 fe->ops.set_tone = isl6421_set_tone;
134 160
135 return fe; 161 return fe;
136} 162}
diff --git a/drivers/media/dvb-frontends/isl6421.h b/drivers/media/dvb-frontends/isl6421.h
index e7ca7d12b50a..630e7f8a150e 100644
--- a/drivers/media/dvb-frontends/isl6421.h
+++ b/drivers/media/dvb-frontends/isl6421.h
@@ -42,10 +42,10 @@
42#if IS_ENABLED(CONFIG_DVB_ISL6421) 42#if IS_ENABLED(CONFIG_DVB_ISL6421)
43/* override_set and override_clear control which system register bits (above) to always set & clear */ 43/* override_set and override_clear control which system register bits (above) to always set & clear */
44extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, 44extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
45 u8 override_set, u8 override_clear); 45 u8 override_set, u8 override_clear, bool override_tone);
46#else 46#else
47static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, 47static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
48 u8 override_set, u8 override_clear) 48 u8 override_set, u8 override_clear, bool override_tone)
49{ 49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL; 51 return NULL;
diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
index e2e0b8faf7a4..07b700a9ed7f 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -2855,6 +2855,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2855 core->board.tuner_type = tv.tuner_type; 2855 core->board.tuner_type = tv.tuner_type;
2856 core->tuner_formats = tv.tuner_formats; 2856 core->tuner_formats = tv.tuner_formats;
2857 core->board.radio.type = tv.has_radio ? CX88_RADIO : 0; 2857 core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
2858 core->model = tv.model;
2858 2859
2859 /* Make sure we support the board model */ 2860 /* Make sure we support the board model */
2860 switch (tv.model) 2861 switch (tv.model)
diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c
index 672b267a2d3e..053ed1ba1d85 100644
--- a/drivers/media/pci/cx88/cx88-dvb.c
+++ b/drivers/media/pci/cx88/cx88-dvb.c
@@ -1042,7 +1042,7 @@ static int dvb_register(struct cx8802_dev *dev)
1042 if (!dvb_attach(isl6421_attach, 1042 if (!dvb_attach(isl6421_attach,
1043 fe0->dvb.frontend, 1043 fe0->dvb.frontend,
1044 &dev->core->i2c_adap, 1044 &dev->core->i2c_adap,
1045 0x08, ISL6421_DCL, 0x00)) 1045 0x08, ISL6421_DCL, 0x00, false))
1046 goto frontend_detach; 1046 goto frontend_detach;
1047 } 1047 }
1048 /* MFE frontend 2 */ 1048 /* MFE frontend 2 */
@@ -1279,8 +1279,16 @@ static int dvb_register(struct cx8802_dev *dev)
1279 &hauppauge_novas_config, 1279 &hauppauge_novas_config,
1280 &core->i2c_adap); 1280 &core->i2c_adap);
1281 if (fe0->dvb.frontend) { 1281 if (fe0->dvb.frontend) {
1282 bool override_tone;
1283
1284 if (core->model == 92001)
1285 override_tone = true;
1286 else
1287 override_tone = false;
1288
1282 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, 1289 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1283 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) 1290 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00,
1291 override_tone))
1284 goto frontend_detach; 1292 goto frontend_detach;
1285 } 1293 }
1286 break; 1294 break;
@@ -1403,7 +1411,7 @@ static int dvb_register(struct cx8802_dev *dev)
1403 if (!dvb_attach(isl6421_attach, 1411 if (!dvb_attach(isl6421_attach,
1404 fe0->dvb.frontend, 1412 fe0->dvb.frontend,
1405 &dev->core->i2c_adap, 1413 &dev->core->i2c_adap,
1406 0x08, ISL6421_DCL, 0x00)) 1414 0x08, ISL6421_DCL, 0x00, false))
1407 goto frontend_detach; 1415 goto frontend_detach;
1408 } 1416 }
1409 /* MFE frontend 2 */ 1417 /* MFE frontend 2 */
@@ -1431,7 +1439,7 @@ static int dvb_register(struct cx8802_dev *dev)
1431 if (!dvb_attach(isl6421_attach, 1439 if (!dvb_attach(isl6421_attach,
1432 fe0->dvb.frontend, 1440 fe0->dvb.frontend,
1433 &dev->core->i2c_adap, 1441 &dev->core->i2c_adap,
1434 0x08, ISL6421_DCL, 0x00)) 1442 0x08, ISL6421_DCL, 0x00, false))
1435 goto frontend_detach; 1443 goto frontend_detach;
1436 } 1444 }
1437 break; 1445 break;
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index eca02c2435de..4e29c9deb684 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -334,6 +334,7 @@ struct cx88_core {
334 /* board name */ 334 /* board name */
335 int nr; 335 int nr;
336 char name[32]; 336 char name[32];
337 u32 model;
337 338
338 /* pci stuff */ 339 /* pci stuff */
339 int pci_bus; 340 int pci_bus;
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index 27915e501db9..45271390d7fb 100644
--- a/drivers/media/pci/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -1391,8 +1391,9 @@ static int dvb_init(struct saa7134_dev *dev)
1391 wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); 1391 wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
1392 goto detach_frontend; 1392 goto detach_frontend;
1393 } 1393 }
1394 if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap, 1394 if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
1395 0x08, 0, 0) == NULL) { 1395 &dev->i2c_adap,
1396 0x08, 0, 0, false) == NULL) {
1396 wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); 1397 wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
1397 goto detach_frontend; 1398 goto detach_frontend;
1398 } 1399 }
@@ -1509,7 +1510,8 @@ static int dvb_init(struct saa7134_dev *dev)
1509 goto detach_frontend; 1510 goto detach_frontend;
1510 } 1511 }
1511 if (dvb_attach(isl6421_attach, fe0->dvb.frontend, 1512 if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
1512 &dev->i2c_adap, 0x08, 0, 0) == NULL) { 1513 &dev->i2c_adap,
1514 0x08, 0, 0, false) == NULL) {
1513 wprintk("%s: No ISL6421 found!\n", __func__); 1515 wprintk("%s: No ISL6421 found!\n", __func__);
1514 goto detach_frontend; 1516 goto detach_frontend;
1515 } 1517 }