aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/frontends/Kconfig10
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c145
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h102
-rw-r--r--drivers/media/dvb/ttpci/Kconfig3
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c2
-rw-r--r--drivers/media/dvb/ttpci/budget.c2
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig1
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c28
10 files changed, 169 insertions, 127 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 6d90ff3f71ec..64cd63623b0b 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -216,4 +216,14 @@ config DVB_LGDT330X
216 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 216 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
217 to support this frontend. 217 to support this frontend.
218 218
219
220comment "Miscellaneous devices"
221 depends on DVB_CORE
222
223config DVB_LNBP21
224 tristate "LNBP21 SEC controller"
225 depends on DVB_CORE
226 help
227 An SEC control chip.
228
219endmenu 229endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index d09b6071fbaf..7238e6ef2f22 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
31obj-$(CONFIG_DVB_S5H1420) += s5h1420.o 31obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
32obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o 32obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
33obj-$(CONFIG_DVB_CX24123) += cx24123.o 33obj-$(CONFIG_DVB_CX24123) += cx24123.o
34obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
new file mode 100644
index 000000000000..c9152c1fbc3f
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -0,0 +1,145 @@
1/*
2 * lnbp21.h - driver for lnb supply and control ic lnbp21
3 *
4 * Copyright (C) 2006 Oliver Endriss
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 *
23 *
24 * the project's page is at http://www.linuxtv.org
25 */
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/string.h>
33#include <linux/slab.h>
34
35#include "dvb_frontend.h"
36#include "lnbp21.h"
37
38struct lnbp21 {
39 u8 config;
40 u8 override_or;
41 u8 override_and;
42 struct i2c_adapter *i2c;
43 void (*release_chain)(struct dvb_frontend* fe);
44};
45
46static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
47{
48 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
49 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
50 .buf = &lnbp21->config,
51 .len = sizeof(lnbp21->config) };
52
53 lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
54
55 switch(voltage) {
56 case SEC_VOLTAGE_OFF:
57 break;
58 case SEC_VOLTAGE_13:
59 lnbp21->config |= LNBP21_EN;
60 break;
61 case SEC_VOLTAGE_18:
62 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
63 break;
64 default:
65 return -EINVAL;
66 };
67
68 lnbp21->config |= lnbp21->override_or;
69 lnbp21->config &= lnbp21->override_and;
70
71 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
72}
73
74static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
75{
76 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
77 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
78 .buf = &lnbp21->config,
79 .len = sizeof(lnbp21->config) };
80
81 if (arg)
82 lnbp21->config |= LNBP21_LLC;
83 else
84 lnbp21->config &= ~LNBP21_LLC;
85
86 lnbp21->config |= lnbp21->override_or;
87 lnbp21->config &= lnbp21->override_and;
88
89 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
90}
91
92static void lnbp21_release(struct dvb_frontend *fe)
93{
94 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
95
96 /* LNBP power off */
97 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
98
99 /* free data & call next release routine */
100 fe->ops->release = lnbp21->release_chain;
101 kfree(fe->misc_priv);
102 fe->misc_priv = NULL;
103 if (fe->ops->release)
104 fe->ops->release(fe);
105}
106
107int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
108{
109 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
110 if (!lnbp21)
111 return -ENOMEM;
112
113 /* default configuration */
114 lnbp21->config = LNBP21_ISEL;
115 lnbp21->i2c = i2c;
116 fe->misc_priv = lnbp21;
117
118 /* bits which should be forced to '1' */
119 lnbp21->override_or = override_set;
120
121 /* bits which should be forced to '0' */
122 lnbp21->override_and = ~override_clear;
123
124 /* detect if it is present or not */
125 if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
126 kfree(lnbp21);
127 fe->misc_priv = NULL;
128 return -EIO;
129 }
130
131 /* install release callback */
132 lnbp21->release_chain = fe->ops->release;
133 fe->ops->release = lnbp21_release;
134
135 /* override frontend ops */
136 fe->ops->set_voltage = lnbp21_set_voltage;
137 fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
138
139 return 0;
140}
141EXPORT_SYMBOL(lnbp21_attach);
142
143MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
144MODULE_AUTHOR("Oliver Endriss");
145MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 0dcbe61b61b1..047a4ab68c01 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -27,7 +27,7 @@
27#ifndef _LNBP21_H 27#ifndef _LNBP21_H
28#define _LNBP21_H 28#define _LNBP21_H
29 29
30/* system register */ 30/* system register bits */
31#define LNBP21_OLF 0x01 31#define LNBP21_OLF 0x01
32#define LNBP21_OTF 0x02 32#define LNBP21_OTF 0x02
33#define LNBP21_EN 0x04 33#define LNBP21_EN 0x04
@@ -37,103 +37,9 @@
37#define LNBP21_ISEL 0x40 37#define LNBP21_ISEL 0x40
38#define LNBP21_PCL 0x80 38#define LNBP21_PCL 0x80
39 39
40struct lnbp21 { 40#include <linux/dvb/frontend.h>
41 u8 config;
42 u8 override_or;
43 u8 override_and;
44 struct i2c_adapter *i2c;
45 void (*release_chain)(struct dvb_frontend* fe);
46};
47 41
48static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 42/* override_set and override_clear control which system register bits (above) to always set & clear */
49{ 43extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
50 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
51 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
52 .buf = &lnbp21->config,
53 .len = sizeof(lnbp21->config) };
54
55 lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
56
57 switch(voltage) {
58 case SEC_VOLTAGE_OFF:
59 break;
60 case SEC_VOLTAGE_13:
61 lnbp21->config |= LNBP21_EN;
62 break;
63 case SEC_VOLTAGE_18:
64 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
65 break;
66 default:
67 return -EINVAL;
68 };
69
70 lnbp21->config |= lnbp21->override_or;
71 lnbp21->config &= lnbp21->override_and;
72
73 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
74}
75
76static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77{
78 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
79 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
80 .buf = &lnbp21->config,
81 .len = sizeof(lnbp21->config) };
82
83 if (arg)
84 lnbp21->config |= LNBP21_LLC;
85 else
86 lnbp21->config &= ~LNBP21_LLC;
87
88 lnbp21->config |= lnbp21->override_or;
89 lnbp21->config &= lnbp21->override_and;
90
91 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
92}
93
94static void lnbp21_exit(struct dvb_frontend *fe)
95{
96 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
97
98 /* LNBP power off */
99 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
100
101 /* free data & call next release routine */
102 fe->ops->release = lnbp21->release_chain;
103 kfree(fe->misc_priv);
104 fe->misc_priv = NULL;
105 if (fe->ops->release)
106 fe->ops->release(fe);
107}
108
109static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
110{
111 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
112
113 if (!lnbp21)
114 return -ENOMEM;
115
116 /* default configuration */
117 lnbp21->config = LNBP21_ISEL;
118
119 /* bits which should be forced to '1' */
120 lnbp21->override_or = override_set;
121
122 /* bits which should be forced to '0' */
123 lnbp21->override_and = ~override_clear;
124
125 /* install release callback */
126 lnbp21->release_chain = fe->ops->release;
127 fe->ops->release = lnbp21_exit;
128
129 /* override frontend ops */
130 fe->ops->set_voltage = lnbp21_set_voltage;
131 fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
132
133 lnbp21->i2c = i2c;
134 fe->misc_priv = lnbp21;
135
136 return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
137}
138 44
139#endif 45#endif
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index b5ac7dfde52f..987881fa988c 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -10,6 +10,7 @@ config DVB_AV7110
10 select DVB_SP8870 10 select DVB_SP8870
11 select DVB_STV0297 11 select DVB_STV0297
12 select DVB_L64781 12 select DVB_L64781
13 select DVB_LNBP21
13 help 14 help
14 Support for SAA7146 and AV7110 based DVB cards as produced 15 Support for SAA7146 and AV7110 based DVB cards as produced
15 by Fujitsu-Siemens, Technotrend, Hauppauge and others. 16 by Fujitsu-Siemens, Technotrend, Hauppauge and others.
@@ -67,6 +68,7 @@ config DVB_BUDGET
67 select DVB_TDA8083 68 select DVB_TDA8083
68 select DVB_TDA10021 69 select DVB_TDA10021
69 select DVB_S5H1420 70 select DVB_S5H1420
71 select DVB_LNBP21
70 help 72 help
71 Support for simple SAA7146 based DVB cards 73 Support for simple SAA7146 based DVB cards
72 (so called Budget- or Nova-PCI cards) without onboard 74 (so called Budget- or Nova-PCI cards) without onboard
@@ -84,6 +86,7 @@ config DVB_BUDGET_CI
84 select DVB_STV0297 86 select DVB_STV0297
85 select DVB_STV0299 87 select DVB_STV0299
86 select DVB_TDA1004X 88 select DVB_TDA1004X
89 select DVB_LNBP21
87 help 90 help
88 Support for simple SAA7146 based DVB cards 91 Support for simple SAA7146 based DVB cards
89 (so called Budget- or Nova-PCI cards) without onboard 92 (so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 5f976d5eda42..1a6d7a3bf459 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -2223,7 +2223,7 @@ static int frontend_init(struct av7110 *av7110)
2223 av7110->fe->ops->tuner_ops.set_params = alps_bsbe1_tuner_set_params; 2223 av7110->fe->ops->tuner_ops.set_params = alps_bsbe1_tuner_set_params;
2224 av7110->fe->tuner_priv = &av7110->i2c_adap; 2224 av7110->fe->tuner_priv = &av7110->i2c_adap;
2225 2225
2226 if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { 2226 if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) {
2227 printk("dvb-ttpci: LNBP21 not found!\n"); 2227 printk("dvb-ttpci: LNBP21 not found!\n");
2228 if (av7110->fe->ops->release) 2228 if (av7110->fe->ops->release)
2229 av7110->fe->ops->release(av7110->fe); 2229 av7110->fe->ops->release(av7110->fe);
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index ed610e56b91e..145e12f9a7f6 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -1043,7 +1043,7 @@ static void frontend_init(struct budget_ci *budget_ci)
1043 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; 1043 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1044 1044
1045 budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; 1045 budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
1046 if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { 1046 if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
1047 printk("%s: No LNBP21 found!\n", __FUNCTION__); 1047 printk("%s: No LNBP21 found!\n", __FUNCTION__);
1048 if (budget_ci->budget.dvb_frontend->ops->release) 1048 if (budget_ci->budget.dvb_frontend->ops->release)
1049 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); 1049 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index a231975cbe3c..d98395fefc95 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -423,7 +423,7 @@ static void frontend_init(struct budget *budget)
423 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); 423 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
424 if (budget->dvb_frontend) { 424 if (budget->dvb_frontend) {
425 budget->dvb_frontend->ops->tuner_ops.set_params = s5h1420_tuner_set_params; 425 budget->dvb_frontend->ops->tuner_ops.set_params = s5h1420_tuner_set_params;
426 if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { 426 if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) {
427 printk("%s: No LNBP21 found!\n", __FUNCTION__); 427 printk("%s: No LNBP21 found!\n", __FUNCTION__);
428 goto error_out; 428 goto error_out;
429 } 429 }
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index 914587d52b57..d1004e863290 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -6,6 +6,7 @@ config DVB_TTUSB_BUDGET
6 select DVB_VES1820 6 select DVB_VES1820
7 select DVB_TDA8083 7 select DVB_TDA8083
8 select DVB_STV0299 8 select DVB_STV0299
9 select DVB_LNBP21
9 help 10 help
10 Support for external USB adapters designed by Technotrend and 11 Support for external USB adapters designed by Technotrend and
11 produced by Hauppauge, shipped under the brand name 'Nova-USB'. 12 produced by Hauppauge, shipped under the brand name 'Nova-USB'.
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index cd19ba628101..71581303b0ea 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -30,6 +30,7 @@
30#include "tda1004x.h" 30#include "tda1004x.h"
31#include "stv0299.h" 31#include "stv0299.h"
32#include "tda8083.h" 32#include "tda8083.h"
33#include "lnbp21.h"
33 34
34#include <linux/dvb/frontend.h> 35#include <linux/dvb/frontend.h>
35#include <linux/dvb/dmx.h> 36#include <linux/dvb/dmx.h>
@@ -486,31 +487,6 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe,
486} 487}
487#endif 488#endif
488 489
489static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
490{
491 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
492 int ret;
493 u8 data[1];
494 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
495
496 switch(voltage) {
497 case SEC_VOLTAGE_OFF:
498 data[0] = 0x00;
499 break;
500 case SEC_VOLTAGE_13:
501 data[0] = 0x44;
502 break;
503 case SEC_VOLTAGE_18:
504 data[0] = 0x4c;
505 break;
506 default:
507 return -EINVAL;
508 };
509
510 ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1);
511 return (ret != 1) ? -EIO : 0;
512}
513
514static int ttusb_update_lnb(struct ttusb *ttusb) 490static int ttusb_update_lnb(struct ttusb *ttusb)
515{ 491{
516 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, 492 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
@@ -1415,7 +1391,7 @@ static void frontend_init(struct ttusb* ttusb)
1415 1391
1416 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 1392 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1417 alps_stv0299_config.inittab = alps_bsbe1_inittab; 1393 alps_stv0299_config.inittab = alps_bsbe1_inittab;
1418 ttusb->fe->ops->set_voltage = lnbp21_set_voltage; 1394 lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0);
1419 } else { // ALPS BSRU6 1395 } else { // ALPS BSRU6
1420 ttusb->fe->ops->set_voltage = ttusb_set_voltage; 1396 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1421 } 1397 }