aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/budget-ci.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/media/dvb/ttpci/budget-ci.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/media/dvb/ttpci/budget-ci.c')
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 13ac9e3ab121..926f299b5225 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -26,16 +26,15 @@
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 * 27 *
28 * 28 *
29 * the project's page is at http://www.linuxtv.org/dvb/ 29 * the project's page is at http://www.linuxtv.org/
30 */ 30 */
31 31
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/errno.h> 33#include <linux/errno.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/input.h>
37#include <linux/spinlock.h> 36#include <linux/spinlock.h>
38#include <media/ir-core.h> 37#include <media/rc-core.h>
39 38
40#include "budget.h" 39#include "budget.h"
41 40
@@ -53,6 +52,7 @@
53#include "bsru6.h" 52#include "bsru6.h"
54#include "tda1002x.h" 53#include "tda1002x.h"
55#include "tda827x.h" 54#include "tda827x.h"
55#include "bsbe1-d01a.h"
56 56
57#define MODULE_NAME "budget_ci" 57#define MODULE_NAME "budget_ci"
58 58
@@ -96,13 +96,14 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
96DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 96DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
97 97
98struct budget_ci_ir { 98struct budget_ci_ir {
99 struct input_dev *dev; 99 struct rc_dev *dev;
100 struct tasklet_struct msp430_irq_tasklet; 100 struct tasklet_struct msp430_irq_tasklet;
101 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ 101 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
102 char phys[32]; 102 char phys[32];
103 int rc5_device; 103 int rc5_device;
104 u32 ir_key; 104 u32 ir_key;
105 bool have_command; 105 bool have_command;
106 bool full_rc5; /* Outputs a full RC5 code */
106}; 107};
107 108
108struct budget_ci { 109struct budget_ci {
@@ -118,7 +119,7 @@ struct budget_ci {
118static void msp430_ir_interrupt(unsigned long data) 119static void msp430_ir_interrupt(unsigned long data)
119{ 120{
120 struct budget_ci *budget_ci = (struct budget_ci *) data; 121 struct budget_ci *budget_ci = (struct budget_ci *) data;
121 struct input_dev *dev = budget_ci->ir.dev; 122 struct rc_dev *dev = budget_ci->ir.dev;
122 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; 123 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
123 124
124 /* 125 /*
@@ -155,24 +156,29 @@ static void msp430_ir_interrupt(unsigned long data)
155 return; 156 return;
156 budget_ci->ir.have_command = false; 157 budget_ci->ir.have_command = false;
157 158
158 /* FIXME: We should generate complete scancodes with device info */
159 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && 159 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
160 budget_ci->ir.rc5_device != (command & 0x1f)) 160 budget_ci->ir.rc5_device != (command & 0x1f))
161 return; 161 return;
162 162
163 ir_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0); 163 if (budget_ci->ir.full_rc5) {
164 rc_keydown(dev,
165 budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
166 (command & 0x20) ? 1 : 0);
167 return;
168 }
169
170 /* FIXME: We should generate complete scancodes for all devices */
171 rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
164} 172}
165 173
166static int msp430_ir_init(struct budget_ci *budget_ci) 174static int msp430_ir_init(struct budget_ci *budget_ci)
167{ 175{
168 struct saa7146_dev *saa = budget_ci->budget.dev; 176 struct saa7146_dev *saa = budget_ci->budget.dev;
169 struct input_dev *input_dev = budget_ci->ir.dev; 177 struct rc_dev *dev;
170 int error; 178 int error;
171 char *ir_codes = NULL;
172 179
173 180 dev = rc_allocate_device();
174 budget_ci->ir.dev = input_dev = input_allocate_device(); 181 if (!dev) {
175 if (!input_dev) {
176 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); 182 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
177 return -ENOMEM; 183 return -ENOMEM;
178 } 184 }
@@ -182,19 +188,20 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
182 snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys), 188 snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
183 "pci-%s/ir0", pci_name(saa->pci)); 189 "pci-%s/ir0", pci_name(saa->pci));
184 190
185 input_dev->name = budget_ci->ir.name; 191 dev->driver_name = MODULE_NAME;
186 192 dev->input_name = budget_ci->ir.name;
187 input_dev->phys = budget_ci->ir.phys; 193 dev->input_phys = budget_ci->ir.phys;
188 input_dev->id.bustype = BUS_PCI; 194 dev->input_id.bustype = BUS_PCI;
189 input_dev->id.version = 1; 195 dev->input_id.version = 1;
196 dev->scanmask = 0xff;
190 if (saa->pci->subsystem_vendor) { 197 if (saa->pci->subsystem_vendor) {
191 input_dev->id.vendor = saa->pci->subsystem_vendor; 198 dev->input_id.vendor = saa->pci->subsystem_vendor;
192 input_dev->id.product = saa->pci->subsystem_device; 199 dev->input_id.product = saa->pci->subsystem_device;
193 } else { 200 } else {
194 input_dev->id.vendor = saa->pci->vendor; 201 dev->input_id.vendor = saa->pci->vendor;
195 input_dev->id.product = saa->pci->device; 202 dev->input_id.product = saa->pci->device;
196 } 203 }
197 input_dev->dev.parent = &saa->pci->dev; 204 dev->dev.parent = &saa->pci->dev;
198 205
199 if (rc5_device < 0) 206 if (rc5_device < 0)
200 budget_ci->ir.rc5_device = IR_DEVICE_ANY; 207 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -208,7 +215,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
208 case 0x1011: 215 case 0x1011:
209 case 0x1012: 216 case 0x1012:
210 /* The hauppauge keymap is a superset of these remotes */ 217 /* The hauppauge keymap is a superset of these remotes */
211 ir_codes = RC_MAP_HAUPPAUGE_NEW; 218 dev->map_name = RC_MAP_HAUPPAUGE;
219 budget_ci->ir.full_rc5 = true;
212 220
213 if (rc5_device < 0) 221 if (rc5_device < 0)
214 budget_ci->ir.rc5_device = 0x1f; 222 budget_ci->ir.rc5_device = 0x1f;
@@ -217,24 +225,24 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
217 case 0x1017: 225 case 0x1017:
218 case 0x1019: 226 case 0x1019:
219 case 0x101a: 227 case 0x101a:
228 case 0x101b:
220 /* for the Technotrend 1500 bundled remote */ 229 /* for the Technotrend 1500 bundled remote */
221 ir_codes = RC_MAP_TT_1500; 230 dev->map_name = RC_MAP_TT_1500;
222 break; 231 break;
223 default: 232 default:
224 /* unknown remote */ 233 /* unknown remote */
225 ir_codes = RC_MAP_BUDGET_CI_OLD; 234 dev->map_name = RC_MAP_BUDGET_CI_OLD;
226 break; 235 break;
227 } 236 }
228 237
229 error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME); 238 error = rc_register_device(dev);
230 if (error) { 239 if (error) {
231 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); 240 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
241 rc_free_device(dev);
232 return error; 242 return error;
233 } 243 }
234 244
235 /* note: these must be after input_register_device */ 245 budget_ci->ir.dev = dev;
236 input_dev->rep[REP_DELAY] = 400;
237 input_dev->rep[REP_PERIOD] = 250;
238 246
239 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, 247 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
240 (unsigned long) budget_ci); 248 (unsigned long) budget_ci);
@@ -248,13 +256,12 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
248static void msp430_ir_deinit(struct budget_ci *budget_ci) 256static void msp430_ir_deinit(struct budget_ci *budget_ci)
249{ 257{
250 struct saa7146_dev *saa = budget_ci->budget.dev; 258 struct saa7146_dev *saa = budget_ci->budget.dev;
251 struct input_dev *dev = budget_ci->ir.dev;
252 259
253 SAA7146_IER_DISABLE(saa, MASK_06); 260 SAA7146_IER_DISABLE(saa, MASK_06);
254 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 261 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
255 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); 262 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
256 263
257 ir_input_unregister(dev); 264 rc_unregister_device(budget_ci->ir.dev);
258} 265}
259 266
260static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) 267static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
@@ -1383,6 +1390,23 @@ static void frontend_init(struct budget_ci *budget_ci)
1383 } 1390 }
1384 break; 1391 break;
1385 1392
1393 case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
1394 budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
1395 if (budget_ci->budget.dvb_frontend) {
1396 if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
1397 if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1398 printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
1399 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1400 budget_ci->budget.dvb_frontend = NULL;
1401 }
1402 } else {
1403 printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
1404 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1405 budget_ci->budget.dvb_frontend = NULL;
1406 }
1407 }
1408 break;
1409
1386 case 0x1019: // TT S2-3200 PCI 1410 case 0x1019: // TT S2-3200 PCI
1387 /* 1411 /*
1388 * NOTE! on some STB0899 versions, the internal PLL takes a longer time 1412 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
@@ -1513,6 +1537,7 @@ MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1513MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); 1537MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1514MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); 1538MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1515MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); 1539MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1540MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
1516 1541
1517static struct pci_device_id pci_tbl[] = { 1542static struct pci_device_id pci_tbl[] = {
1518 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), 1543 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1523,6 +1548,7 @@ static struct pci_device_id pci_tbl[] = {
1523 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), 1548 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1524 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), 1549 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1525 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), 1550 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1551 MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
1526 { 1552 {
1527 .vendor = 0, 1553 .vendor = 0,
1528 } 1554 }