saa7134-input.c 16 KB

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