saa7134-input.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. /*
  2. *
  3. * handle saa7134 IR remotes via linux kernel input layer.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. #include <linux/module.h>
  21. #include <linux/moduleparam.h>
  22. #include <linux/init.h>
  23. #include <linux/delay.h>
  24. #include <linux/sched.h>
  25. #include <linux/interrupt.h>
  26. #include <linux/input.h>
  27. #include "saa7134-reg.h"
  28. #include "saa7134.h"
  29. static unsigned int disable_ir = 0;
  30. module_param(disable_ir, int, 0444);
  31. MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
  32. static unsigned int ir_debug = 0;
  33. module_param(ir_debug, int, 0644);
  34. MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
  35. #define dprintk(fmt, arg...) if (ir_debug) \
  36. printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
  37. /* ---------------------------------------------------------------------- */
  38. static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
  39. [ 15 ] = KEY_KP0,
  40. [ 3 ] = KEY_KP1,
  41. [ 4 ] = KEY_KP2,
  42. [ 5 ] = KEY_KP3,
  43. [ 7 ] = KEY_KP4,
  44. [ 8 ] = KEY_KP5,
  45. [ 9 ] = KEY_KP6,
  46. [ 11 ] = KEY_KP7,
  47. [ 12 ] = KEY_KP8,
  48. [ 13 ] = KEY_KP9,
  49. [ 14 ] = KEY_TUNER, // Air/Cable
  50. [ 17 ] = KEY_VIDEO, // Video
  51. [ 21 ] = KEY_AUDIO, // Audio
  52. [ 0 ] = KEY_POWER, // Pover
  53. [ 2 ] = KEY_ZOOM, // Fullscreen
  54. [ 27 ] = KEY_MUTE, // Mute
  55. [ 20 ] = KEY_VOLUMEUP,
  56. [ 23 ] = KEY_VOLUMEDOWN,
  57. [ 18 ] = KEY_CHANNELUP, // Channel +
  58. [ 19 ] = KEY_CHANNELDOWN, // Channel -
  59. [ 6 ] = KEY_AGAIN, // Recal
  60. [ 16 ] = KEY_KPENTER, // Enter
  61. [ 26 ] = KEY_F22, // Stereo
  62. [ 24 ] = KEY_EDIT, // AV Source
  63. };
  64. static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
  65. [ 0 ] = KEY_KP0,
  66. [ 1 ] = KEY_KP1,
  67. [ 2 ] = KEY_KP2,
  68. [ 3 ] = KEY_KP3,
  69. [ 4 ] = KEY_KP4,
  70. [ 5 ] = KEY_KP5,
  71. [ 6 ] = KEY_KP6,
  72. [ 7 ] = KEY_KP7,
  73. [ 8 ] = KEY_KP8,
  74. [ 9 ] = KEY_KP9,
  75. [ 0x0a ] = KEY_POWER,
  76. [ 0x0b ] = KEY_PROG1, // app
  77. [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen
  78. [ 0x0d ] = KEY_CHANNELUP, // channel
  79. [ 0x0e ] = KEY_CHANNELDOWN, // channel-
  80. [ 0x0f ] = KEY_VOLUMEUP,
  81. [ 0x10 ] = KEY_VOLUMEDOWN,
  82. [ 0x11 ] = KEY_TUNER, // AV
  83. [ 0x12 ] = KEY_NUMLOCK, // -/--
  84. [ 0x13 ] = KEY_AUDIO, // audio
  85. [ 0x14 ] = KEY_MUTE,
  86. [ 0x15 ] = KEY_UP,
  87. [ 0x16 ] = KEY_DOWN,
  88. [ 0x17 ] = KEY_LEFT,
  89. [ 0x18 ] = KEY_RIGHT,
  90. [ 0x19 ] = BTN_LEFT,
  91. [ 0x1a ] = BTN_RIGHT,
  92. [ 0x1b ] = KEY_WWW, // text
  93. [ 0x1c ] = KEY_REWIND,
  94. [ 0x1d ] = KEY_FORWARD,
  95. [ 0x1e ] = KEY_RECORD,
  96. [ 0x1f ] = KEY_PLAY,
  97. [ 0x20 ] = KEY_PREVIOUSSONG,
  98. [ 0x21 ] = KEY_NEXTSONG,
  99. [ 0x22 ] = KEY_PAUSE,
  100. [ 0x23 ] = KEY_STOP,
  101. };
  102. /* Alfons Geser <a.geser@cox.net>
  103. * updates from Job D. R. Borges <jobdrb@ig.com.br> */
  104. static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
  105. [ 18 ] = KEY_POWER,
  106. [ 1 ] = KEY_TV, // DVR
  107. [ 21 ] = KEY_DVD, // DVD
  108. [ 23 ] = KEY_AUDIO, // music
  109. // DVR mode / DVD mode / music mode
  110. [ 27 ] = KEY_MUTE, // mute
  111. [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
  112. [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
  113. [ 22 ] = KEY_ZOOM, // full screen
  114. [ 28 ] = KEY_VIDEO, // video source / eject / delall
  115. [ 29 ] = KEY_RESTART, // playback / angle / del
  116. [ 47 ] = KEY_SEARCH, // scan / menu / playlist
  117. [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
  118. [ 49 ] = KEY_HELP, // help
  119. [ 50 ] = KEY_MODE, // num/memo
  120. [ 51 ] = KEY_ESC, // cancel
  121. [ 12 ] = KEY_UP, // up
  122. [ 16 ] = KEY_DOWN, // down
  123. [ 8 ] = KEY_LEFT, // left
  124. [ 4 ] = KEY_RIGHT, // right
  125. [ 3 ] = KEY_SELECT, // select
  126. [ 31 ] = KEY_REWIND, // rewind
  127. [ 32 ] = KEY_PLAYPAUSE, // play/pause
  128. [ 41 ] = KEY_FORWARD, // forward
  129. [ 20 ] = KEY_AGAIN, // repeat
  130. [ 43 ] = KEY_RECORD, // recording
  131. [ 44 ] = KEY_STOP, // stop
  132. [ 45 ] = KEY_PLAY, // play
  133. [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
  134. [ 0 ] = KEY_KP0,
  135. [ 5 ] = KEY_KP1,
  136. [ 6 ] = KEY_KP2,
  137. [ 7 ] = KEY_KP3,
  138. [ 9 ] = KEY_KP4,
  139. [ 10 ] = KEY_KP5,
  140. [ 11 ] = KEY_KP6,
  141. [ 13 ] = KEY_KP7,
  142. [ 14 ] = KEY_KP8,
  143. [ 15 ] = KEY_KP9,
  144. [ 42 ] = KEY_VOLUMEUP,
  145. [ 17 ] = KEY_VOLUMEDOWN,
  146. [ 24 ] = KEY_CHANNELUP, // CH.tracking up
  147. [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
  148. [ 19 ] = KEY_KPENTER, // enter
  149. [ 33 ] = KEY_KPDOT, // . (decimal dot)
  150. };
  151. static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
  152. [ 30 ] = KEY_POWER, // power
  153. [ 28 ] = KEY_SEARCH, // scan
  154. [ 7 ] = KEY_SELECT, // source
  155. [ 22 ] = KEY_VOLUMEUP,
  156. [ 20 ] = KEY_VOLUMEDOWN,
  157. [ 31 ] = KEY_CHANNELUP,
  158. [ 23 ] = KEY_CHANNELDOWN,
  159. [ 24 ] = KEY_MUTE,
  160. [ 2 ] = KEY_KP0,
  161. [ 1 ] = KEY_KP1,
  162. [ 11 ] = KEY_KP2,
  163. [ 27 ] = KEY_KP3,
  164. [ 5 ] = KEY_KP4,
  165. [ 9 ] = KEY_KP5,
  166. [ 21 ] = KEY_KP6,
  167. [ 6 ] = KEY_KP7,
  168. [ 10 ] = KEY_KP8,
  169. [ 18 ] = KEY_KP9,
  170. [ 16 ] = KEY_KPDOT,
  171. [ 3 ] = KEY_TUNER, // tv/fm
  172. [ 4 ] = KEY_REWIND, // fm tuning left or function left
  173. [ 12 ] = KEY_FORWARD, // fm tuning right or function right
  174. [ 0 ] = KEY_RECORD,
  175. [ 8 ] = KEY_STOP,
  176. [ 17 ] = KEY_PLAY,
  177. [ 25 ] = KEY_ZOOM,
  178. [ 14 ] = KEY_MENU, // function
  179. [ 19 ] = KEY_AGAIN, // recall
  180. [ 29 ] = KEY_RESTART, // reset
  181. [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle
  182. // FIXME
  183. [ 13 ] = KEY_F21, // mts
  184. [ 15 ] = KEY_F22, // min
  185. };
  186. /* Alex Hermann <gaaf@gmx.net> */
  187. static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
  188. [ 40 ] = KEY_KP1,
  189. [ 24 ] = KEY_KP2,
  190. [ 56 ] = KEY_KP3,
  191. [ 36 ] = KEY_KP4,
  192. [ 20 ] = KEY_KP5,
  193. [ 52 ] = KEY_KP6,
  194. [ 44 ] = KEY_KP7,
  195. [ 28 ] = KEY_KP8,
  196. [ 60 ] = KEY_KP9,
  197. [ 34 ] = KEY_KP0,
  198. [ 32 ] = KEY_TV, // TV/FM
  199. [ 16 ] = KEY_CD, // CD
  200. [ 48 ] = KEY_TEXT, // TELETEXT
  201. [ 0 ] = KEY_POWER, // POWER
  202. [ 8 ] = KEY_VIDEO, // VIDEO
  203. [ 4 ] = KEY_AUDIO, // AUDIO
  204. [ 12 ] = KEY_ZOOM, // FULL SCREEN
  205. [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
  206. [ 50 ] = KEY_REWIND, // LOOP - ???
  207. [ 2 ] = KEY_PRINT, // PREVIEW - ???
  208. [ 42 ] = KEY_SEARCH, // AUTOSCAN
  209. [ 26 ] = KEY_SLEEP, // FREEZE - ???
  210. [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
  211. [ 10 ] = KEY_MUTE, // MUTE
  212. [ 38 ] = KEY_RECORD, // RECORD
  213. [ 22 ] = KEY_PAUSE, // PAUSE
  214. [ 54 ] = KEY_STOP, // STOP
  215. [ 6 ] = KEY_PLAY, // PLAY
  216. [ 46 ] = KEY_RED, // <RED>
  217. [ 33 ] = KEY_GREEN, // <GREEN>
  218. [ 14 ] = KEY_YELLOW, // <YELLOW>
  219. [ 1 ] = KEY_BLUE, // <BLUE>
  220. [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
  221. [ 62 ] = KEY_VOLUMEUP, // VOLUME+
  222. [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
  223. [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
  224. };
  225. static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
  226. [ 20 ] = KEY_MUTE,
  227. [ 36 ] = KEY_ZOOM,
  228. [ 1 ] = KEY_DVD,
  229. [ 35 ] = KEY_RADIO,
  230. [ 0 ] = KEY_TV,
  231. [ 10 ] = KEY_REWIND,
  232. [ 8 ] = KEY_PLAYPAUSE,
  233. [ 15 ] = KEY_FORWARD,
  234. [ 2 ] = KEY_PREVIOUS,
  235. [ 7 ] = KEY_STOP,
  236. [ 6 ] = KEY_NEXT,
  237. [ 12 ] = KEY_UP,
  238. [ 14 ] = KEY_DOWN,
  239. [ 11 ] = KEY_LEFT,
  240. [ 13 ] = KEY_RIGHT,
  241. [ 17 ] = KEY_OK,
  242. [ 3 ] = KEY_MENU,
  243. [ 9 ] = KEY_SETUP,
  244. [ 5 ] = KEY_VIDEO,
  245. [ 34 ] = KEY_CHANNEL,
  246. [ 18 ] = KEY_VOLUMEUP,
  247. [ 21 ] = KEY_VOLUMEDOWN,
  248. [ 16 ] = KEY_CHANNELUP,
  249. [ 19 ] = KEY_CHANNELDOWN,
  250. [ 4 ] = KEY_RECORD,
  251. [ 22 ] = KEY_KP1,
  252. [ 23 ] = KEY_KP2,
  253. [ 24 ] = KEY_KP3,
  254. [ 25 ] = KEY_KP4,
  255. [ 26 ] = KEY_KP5,
  256. [ 27 ] = KEY_KP6,
  257. [ 28 ] = KEY_KP7,
  258. [ 29 ] = KEY_KP8,
  259. [ 30 ] = KEY_KP9,
  260. [ 31 ] = KEY_KP0,
  261. [ 32 ] = KEY_LANGUAGE,
  262. [ 33 ] = KEY_SLEEP,
  263. };
  264. /* Michael Tokarev <mjt@tls.msk.ru>
  265. http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
  266. keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
  267. least, and probably other cards too.
  268. The "ascii-art picture" below (in comments, first row
  269. is the keycode in hex, and subsequent row(s) shows
  270. the button labels (several variants when appropriate)
  271. helps to descide which keycodes to assign to the buttons.
  272. */
  273. static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
  274. /* 0x1c 0x12 *
  275. * FUNCTION POWER *
  276. * FM (|) *
  277. * */
  278. [ 0x1c ] = KEY_RADIO, /*XXX*/
  279. [ 0x12 ] = KEY_POWER,
  280. /* 0x01 0x02 0x03 *
  281. * 1 2 3 *
  282. * *
  283. * 0x04 0x05 0x06 *
  284. * 4 5 6 *
  285. * *
  286. * 0x07 0x08 0x09 *
  287. * 7 8 9 *
  288. * */
  289. [ 0x01 ] = KEY_KP1,
  290. [ 0x02 ] = KEY_KP2,
  291. [ 0x03 ] = KEY_KP3,
  292. [ 0x04 ] = KEY_KP4,
  293. [ 0x05 ] = KEY_KP5,
  294. [ 0x06 ] = KEY_KP6,
  295. [ 0x07 ] = KEY_KP7,
  296. [ 0x08 ] = KEY_KP8,
  297. [ 0x09 ] = KEY_KP9,
  298. /* 0x0a 0x00 0x17 *
  299. * RECALL 0 +100 *
  300. * PLUS *
  301. * */
  302. [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */
  303. [ 0x00 ] = KEY_KP0,
  304. [ 0x17 ] = KEY_DIGITS, /*XXX*/
  305. /* 0x14 0x10 *
  306. * MENU INFO *
  307. * OSD */
  308. [ 0x14 ] = KEY_MENU,
  309. [ 0x10 ] = KEY_INFO,
  310. /* 0x0b *
  311. * Up *
  312. * *
  313. * 0x18 0x16 0x0c *
  314. * Left Ok Right *
  315. * *
  316. * 0x015 *
  317. * Down *
  318. * */
  319. [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */
  320. [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */
  321. [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */
  322. [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */
  323. [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */
  324. /* 0x11 0x0d *
  325. * TV/AV MODE *
  326. * SOURCE STEREO *
  327. * */
  328. [ 0x11 ] = KEY_TV, /*XXX*/
  329. [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */
  330. /* 0x0f 0x1b 0x1a *
  331. * AUDIO Vol+ Chan+ *
  332. * TIMESHIFT??? *
  333. * *
  334. * 0x0e 0x1f 0x1e *
  335. * SLEEP Vol- Chan- *
  336. * */
  337. [ 0x0f ] = KEY_AUDIO,
  338. [ 0x1b ] = KEY_VOLUMEUP,
  339. [ 0x1a ] = KEY_CHANNELUP,
  340. [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */
  341. [ 0x1f ] = KEY_VOLUMEDOWN,
  342. [ 0x1e ] = KEY_CHANNELDOWN,
  343. /* 0x13 0x19 *
  344. * MUTE SNAPSHOT*
  345. * */
  346. [ 0x13 ] = KEY_MUTE,
  347. [ 0x19 ] = KEY_RECORD, /*XXX*/
  348. // 0x1d unused ?
  349. };
  350. /* ---------------------------------------------------------------------- */
  351. static int build_key(struct saa7134_dev *dev)
  352. {
  353. struct saa7134_ir *ir = dev->remote;
  354. u32 gpio, data;
  355. /* rising SAA7134_GPIO_GPRESCAN reads the status */
  356. saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
  357. saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
  358. gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
  359. if (ir->polling) {
  360. if (ir->last_gpio == gpio)
  361. return 0;
  362. ir->last_gpio = gpio;
  363. }
  364. data = ir_extract_bits(gpio, ir->mask_keycode);
  365. dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
  366. gpio, ir->mask_keycode, data);
  367. if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
  368. (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
  369. ir_input_keydown(&ir->dev,&ir->ir,data,data);
  370. } else {
  371. ir_input_nokey(&ir->dev,&ir->ir);
  372. }
  373. return 0;
  374. }
  375. /* ---------------------------------------------------------------------- */
  376. void saa7134_input_irq(struct saa7134_dev *dev)
  377. {
  378. struct saa7134_ir *ir = dev->remote;
  379. if (!ir->polling)
  380. build_key(dev);
  381. }
  382. static void saa7134_input_timer(unsigned long data)
  383. {
  384. struct saa7134_dev *dev = (struct saa7134_dev*)data;
  385. struct saa7134_ir *ir = dev->remote;
  386. unsigned long timeout;
  387. build_key(dev);
  388. timeout = jiffies + (ir->polling * HZ / 1000);
  389. mod_timer(&ir->timer, timeout);
  390. }
  391. int saa7134_input_init1(struct saa7134_dev *dev)
  392. {
  393. struct saa7134_ir *ir;
  394. IR_KEYTAB_TYPE *ir_codes = NULL;
  395. u32 mask_keycode = 0;
  396. u32 mask_keydown = 0;
  397. u32 mask_keyup = 0;
  398. int polling = 0;
  399. int ir_type = IR_TYPE_OTHER;
  400. if (!dev->has_remote)
  401. return -ENODEV;
  402. if (disable_ir)
  403. return -ENODEV;
  404. /* detect & configure */
  405. switch (dev->board) {
  406. case SAA7134_BOARD_FLYVIDEO2000:
  407. case SAA7134_BOARD_FLYVIDEO3000:
  408. case SAA7134_BOARD_FLYTVPLATINUM_FM:
  409. ir_codes = flyvideo_codes;
  410. mask_keycode = 0xEC00000;
  411. mask_keydown = 0x0040000;
  412. break;
  413. case SAA7134_BOARD_CINERGY400:
  414. case SAA7134_BOARD_CINERGY600:
  415. case SAA7134_BOARD_CINERGY600_MK3:
  416. ir_codes = cinergy_codes;
  417. mask_keycode = 0x00003f;
  418. mask_keyup = 0x040000;
  419. break;
  420. case SAA7134_BOARD_ECS_TVP3XP:
  421. case SAA7134_BOARD_ECS_TVP3XP_4CB5:
  422. ir_codes = eztv_codes;
  423. mask_keycode = 0x00017c;
  424. mask_keyup = 0x000002;
  425. polling = 50; // ms
  426. break;
  427. case SAA7134_BOARD_KWORLD_XPERT:
  428. case SAA7134_BOARD_AVACSSMARTTV:
  429. ir_codes = avacssmart_codes;
  430. mask_keycode = 0x00001F;
  431. mask_keyup = 0x000020;
  432. polling = 50; // ms
  433. break;
  434. case SAA7134_BOARD_MD2819:
  435. case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
  436. case SAA7134_BOARD_AVERMEDIA_305:
  437. case SAA7134_BOARD_AVERMEDIA_307:
  438. case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
  439. case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
  440. case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
  441. ir_codes = md2819_codes;
  442. mask_keycode = 0x0007C8;
  443. mask_keydown = 0x000010;
  444. polling = 50; // ms
  445. /* Set GPIO pin2 to high to enable the IR controller */
  446. saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
  447. saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
  448. break;
  449. case SAA7134_BOARD_MANLI_MTV001:
  450. case SAA7134_BOARD_MANLI_MTV002:
  451. ir_codes = manli_codes;
  452. mask_keycode = 0x001f00;
  453. mask_keyup = 0x004000;
  454. mask_keydown = 0x002000;
  455. polling = 50; // ms
  456. break;
  457. case SAA7134_BOARD_VIDEOMATE_TV_PVR:
  458. case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
  459. ir_codes = videomate_tv_pvr_codes;
  460. mask_keycode = 0x00003F;
  461. mask_keyup = 0x400000;
  462. polling = 50; // ms
  463. break;
  464. }
  465. if (NULL == ir_codes) {
  466. printk("%s: Oops: IR config error [card=%d]\n",
  467. dev->name, dev->board);
  468. return -ENODEV;
  469. }
  470. ir = kmalloc(sizeof(*ir),GFP_KERNEL);
  471. if (NULL == ir)
  472. return -ENOMEM;
  473. memset(ir,0,sizeof(*ir));
  474. /* init hardware-specific stuff */
  475. ir->mask_keycode = mask_keycode;
  476. ir->mask_keydown = mask_keydown;
  477. ir->mask_keyup = mask_keyup;
  478. ir->polling = polling;
  479. /* init input device */
  480. snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
  481. saa7134_boards[dev->board].name);
  482. snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
  483. pci_name(dev->pci));
  484. ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
  485. ir->dev.name = ir->name;
  486. ir->dev.phys = ir->phys;
  487. ir->dev.id.bustype = BUS_PCI;
  488. ir->dev.id.version = 1;
  489. if (dev->pci->subsystem_vendor) {
  490. ir->dev.id.vendor = dev->pci->subsystem_vendor;
  491. ir->dev.id.product = dev->pci->subsystem_device;
  492. } else {
  493. ir->dev.id.vendor = dev->pci->vendor;
  494. ir->dev.id.product = dev->pci->device;
  495. }
  496. ir->dev.dev = &dev->pci->dev;
  497. /* all done */
  498. dev->remote = ir;
  499. if (ir->polling) {
  500. init_timer(&ir->timer);
  501. ir->timer.function = saa7134_input_timer;
  502. ir->timer.data = (unsigned long)dev;
  503. ir->timer.expires = jiffies + HZ;
  504. add_timer(&ir->timer);
  505. }
  506. input_register_device(&dev->remote->dev);
  507. printk("%s: registered input device for IR\n",dev->name);
  508. return 0;
  509. }
  510. void saa7134_input_fini(struct saa7134_dev *dev)
  511. {
  512. if (NULL == dev->remote)
  513. return;
  514. input_unregister_device(&dev->remote->dev);
  515. if (dev->remote->polling)
  516. del_timer_sync(&dev->remote->timer);
  517. kfree(dev->remote);
  518. dev->remote = NULL;
  519. }
  520. /* ----------------------------------------------------------------------
  521. * Local variables:
  522. * c-basic-offset: 8
  523. * End:
  524. */