aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Klötzke <jan@kloetzke.net>2015-06-06 15:58:13 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-06-10 10:58:24 -0400
commita96762da0cfcbe27f18febb84797269cd9faf791 (patch)
treefc5d8339e60fa9efdd7306d54a3840992d918b28
parent1c35cf9ccac5cf32cd865e6a62dfd16dd50ad5dd (diff)
[media] mantis: add remote control support
The embedded UART is apparently used to receive decoded IR (RC5?) codes. Forward these scan codes to the RC framework and (where known) add corresponding mapping tables to translate them into regular keys. This patch has been tested on a TechniSat CableStar HD2. The mappings of other rc-maps were taken from Christoph Pinkl's patch (http://patchwork.linuxtv.org/patch/7217/) and the s2-liplianin repository. The major difference to Christoph's patch is a reworked interrupt handling of the UART because the RX interrupt is apparently level triggered and requires masking until the FIFO is read by the UART worker. Signed-off-by: Jan Klötzke <jan@kloetzke.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/pci/mantis/hopper_cards.c13
-rw-r--r--drivers/media/pci/mantis/mantis_cards.c57
-rw-r--r--drivers/media/pci/mantis/mantis_common.h33
-rw-r--r--drivers/media/pci/mantis/mantis_dma.c5
-rw-r--r--drivers/media/pci/mantis/mantis_i2c.c8
-rw-r--r--drivers/media/pci/mantis/mantis_input.c106
-rw-r--r--drivers/media/pci/mantis/mantis_input.h28
-rw-r--r--drivers/media/pci/mantis/mantis_pcmcia.c4
-rw-r--r--drivers/media/pci/mantis/mantis_uart.c62
9 files changed, 166 insertions, 150 deletions
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index 104914a5bf06..97b7a3220dbd 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -106,6 +106,9 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
106 } 106 }
107 if (stat & MANTIS_INT_IRQ1) { 107 if (stat & MANTIS_INT_IRQ1) {
108 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); 108 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
109 spin_lock(&mantis->intmask_lock);
110 mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, MANTIS_INT_MASK);
111 spin_unlock(&mantis->intmask_lock);
109 schedule_work(&mantis->uart_work); 112 schedule_work(&mantis->uart_work);
110 } 113 }
111 if (stat & MANTIS_INT_OCERR) { 114 if (stat & MANTIS_INT_OCERR) {
@@ -154,6 +157,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
154static int hopper_pci_probe(struct pci_dev *pdev, 157static int hopper_pci_probe(struct pci_dev *pdev,
155 const struct pci_device_id *pci_id) 158 const struct pci_device_id *pci_id)
156{ 159{
160 struct mantis_pci_drvdata *drvdata;
157 struct mantis_pci *mantis; 161 struct mantis_pci *mantis;
158 struct mantis_hwconfig *config; 162 struct mantis_hwconfig *config;
159 int err = 0; 163 int err = 0;
@@ -165,12 +169,16 @@ static int hopper_pci_probe(struct pci_dev *pdev,
165 goto fail0; 169 goto fail0;
166 } 170 }
167 171
172 drvdata = (struct mantis_pci_drvdata *) pci_id->driver_data;
168 mantis->num = devs; 173 mantis->num = devs;
169 mantis->verbose = verbose; 174 mantis->verbose = verbose;
170 mantis->pdev = pdev; 175 mantis->pdev = pdev;
171 config = (struct mantis_hwconfig *) pci_id->driver_data; 176 config = drvdata->hwconfig;
172 config->irq_handler = &hopper_irq_handler; 177 config->irq_handler = &hopper_irq_handler;
173 mantis->hwconfig = config; 178 mantis->hwconfig = config;
179 mantis->rc_map_name = drvdata->rc_map_name;
180
181 spin_lock_init(&mantis->intmask_lock);
174 182
175 err = mantis_pci_init(mantis); 183 err = mantis_pci_init(mantis);
176 if (err) { 184 if (err) {
@@ -247,7 +255,8 @@ static void hopper_pci_remove(struct pci_dev *pdev)
247} 255}
248 256
249static struct pci_device_id hopper_pci_table[] = { 257static struct pci_device_id hopper_pci_table[] = {
250 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), 258 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config,
259 NULL),
251 { } 260 { }
252}; 261};
253 262
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 9861a8cf1dce..6b64bfd938b6 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <asm/irq.h> 26#include <asm/irq.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <media/rc-map.h>
28 29
29#include "dmxdev.h" 30#include "dmxdev.h"
30#include "dvbdev.h" 31#include "dvbdev.h"
@@ -49,6 +50,7 @@
49#include "mantis_pci.h" 50#include "mantis_pci.h"
50#include "mantis_i2c.h" 51#include "mantis_i2c.h"
51#include "mantis_reg.h" 52#include "mantis_reg.h"
53#include "mantis_input.h"
52 54
53static unsigned int verbose; 55static unsigned int verbose;
54module_param(verbose, int, 0644); 56module_param(verbose, int, 0644);
@@ -114,6 +116,9 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
114 } 116 }
115 if (stat & MANTIS_INT_IRQ1) { 117 if (stat & MANTIS_INT_IRQ1) {
116 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); 118 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
119 spin_lock(&mantis->intmask_lock);
120 mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, MANTIS_INT_MASK);
121 spin_unlock(&mantis->intmask_lock);
117 schedule_work(&mantis->uart_work); 122 schedule_work(&mantis->uart_work);
118 } 123 }
119 if (stat & MANTIS_INT_OCERR) { 124 if (stat & MANTIS_INT_OCERR) {
@@ -162,6 +167,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
162static int mantis_pci_probe(struct pci_dev *pdev, 167static int mantis_pci_probe(struct pci_dev *pdev,
163 const struct pci_device_id *pci_id) 168 const struct pci_device_id *pci_id)
164{ 169{
170 struct mantis_pci_drvdata *drvdata;
165 struct mantis_pci *mantis; 171 struct mantis_pci *mantis;
166 struct mantis_hwconfig *config; 172 struct mantis_hwconfig *config;
167 int err = 0; 173 int err = 0;
@@ -172,12 +178,16 @@ static int mantis_pci_probe(struct pci_dev *pdev,
172 return -ENOMEM; 178 return -ENOMEM;
173 } 179 }
174 180
181 drvdata = (struct mantis_pci_drvdata *) pci_id->driver_data;
175 mantis->num = devs; 182 mantis->num = devs;
176 mantis->verbose = verbose; 183 mantis->verbose = verbose;
177 mantis->pdev = pdev; 184 mantis->pdev = pdev;
178 config = (struct mantis_hwconfig *) pci_id->driver_data; 185 config = drvdata->hwconfig;
179 config->irq_handler = &mantis_irq_handler; 186 config->irq_handler = &mantis_irq_handler;
180 mantis->hwconfig = config; 187 mantis->hwconfig = config;
188 mantis->rc_map_name = drvdata->rc_map_name;
189
190 spin_lock_init(&mantis->intmask_lock);
181 191
182 err = mantis_pci_init(mantis); 192 err = mantis_pci_init(mantis);
183 if (err) { 193 if (err) {
@@ -215,16 +225,25 @@ static int mantis_pci_probe(struct pci_dev *pdev,
215 goto err_dma_exit; 225 goto err_dma_exit;
216 } 226 }
217 227
228 err = mantis_input_init(mantis);
229 if (err < 0) {
230 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
231 goto err_dvb_exit;
232 }
233
218 err = mantis_uart_init(mantis); 234 err = mantis_uart_init(mantis);
219 if (err < 0) { 235 if (err < 0) {
220 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); 236 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err);
221 goto err_dvb_exit; 237 goto err_input_exit;
222 } 238 }
223 239
224 devs++; 240 devs++;
225 241
226 return 0; 242 return 0;
227 243
244err_input_exit:
245 mantis_input_exit(mantis);
246
228err_dvb_exit: 247err_dvb_exit:
229 mantis_dvb_exit(mantis); 248 mantis_dvb_exit(mantis);
230 249
@@ -250,6 +269,7 @@ static void mantis_pci_remove(struct pci_dev *pdev)
250 if (mantis) { 269 if (mantis) {
251 270
252 mantis_uart_exit(mantis); 271 mantis_uart_exit(mantis);
272 mantis_input_exit(mantis);
253 mantis_dvb_exit(mantis); 273 mantis_dvb_exit(mantis);
254 mantis_dma_exit(mantis); 274 mantis_dma_exit(mantis);
255 mantis_i2c_exit(mantis); 275 mantis_i2c_exit(mantis);
@@ -260,17 +280,28 @@ static void mantis_pci_remove(struct pci_dev *pdev)
260} 280}
261 281
262static struct pci_device_id mantis_pci_table[] = { 282static struct pci_device_id mantis_pci_table[] = {
263 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), 283 MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config,
264 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), 284 RC_MAP_TECHNISAT_TS35),
265 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), 285 MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config,
266 MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), 286 NULL),
267 MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), 287 MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config,
268 MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), 288 NULL),
269 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), 289 MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config,
270 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), 290 RC_MAP_TERRATEC_CINERGY_C_PCI),
271 MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), 291 MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config,
272 MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config), 292 RC_MAP_TERRATEC_CINERGY_S2_HD),
273 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), 293 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config,
294 NULL),
295 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config,
296 NULL),
297 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config,
298 RC_MAP_TWINHAN_DTV_CAB_CI),
299 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config,
300 RC_MAP_TWINHAN_DTV_CAB_CI),
301 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config,
302 NULL),
303 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config,
304 NULL),
274 { } 305 { }
275}; 306};
276 307
diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h
index 8ff448bb792d..d48778a366a9 100644
--- a/drivers/media/pci/mantis/mantis_common.h
+++ b/drivers/media/pci/mantis/mantis_common.h
@@ -25,6 +25,7 @@
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/workqueue.h> 26#include <linux/workqueue.h>
27 27
28#include "mantis_reg.h"
28#include "mantis_uart.h" 29#include "mantis_uart.h"
29 30
30#include "mantis_link.h" 31#include "mantis_link.h"
@@ -68,12 +69,13 @@
68#define TECHNISAT 0x1ae4 69#define TECHNISAT 0x1ae4
69#define TERRATEC 0x153b 70#define TERRATEC 0x153b
70 71
71#define MAKE_ENTRY(__subven, __subdev, __configptr) { \ 72#define MAKE_ENTRY(__subven, __subdev, __configptr, __rc) { \
72 .vendor = TWINHAN_TECHNOLOGIES, \ 73 .vendor = TWINHAN_TECHNOLOGIES, \
73 .device = MANTIS, \ 74 .device = MANTIS, \
74 .subvendor = (__subven), \ 75 .subvendor = (__subven), \
75 .subdevice = (__subdev), \ 76 .subdevice = (__subdev), \
76 .driver_data = (unsigned long) (__configptr) \ 77 .driver_data = (unsigned long) \
78 &(struct mantis_pci_drvdata){__configptr, __rc} \
77} 79}
78 80
79enum mantis_i2c_mode { 81enum mantis_i2c_mode {
@@ -101,6 +103,11 @@ struct mantis_hwconfig {
101 enum mantis_i2c_mode i2c_mode; 103 enum mantis_i2c_mode i2c_mode;
102}; 104};
103 105
106struct mantis_pci_drvdata {
107 struct mantis_hwconfig *hwconfig;
108 char *rc_map_name;
109};
110
104struct mantis_pci { 111struct mantis_pci {
105 unsigned int verbose; 112 unsigned int verbose;
106 113
@@ -131,6 +138,7 @@ struct mantis_pci {
131 dma_addr_t risc_dma; 138 dma_addr_t risc_dma;
132 139
133 struct tasklet_struct tasklet; 140 struct tasklet_struct tasklet;
141 spinlock_t intmask_lock;
134 142
135 struct i2c_adapter adapter; 143 struct i2c_adapter adapter;
136 int i2c_rc; 144 int i2c_rc;
@@ -165,15 +173,32 @@ struct mantis_pci {
165 173
166 struct mantis_ca *mantis_ca; 174 struct mantis_ca *mantis_ca;
167 175
168 wait_queue_head_t uart_wq;
169 struct work_struct uart_work; 176 struct work_struct uart_work;
170 spinlock_t uart_lock;
171 177
172 struct rc_dev *rc; 178 struct rc_dev *rc;
173 char input_name[80]; 179 char input_name[80];
174 char input_phys[80]; 180 char input_phys[80];
181 char *rc_map_name;
175}; 182};
176 183
177#define MANTIS_HIF_STATUS (mantis->gpio_status) 184#define MANTIS_HIF_STATUS (mantis->gpio_status)
178 185
186static inline void mantis_mask_ints(struct mantis_pci *mantis, u32 mask)
187{
188 unsigned long flags;
189
190 spin_lock_irqsave(&mantis->intmask_lock, flags);
191 mmwrite(mmread(MANTIS_INT_MASK) & ~mask, MANTIS_INT_MASK);
192 spin_unlock_irqrestore(&mantis->intmask_lock, flags);
193}
194
195static inline void mantis_unmask_ints(struct mantis_pci *mantis, u32 mask)
196{
197 unsigned long flags;
198
199 spin_lock_irqsave(&mantis->intmask_lock, flags);
200 mmwrite(mmread(MANTIS_INT_MASK) | mask, MANTIS_INT_MASK);
201 spin_unlock_irqrestore(&mantis->intmask_lock, flags);
202}
203
179#endif /* __MANTIS_COMMON_H */ 204#endif /* __MANTIS_COMMON_H */
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c
index 566c407175a4..1d59c7e039f7 100644
--- a/drivers/media/pci/mantis/mantis_dma.c
+++ b/drivers/media/pci/mantis/mantis_dma.c
@@ -190,7 +190,7 @@ void mantis_dma_start(struct mantis_pci *mantis)
190 mmwrite(0, MANTIS_DMA_CTL); 190 mmwrite(0, MANTIS_DMA_CTL);
191 mantis->last_block = mantis->busy_block = 0; 191 mantis->last_block = mantis->busy_block = 0;
192 192
193 mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); 193 mantis_unmask_ints(mantis, MANTIS_INT_RISCI);
194 194
195 mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN 195 mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN
196 | MANTIS_RISC_EN, MANTIS_DMA_CTL); 196 | MANTIS_RISC_EN, MANTIS_DMA_CTL);
@@ -209,8 +209,7 @@ void mantis_dma_stop(struct mantis_pci *mantis)
209 209
210 mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); 210 mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT);
211 211
212 mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | 212 mantis_mask_ints(mantis, MANTIS_INT_RISCI | MANTIS_INT_RISCEN);
213 MANTIS_INT_RISCEN), MANTIS_INT_MASK);
214} 213}
215 214
216 215
diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c
index 895ddba3c0fb..a93823490a43 100644
--- a/drivers/media/pci/mantis/mantis_i2c.c
+++ b/drivers/media/pci/mantis/mantis_i2c.c
@@ -245,8 +245,7 @@ int mantis_i2c_init(struct mantis_pci *mantis)
245 intmask = mmread(MANTIS_INT_MASK); 245 intmask = mmread(MANTIS_INT_MASK);
246 mmwrite(intstat, MANTIS_INT_STAT); 246 mmwrite(intstat, MANTIS_INT_STAT);
247 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); 247 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
248 intmask = mmread(MANTIS_INT_MASK); 248 mantis_mask_ints(mantis, MANTIS_INT_I2CDONE);
249 mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
250 249
251 return 0; 250 return 0;
252} 251}
@@ -254,11 +253,8 @@ EXPORT_SYMBOL_GPL(mantis_i2c_init);
254 253
255int mantis_i2c_exit(struct mantis_pci *mantis) 254int mantis_i2c_exit(struct mantis_pci *mantis)
256{ 255{
257 u32 intmask;
258
259 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); 256 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
260 intmask = mmread(MANTIS_INT_MASK); 257 mantis_mask_ints(mantis, MANTIS_INT_I2CDONE);
261 mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
262 258
263 dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); 259 dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
264 i2c_del_adapter(&mantis->adapter); 260 i2c_del_adapter(&mantis->adapter);
diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
index 0e5252e5c0ef..abf0ddfef0cb 100644
--- a/drivers/media/pci/mantis/mantis_input.c
+++ b/drivers/media/pci/mantis/mantis_input.c
@@ -18,8 +18,6 @@
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/ 19*/
20 20
21#if 0 /* Currently unused */
22
23#include <media/rc-core.h> 21#include <media/rc-core.h>
24#include <linux/pci.h> 22#include <linux/pci.h>
25 23
@@ -30,100 +28,32 @@
30#include "dvb_net.h" 28#include "dvb_net.h"
31 29
32#include "mantis_common.h" 30#include "mantis_common.h"
33#include "mantis_reg.h" 31#include "mantis_input.h"
34#include "mantis_uart.h"
35 32
36#define MODULE_NAME "mantis_core" 33#define MODULE_NAME "mantis_core"
37#define RC_MAP_MANTIS "rc-mantis" 34
38 35void mantis_input_process(struct mantis_pci *mantis, int scancode)
39static struct rc_map_table mantis_ir_table[] = { 36{
40 { 0x29, KEY_POWER }, 37 if (mantis->rc)
41 { 0x28, KEY_FAVORITES }, 38 rc_keydown(mantis->rc, RC_TYPE_UNKNOWN, scancode, 0);
42 { 0x30, KEY_TEXT }, 39}
43 { 0x17, KEY_INFO }, /* Preview */
44 { 0x23, KEY_EPG },
45 { 0x3b, KEY_F22 }, /* Record List */
46 { 0x3c, KEY_1 },
47 { 0x3e, KEY_2 },
48 { 0x39, KEY_3 },
49 { 0x36, KEY_4 },
50 { 0x22, KEY_5 },
51 { 0x20, KEY_6 },
52 { 0x32, KEY_7 },
53 { 0x26, KEY_8 },
54 { 0x24, KEY_9 },
55 { 0x2a, KEY_0 },
56
57 { 0x33, KEY_CANCEL },
58 { 0x2c, KEY_BACK },
59 { 0x15, KEY_CLEAR },
60 { 0x3f, KEY_TAB },
61 { 0x10, KEY_ENTER },
62 { 0x14, KEY_UP },
63 { 0x0d, KEY_RIGHT },
64 { 0x0e, KEY_DOWN },
65 { 0x11, KEY_LEFT },
66
67 { 0x21, KEY_VOLUMEUP },
68 { 0x35, KEY_VOLUMEDOWN },
69 { 0x3d, KEY_CHANNELDOWN },
70 { 0x3a, KEY_CHANNELUP },
71 { 0x2e, KEY_RECORD },
72 { 0x2b, KEY_PLAY },
73 { 0x13, KEY_PAUSE },
74 { 0x25, KEY_STOP },
75
76 { 0x1f, KEY_REWIND },
77 { 0x2d, KEY_FASTFORWARD },
78 { 0x1e, KEY_PREVIOUS }, /* Replay |< */
79 { 0x1d, KEY_NEXT }, /* Skip >| */
80
81 { 0x0b, KEY_CAMERA }, /* Capture */
82 { 0x0f, KEY_LANGUAGE }, /* SAP */
83 { 0x18, KEY_MODE }, /* PIP */
84 { 0x12, KEY_ZOOM }, /* Full screen */
85 { 0x1c, KEY_SUBTITLE },
86 { 0x2f, KEY_MUTE },
87 { 0x16, KEY_F20 }, /* L/R */
88 { 0x38, KEY_F21 }, /* Hibernate */
89
90 { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */
91 { 0x31, KEY_AGAIN }, /* Recall */
92 { 0x1a, KEY_KPPLUS }, /* Zoom+ */
93 { 0x19, KEY_KPMINUS }, /* Zoom- */
94 { 0x27, KEY_RED },
95 { 0x0C, KEY_GREEN },
96 { 0x01, KEY_YELLOW },
97 { 0x00, KEY_BLUE },
98};
99
100static struct rc_map_list ir_mantis_map = {
101 .map = {
102 .scan = mantis_ir_table,
103 .size = ARRAY_SIZE(mantis_ir_table),
104 .rc_type = RC_TYPE_UNKNOWN,
105 .name = RC_MAP_MANTIS,
106 }
107};
108 40
109int mantis_input_init(struct mantis_pci *mantis) 41int mantis_input_init(struct mantis_pci *mantis)
110{ 42{
111 struct rc_dev *dev; 43 struct rc_dev *dev;
112 int err; 44 int err;
113 45
114 err = rc_map_register(&ir_mantis_map);
115 if (err)
116 goto out;
117
118 dev = rc_allocate_device(); 46 dev = rc_allocate_device();
119 if (!dev) { 47 if (!dev) {
120 dprintk(MANTIS_ERROR, 1, "Remote device allocation failed"); 48 dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
121 err = -ENOMEM; 49 err = -ENOMEM;
122 goto out_map; 50 goto out;
123 } 51 }
124 52
125 sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name); 53 snprintf(mantis->input_name, sizeof(mantis->input_name),
126 sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev)); 54 "Mantis %s IR receiver", mantis->hwconfig->model_name);
55 snprintf(mantis->input_phys, sizeof(mantis->input_phys),
56 "pci-%s/ir0", pci_name(mantis->pdev));
127 57
128 dev->input_name = mantis->input_name; 58 dev->input_name = mantis->input_name;
129 dev->input_phys = mantis->input_phys; 59 dev->input_phys = mantis->input_phys;
@@ -132,7 +62,7 @@ int mantis_input_init(struct mantis_pci *mantis)
132 dev->input_id.product = mantis->device_id; 62 dev->input_id.product = mantis->device_id;
133 dev->input_id.version = 1; 63 dev->input_id.version = 1;
134 dev->driver_name = MODULE_NAME; 64 dev->driver_name = MODULE_NAME;
135 dev->map_name = RC_MAP_MANTIS; 65 dev->map_name = mantis->rc_map_name ? : RC_MAP_EMPTY;
136 dev->dev.parent = &mantis->pdev->dev; 66 dev->dev.parent = &mantis->pdev->dev;
137 67
138 err = rc_register_device(dev); 68 err = rc_register_device(dev);
@@ -146,17 +76,13 @@ int mantis_input_init(struct mantis_pci *mantis)
146 76
147out_dev: 77out_dev:
148 rc_free_device(dev); 78 rc_free_device(dev);
149out_map:
150 rc_map_unregister(&ir_mantis_map);
151out: 79out:
152 return err; 80 return err;
153} 81}
82EXPORT_SYMBOL_GPL(mantis_input_init);
154 83
155int mantis_init_exit(struct mantis_pci *mantis) 84void mantis_input_exit(struct mantis_pci *mantis)
156{ 85{
157 rc_unregister_device(mantis->rc); 86 rc_unregister_device(mantis->rc);
158 rc_map_unregister(&ir_mantis_map);
159 return 0;
160} 87}
161 88EXPORT_SYMBOL_GPL(mantis_input_exit);
162#endif
diff --git a/drivers/media/pci/mantis/mantis_input.h b/drivers/media/pci/mantis/mantis_input.h
new file mode 100644
index 000000000000..3bbde8b11ce1
--- /dev/null
+++ b/drivers/media/pci/mantis/mantis_input.h
@@ -0,0 +1,28 @@
1/*
2 Mantis PCI bridge driver
3
4 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef __MANTIS_INPUT_H
22#define __MANTIS_INPUT_H
23
24extern int mantis_input_init(struct mantis_pci *mantis);
25extern void mantis_input_exit(struct mantis_pci *mantis);
26extern void mantis_input_process(struct mantis_pci *mantis, int scancode);
27
28#endif /* __MANTIS_UART_H */
diff --git a/drivers/media/pci/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c
index 2f188c089666..b2dbc7b2e0f6 100644
--- a/drivers/media/pci/mantis/mantis_pcmcia.c
+++ b/drivers/media/pci/mantis/mantis_pcmcia.c
@@ -89,7 +89,7 @@ int mantis_pcmcia_init(struct mantis_ca *ca)
89 89
90 u32 gpif_stat, card_stat; 90 u32 gpif_stat, card_stat;
91 91
92 mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); 92 mantis_unmask_ints(mantis, MANTIS_INT_IRQ0);
93 gpif_stat = mmread(MANTIS_GPIF_STATUS); 93 gpif_stat = mmread(MANTIS_GPIF_STATUS);
94 card_stat = mmread(MANTIS_GPIF_IRQCFG); 94 card_stat = mmread(MANTIS_GPIF_IRQCFG);
95 95
@@ -117,5 +117,5 @@ void mantis_pcmcia_exit(struct mantis_ca *ca)
117 struct mantis_pci *mantis = ca->ca_priv; 117 struct mantis_pci *mantis = ca->ca_priv;
118 118
119 mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); 119 mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS);
120 mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); 120 mantis_mask_ints(mantis, MANTIS_INT_IRQ0);
121} 121}
diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c
index a70719218631..483410948995 100644
--- a/drivers/media/pci/mantis/mantis_uart.c
+++ b/drivers/media/pci/mantis/mantis_uart.c
@@ -25,6 +25,7 @@
25#include <linux/signal.h> 25#include <linux/signal.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/pci.h>
28 29
29#include "dmxdev.h" 30#include "dmxdev.h"
30#include "dvbdev.h" 31#include "dvbdev.h"
@@ -35,6 +36,7 @@
35#include "mantis_common.h" 36#include "mantis_common.h"
36#include "mantis_reg.h" 37#include "mantis_reg.h"
37#include "mantis_uart.h" 38#include "mantis_uart.h"
39#include "mantis_input.h"
38 40
39struct mantis_uart_params { 41struct mantis_uart_params {
40 enum mantis_baud baud_rate; 42 enum mantis_baud baud_rate;
@@ -59,51 +61,53 @@ static struct {
59 { "EVEN" } 61 { "EVEN" }
60}; 62};
61 63
62#define UART_MAX_BUF 16 64static void mantis_uart_read(struct mantis_pci *mantis)
63
64static int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
65{ 65{
66 struct mantis_hwconfig *config = mantis->hwconfig; 66 struct mantis_hwconfig *config = mantis->hwconfig;
67 u32 stat = 0, i; 67 int i, scancode = 0, err = 0;
68 68
69 /* get data */ 69 /* get data */
70 dprintk(MANTIS_DEBUG, 1, "UART Reading ...");
70 for (i = 0; i < (config->bytes + 1); i++) { 71 for (i = 0; i < (config->bytes + 1); i++) {
72 int data = mmread(MANTIS_UART_RXD);
73 dprintk(MANTIS_DEBUG, 0, " <%02x>", data);
71 74
72 stat = mmread(MANTIS_UART_STAT); 75 scancode = (scancode << 8) | (data & 0x3f);
73 76 err |= data;
74 if (stat & MANTIS_UART_RXFIFO_FULL) {
75 dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
76 }
77 data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
78
79 dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
80 77
81 if (data[i] & (1 << 7)) { 78 if (data & (1 << 7))
82 dprintk(MANTIS_ERROR, 1, "UART framing error"); 79 dprintk(MANTIS_ERROR, 1, "UART framing error");
83 return -EINVAL; 80
84 } 81 if (data & (1 << 6))
85 if (data[i] & (1 << 6)) {
86 dprintk(MANTIS_ERROR, 1, "UART parity error"); 82 dprintk(MANTIS_ERROR, 1, "UART parity error");
87 return -EINVAL;
88 }
89 } 83 }
84 dprintk(MANTIS_DEBUG, 0, "\n");
90 85
91 return 0; 86 if ((err & 0xC0) == 0)
87 mantis_input_process(mantis, scancode);
92} 88}
93 89
94static void mantis_uart_work(struct work_struct *work) 90static void mantis_uart_work(struct work_struct *work)
95{ 91{
96 struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); 92 struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
97 struct mantis_hwconfig *config = mantis->hwconfig; 93 u32 stat;
98 u8 buf[16];
99 int i;
100 94
101 mantis_uart_read(mantis, buf); 95 stat = mmread(MANTIS_UART_STAT);
102 96
103 for (i = 0; i < (config->bytes + 1); i++) 97 if (stat & MANTIS_UART_RXFIFO_FULL)
104 dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); 98 dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
105 99
106 dprintk(MANTIS_DEBUG, 0, "\n"); 100 /*
101 * MANTIS_UART_RXFIFO_DATA is only set if at least config->bytes + 1 bytes
102 * are in the FIFO.
103 */
104 while (stat & MANTIS_UART_RXFIFO_DATA) {
105 mantis_uart_read(mantis);
106 stat = mmread(MANTIS_UART_STAT);
107 }
108
109 /* re-enable UART (RX) interrupt */
110 mantis_unmask_ints(mantis, MANTIS_INT_IRQ1);
107} 111}
108 112
109static int mantis_uart_setup(struct mantis_pci *mantis, 113static int mantis_uart_setup(struct mantis_pci *mantis,
@@ -152,9 +156,6 @@ int mantis_uart_init(struct mantis_pci *mantis)
152 rates[params.baud_rate].string, 156 rates[params.baud_rate].string,
153 parity[params.parity].string); 157 parity[params.parity].string);
154 158
155 init_waitqueue_head(&mantis->uart_wq);
156 spin_lock_init(&mantis->uart_lock);
157
158 INIT_WORK(&mantis->uart_work, mantis_uart_work); 159 INIT_WORK(&mantis->uart_work, mantis_uart_work);
159 160
160 /* disable interrupt */ 161 /* disable interrupt */
@@ -169,8 +170,8 @@ int mantis_uart_init(struct mantis_pci *mantis)
169 mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); 170 mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
170 171
171 /* enable interrupt */ 172 /* enable interrupt */
172 mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
173 mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); 173 mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
174 mantis_unmask_ints(mantis, MANTIS_INT_IRQ1);
174 175
175 schedule_work(&mantis->uart_work); 176 schedule_work(&mantis->uart_work);
176 dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); 177 dprintk(MANTIS_DEBUG, 1, "UART successfully initialized");
@@ -182,6 +183,7 @@ EXPORT_SYMBOL_GPL(mantis_uart_init);
182void mantis_uart_exit(struct mantis_pci *mantis) 183void mantis_uart_exit(struct mantis_pci *mantis)
183{ 184{
184 /* disable interrupt */ 185 /* disable interrupt */
186 mantis_mask_ints(mantis, MANTIS_INT_IRQ1);
185 mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); 187 mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
186 flush_work(&mantis->uart_work); 188 flush_work(&mantis->uart_work);
187} 189}