diff options
Diffstat (limited to 'drivers/media/dvb/ttpci')
-rw-r--r-- | drivers/media/dvb/ttpci/budget-ci.c | 52 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/budget.c | 47 |
2 files changed, 41 insertions, 58 deletions
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 49c2a817a06f..461714396331 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/input.h> | 36 | #include <linux/input.h> |
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <media/ir-common.h> | 38 | #include <media/ir-core.h> |
39 | 39 | ||
40 | #include "budget.h" | 40 | #include "budget.h" |
41 | 41 | ||
@@ -54,6 +54,8 @@ | |||
54 | #include "tda1002x.h" | 54 | #include "tda1002x.h" |
55 | #include "tda827x.h" | 55 | #include "tda827x.h" |
56 | 56 | ||
57 | #define MODULE_NAME "budget_ci" | ||
58 | |||
57 | /* | 59 | /* |
58 | * Regarding DEBIADDR_IR: | 60 | * Regarding DEBIADDR_IR: |
59 | * Some CI modules hang if random addresses are read. | 61 | * Some CI modules hang if random addresses are read. |
@@ -80,12 +82,6 @@ | |||
80 | #define SLOTSTATUS_READY 8 | 82 | #define SLOTSTATUS_READY 8 |
81 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | 83 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) |
82 | 84 | ||
83 | /* | ||
84 | * Milliseconds during which a key is regarded as pressed. | ||
85 | * If an identical command arrives within this time, the timer will start over. | ||
86 | */ | ||
87 | #define IR_KEYPRESS_TIMEOUT 250 | ||
88 | |||
89 | /* RC5 device wildcard */ | 85 | /* RC5 device wildcard */ |
90 | #define IR_DEVICE_ANY 255 | 86 | #define IR_DEVICE_ANY 255 |
91 | 87 | ||
@@ -102,12 +98,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
102 | struct budget_ci_ir { | 98 | struct budget_ci_ir { |
103 | struct input_dev *dev; | 99 | struct input_dev *dev; |
104 | struct tasklet_struct msp430_irq_tasklet; | 100 | struct tasklet_struct msp430_irq_tasklet; |
105 | struct timer_list timer_keyup; | ||
106 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ | 101 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ |
107 | char phys[32]; | 102 | char phys[32]; |
108 | struct ir_input_state state; | ||
109 | int rc5_device; | 103 | int rc5_device; |
110 | u32 last_raw; | ||
111 | u32 ir_key; | 104 | u32 ir_key; |
112 | bool have_command; | 105 | bool have_command; |
113 | }; | 106 | }; |
@@ -122,18 +115,11 @@ struct budget_ci { | |||
122 | u8 tuner_pll_address; /* used for philips_tdm1316l configs */ | 115 | u8 tuner_pll_address; /* used for philips_tdm1316l configs */ |
123 | }; | 116 | }; |
124 | 117 | ||
125 | static void msp430_ir_keyup(unsigned long data) | ||
126 | { | ||
127 | struct budget_ci_ir *ir = (struct budget_ci_ir *) data; | ||
128 | ir_input_nokey(ir->dev, &ir->state); | ||
129 | } | ||
130 | |||
131 | static void msp430_ir_interrupt(unsigned long data) | 118 | static void msp430_ir_interrupt(unsigned long data) |
132 | { | 119 | { |
133 | struct budget_ci *budget_ci = (struct budget_ci *) data; | 120 | struct budget_ci *budget_ci = (struct budget_ci *) data; |
134 | struct input_dev *dev = budget_ci->ir.dev; | 121 | struct input_dev *dev = budget_ci->ir.dev; |
135 | u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; | 122 | u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; |
136 | u32 raw; | ||
137 | 123 | ||
138 | /* | 124 | /* |
139 | * The msp430 chip can generate two different bytes, command and device | 125 | * The msp430 chip can generate two different bytes, command and device |
@@ -169,20 +155,12 @@ static void msp430_ir_interrupt(unsigned long data) | |||
169 | return; | 155 | return; |
170 | budget_ci->ir.have_command = false; | 156 | budget_ci->ir.have_command = false; |
171 | 157 | ||
158 | /* FIXME: We should generate complete scancodes with device info */ | ||
172 | if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && | 159 | if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && |
173 | budget_ci->ir.rc5_device != (command & 0x1f)) | 160 | budget_ci->ir.rc5_device != (command & 0x1f)) |
174 | return; | 161 | return; |
175 | 162 | ||
176 | /* Is this a repeated key sequence? (same device, command, toggle) */ | 163 | ir_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0); |
177 | raw = budget_ci->ir.ir_key | (command << 8); | ||
178 | if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) { | ||
179 | ir_input_nokey(dev, &budget_ci->ir.state); | ||
180 | ir_input_keydown(dev, &budget_ci->ir.state, | ||
181 | budget_ci->ir.ir_key); | ||
182 | budget_ci->ir.last_raw = raw; | ||
183 | } | ||
184 | |||
185 | mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT)); | ||
186 | } | 164 | } |
187 | 165 | ||
188 | static int msp430_ir_init(struct budget_ci *budget_ci) | 166 | static int msp430_ir_init(struct budget_ci *budget_ci) |
@@ -190,7 +168,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
190 | struct saa7146_dev *saa = budget_ci->budget.dev; | 168 | struct saa7146_dev *saa = budget_ci->budget.dev; |
191 | struct input_dev *input_dev = budget_ci->ir.dev; | 169 | struct input_dev *input_dev = budget_ci->ir.dev; |
192 | int error; | 170 | int error; |
193 | struct ir_scancode_table *ir_codes; | 171 | char *ir_codes = NULL; |
194 | 172 | ||
195 | 173 | ||
196 | budget_ci->ir.dev = input_dev = input_allocate_device(); | 174 | budget_ci->ir.dev = input_dev = input_allocate_device(); |
@@ -230,7 +208,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
230 | case 0x1011: | 208 | case 0x1011: |
231 | case 0x1012: | 209 | case 0x1012: |
232 | /* The hauppauge keymap is a superset of these remotes */ | 210 | /* The hauppauge keymap is a superset of these remotes */ |
233 | ir_codes = &ir_codes_hauppauge_new_table; | 211 | ir_codes = RC_MAP_HAUPPAUGE_NEW; |
234 | 212 | ||
235 | if (rc5_device < 0) | 213 | if (rc5_device < 0) |
236 | budget_ci->ir.rc5_device = 0x1f; | 214 | budget_ci->ir.rc5_device = 0x1f; |
@@ -239,22 +217,15 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
239 | case 0x1017: | 217 | case 0x1017: |
240 | case 0x101a: | 218 | case 0x101a: |
241 | /* for the Technotrend 1500 bundled remote */ | 219 | /* for the Technotrend 1500 bundled remote */ |
242 | ir_codes = &ir_codes_tt_1500_table; | 220 | ir_codes = RC_MAP_TT_1500; |
243 | break; | 221 | break; |
244 | default: | 222 | default: |
245 | /* unknown remote */ | 223 | /* unknown remote */ |
246 | ir_codes = &ir_codes_budget_ci_old_table; | 224 | ir_codes = RC_MAP_BUDGET_CI_OLD; |
247 | break; | 225 | break; |
248 | } | 226 | } |
249 | 227 | ||
250 | ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5); | 228 | error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME); |
251 | |||
252 | /* initialise the key-up timeout handler */ | ||
253 | init_timer(&budget_ci->ir.timer_keyup); | ||
254 | budget_ci->ir.timer_keyup.function = msp430_ir_keyup; | ||
255 | budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; | ||
256 | budget_ci->ir.last_raw = 0xffff; /* An impossible value */ | ||
257 | error = ir_input_register(input_dev, ir_codes, NULL); | ||
258 | if (error) { | 229 | if (error) { |
259 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); | 230 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); |
260 | return error; | 231 | return error; |
@@ -282,9 +253,6 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) | |||
282 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 253 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
283 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); | 254 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); |
284 | 255 | ||
285 | del_timer_sync(&dev->timer); | ||
286 | ir_input_nokey(dev, &budget_ci->ir.state); | ||
287 | |||
288 | ir_input_unregister(dev); | 256 | ir_input_unregister(dev); |
289 | } | 257 | } |
290 | 258 | ||
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 1500210c06cf..874a10a9d493 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -442,6 +442,7 @@ static struct stv090x_config tt1600_stv090x_config = { | |||
442 | .repeater_level = STV090x_RPTLEVEL_16, | 442 | .repeater_level = STV090x_RPTLEVEL_16, |
443 | 443 | ||
444 | .tuner_init = NULL, | 444 | .tuner_init = NULL, |
445 | .tuner_sleep = NULL, | ||
445 | .tuner_set_mode = NULL, | 446 | .tuner_set_mode = NULL, |
446 | .tuner_set_frequency = NULL, | 447 | .tuner_set_frequency = NULL, |
447 | .tuner_get_frequency = NULL, | 448 | .tuner_get_frequency = NULL, |
@@ -627,22 +628,36 @@ static void frontend_init(struct budget *budget) | |||
627 | &tt1600_stv6110x_config, | 628 | &tt1600_stv6110x_config, |
628 | &budget->i2c_adap); | 629 | &budget->i2c_adap); |
629 | 630 | ||
630 | tt1600_stv090x_config.tuner_init = ctl->tuner_init; | 631 | if (ctl) { |
631 | tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; | 632 | tt1600_stv090x_config.tuner_init = ctl->tuner_init; |
632 | tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; | 633 | tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; |
633 | tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; | 634 | tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; |
634 | tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; | 635 | tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; |
635 | tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; | 636 | tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; |
636 | tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; | 637 | tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; |
637 | tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; | 638 | tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; |
638 | tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; | 639 | tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; |
639 | tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; | 640 | tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; |
640 | 641 | tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; | |
641 | dvb_attach(isl6423_attach, | 642 | tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; |
642 | budget->dvb_frontend, | 643 | |
643 | &budget->i2c_adap, | 644 | /* call the init function once to initialize |
644 | &tt1600_isl6423_config); | 645 | tuner's clock output divider and demod's |
645 | 646 | master clock */ | |
647 | if (budget->dvb_frontend->ops.init) | ||
648 | budget->dvb_frontend->ops.init(budget->dvb_frontend); | ||
649 | |||
650 | if (dvb_attach(isl6423_attach, | ||
651 | budget->dvb_frontend, | ||
652 | &budget->i2c_adap, | ||
653 | &tt1600_isl6423_config) == NULL) { | ||
654 | printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__); | ||
655 | goto error_out; | ||
656 | } | ||
657 | } else { | ||
658 | printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); | ||
659 | goto error_out; | ||
660 | } | ||
646 | } | 661 | } |
647 | } | 662 | } |
648 | break; | 663 | break; |