saa7134-input.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  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. #define i2cdprintk(fmt, arg...) if (ir_debug) \
  38. printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
  39. /* ---------------------------------------------------------------------- */
  40. static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
  41. [ 15 ] = KEY_KP0,
  42. [ 3 ] = KEY_KP1,
  43. [ 4 ] = KEY_KP2,
  44. [ 5 ] = KEY_KP3,
  45. [ 7 ] = KEY_KP4,
  46. [ 8 ] = KEY_KP5,
  47. [ 9 ] = KEY_KP6,
  48. [ 11 ] = KEY_KP7,
  49. [ 12 ] = KEY_KP8,
  50. [ 13 ] = KEY_KP9,
  51. [ 14 ] = KEY_TUNER, // Air/Cable
  52. [ 17 ] = KEY_VIDEO, // Video
  53. [ 21 ] = KEY_AUDIO, // Audio
  54. [ 0 ] = KEY_POWER, // Pover
  55. [ 2 ] = KEY_ZOOM, // Fullscreen
  56. [ 27 ] = KEY_MUTE, // Mute
  57. [ 20 ] = KEY_VOLUMEUP,
  58. [ 23 ] = KEY_VOLUMEDOWN,
  59. [ 18 ] = KEY_CHANNELUP, // Channel +
  60. [ 19 ] = KEY_CHANNELDOWN, // Channel -
  61. [ 6 ] = KEY_AGAIN, // Recal
  62. [ 16 ] = KEY_KPENTER, // Enter
  63. [ 26 ] = KEY_F22, // Stereo
  64. [ 24 ] = KEY_EDIT, // AV Source
  65. };
  66. static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
  67. [ 0 ] = KEY_KP0,
  68. [ 1 ] = KEY_KP1,
  69. [ 2 ] = KEY_KP2,
  70. [ 3 ] = KEY_KP3,
  71. [ 4 ] = KEY_KP4,
  72. [ 5 ] = KEY_KP5,
  73. [ 6 ] = KEY_KP6,
  74. [ 7 ] = KEY_KP7,
  75. [ 8 ] = KEY_KP8,
  76. [ 9 ] = KEY_KP9,
  77. [ 0x0a ] = KEY_POWER,
  78. [ 0x0b ] = KEY_PROG1, // app
  79. [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen
  80. [ 0x0d ] = KEY_CHANNELUP, // channel
  81. [ 0x0e ] = KEY_CHANNELDOWN, // channel-
  82. [ 0x0f ] = KEY_VOLUMEUP,
  83. [ 0x10 ] = KEY_VOLUMEDOWN,
  84. [ 0x11 ] = KEY_TUNER, // AV
  85. [ 0x12 ] = KEY_NUMLOCK, // -/--
  86. [ 0x13 ] = KEY_AUDIO, // audio
  87. [ 0x14 ] = KEY_MUTE,
  88. [ 0x15 ] = KEY_UP,
  89. [ 0x16 ] = KEY_DOWN,
  90. [ 0x17 ] = KEY_LEFT,
  91. [ 0x18 ] = KEY_RIGHT,
  92. [ 0x19 ] = BTN_LEFT,
  93. [ 0x1a ] = BTN_RIGHT,
  94. [ 0x1b ] = KEY_WWW, // text
  95. [ 0x1c ] = KEY_REWIND,
  96. [ 0x1d ] = KEY_FORWARD,
  97. [ 0x1e ] = KEY_RECORD,
  98. [ 0x1f ] = KEY_PLAY,
  99. [ 0x20 ] = KEY_PREVIOUSSONG,
  100. [ 0x21 ] = KEY_NEXTSONG,
  101. [ 0x22 ] = KEY_PAUSE,
  102. [ 0x23 ] = KEY_STOP,
  103. };
  104. /* Alfons Geser <a.geser@cox.net>
  105. * updates from Job D. R. Borges <jobdrb@ig.com.br> */
  106. static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
  107. [ 18 ] = KEY_POWER,
  108. [ 1 ] = KEY_TV, // DVR
  109. [ 21 ] = KEY_DVD, // DVD
  110. [ 23 ] = KEY_AUDIO, // music
  111. // DVR mode / DVD mode / music mode
  112. [ 27 ] = KEY_MUTE, // mute
  113. [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
  114. [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
  115. [ 22 ] = KEY_ZOOM, // full screen
  116. [ 28 ] = KEY_VIDEO, // video source / eject / delall
  117. [ 29 ] = KEY_RESTART, // playback / angle / del
  118. [ 47 ] = KEY_SEARCH, // scan / menu / playlist
  119. [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
  120. [ 49 ] = KEY_HELP, // help
  121. [ 50 ] = KEY_MODE, // num/memo
  122. [ 51 ] = KEY_ESC, // cancel
  123. [ 12 ] = KEY_UP, // up
  124. [ 16 ] = KEY_DOWN, // down
  125. [ 8 ] = KEY_LEFT, // left
  126. [ 4 ] = KEY_RIGHT, // right
  127. [ 3 ] = KEY_SELECT, // select
  128. [ 31 ] = KEY_REWIND, // rewind
  129. [ 32 ] = KEY_PLAYPAUSE, // play/pause
  130. [ 41 ] = KEY_FORWARD, // forward
  131. [ 20 ] = KEY_AGAIN, // repeat
  132. [ 43 ] = KEY_RECORD, // recording
  133. [ 44 ] = KEY_STOP, // stop
  134. [ 45 ] = KEY_PLAY, // play
  135. [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
  136. [ 0 ] = KEY_KP0,
  137. [ 5 ] = KEY_KP1,
  138. [ 6 ] = KEY_KP2,
  139. [ 7 ] = KEY_KP3,
  140. [ 9 ] = KEY_KP4,
  141. [ 10 ] = KEY_KP5,
  142. [ 11 ] = KEY_KP6,
  143. [ 13 ] = KEY_KP7,
  144. [ 14 ] = KEY_KP8,
  145. [ 15 ] = KEY_KP9,
  146. [ 42 ] = KEY_VOLUMEUP,
  147. [ 17 ] = KEY_VOLUMEDOWN,
  148. [ 24 ] = KEY_CHANNELUP, // CH.tracking up
  149. [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
  150. [ 19 ] = KEY_KPENTER, // enter
  151. [ 33 ] = KEY_KPDOT, // . (decimal dot)
  152. };
  153. static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
  154. [ 30 ] = KEY_POWER, // power
  155. [ 28 ] = KEY_SEARCH, // scan
  156. [ 7 ] = KEY_SELECT, // source
  157. [ 22 ] = KEY_VOLUMEUP,
  158. [ 20 ] = KEY_VOLUMEDOWN,
  159. [ 31 ] = KEY_CHANNELUP,
  160. [ 23 ] = KEY_CHANNELDOWN,
  161. [ 24 ] = KEY_MUTE,
  162. [ 2 ] = KEY_KP0,
  163. [ 1 ] = KEY_KP1,
  164. [ 11 ] = KEY_KP2,
  165. [ 27 ] = KEY_KP3,
  166. [ 5 ] = KEY_KP4,
  167. [ 9 ] = KEY_KP5,
  168. [ 21 ] = KEY_KP6,
  169. [ 6 ] = KEY_KP7,
  170. [ 10 ] = KEY_KP8,
  171. [ 18 ] = KEY_KP9,
  172. [ 16 ] = KEY_KPDOT,
  173. [ 3 ] = KEY_TUNER, // tv/fm
  174. [ 4 ] = KEY_REWIND, // fm tuning left or function left
  175. [ 12 ] = KEY_FORWARD, // fm tuning right or function right
  176. [ 0 ] = KEY_RECORD,
  177. [ 8 ] = KEY_STOP,
  178. [ 17 ] = KEY_PLAY,
  179. [ 25 ] = KEY_ZOOM,
  180. [ 14 ] = KEY_MENU, // function
  181. [ 19 ] = KEY_AGAIN, // recall
  182. [ 29 ] = KEY_RESTART, // reset
  183. [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle
  184. // FIXME
  185. [ 13 ] = KEY_F21, // mts
  186. [ 15 ] = KEY_F22, // min
  187. };
  188. /* Alex Hermann <gaaf@gmx.net> */
  189. static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
  190. [ 40 ] = KEY_KP1,
  191. [ 24 ] = KEY_KP2,
  192. [ 56 ] = KEY_KP3,
  193. [ 36 ] = KEY_KP4,
  194. [ 20 ] = KEY_KP5,
  195. [ 52 ] = KEY_KP6,
  196. [ 44 ] = KEY_KP7,
  197. [ 28 ] = KEY_KP8,
  198. [ 60 ] = KEY_KP9,
  199. [ 34 ] = KEY_KP0,
  200. [ 32 ] = KEY_TV, // TV/FM
  201. [ 16 ] = KEY_CD, // CD
  202. [ 48 ] = KEY_TEXT, // TELETEXT
  203. [ 0 ] = KEY_POWER, // POWER
  204. [ 8 ] = KEY_VIDEO, // VIDEO
  205. [ 4 ] = KEY_AUDIO, // AUDIO
  206. [ 12 ] = KEY_ZOOM, // FULL SCREEN
  207. [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
  208. [ 50 ] = KEY_REWIND, // LOOP - ???
  209. [ 2 ] = KEY_PRINT, // PREVIEW - ???
  210. [ 42 ] = KEY_SEARCH, // AUTOSCAN
  211. [ 26 ] = KEY_SLEEP, // FREEZE - ???
  212. [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
  213. [ 10 ] = KEY_MUTE, // MUTE
  214. [ 38 ] = KEY_RECORD, // RECORD
  215. [ 22 ] = KEY_PAUSE, // PAUSE
  216. [ 54 ] = KEY_STOP, // STOP
  217. [ 6 ] = KEY_PLAY, // PLAY
  218. [ 46 ] = KEY_RED, // <RED>
  219. [ 33 ] = KEY_GREEN, // <GREEN>
  220. [ 14 ] = KEY_YELLOW, // <YELLOW>
  221. [ 1 ] = KEY_BLUE, // <BLUE>
  222. [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
  223. [ 62 ] = KEY_VOLUMEUP, // VOLUME+
  224. [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
  225. [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
  226. };
  227. static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
  228. [ 20 ] = KEY_MUTE,
  229. [ 36 ] = KEY_ZOOM,
  230. [ 1 ] = KEY_DVD,
  231. [ 35 ] = KEY_RADIO,
  232. [ 0 ] = KEY_TV,
  233. [ 10 ] = KEY_REWIND,
  234. [ 8 ] = KEY_PLAYPAUSE,
  235. [ 15 ] = KEY_FORWARD,
  236. [ 2 ] = KEY_PREVIOUS,
  237. [ 7 ] = KEY_STOP,
  238. [ 6 ] = KEY_NEXT,
  239. [ 12 ] = KEY_UP,
  240. [ 14 ] = KEY_DOWN,
  241. [ 11 ] = KEY_LEFT,
  242. [ 13 ] = KEY_RIGHT,
  243. [ 17 ] = KEY_OK,
  244. [ 3 ] = KEY_MENU,
  245. [ 9 ] = KEY_SETUP,
  246. [ 5 ] = KEY_VIDEO,
  247. [ 34 ] = KEY_CHANNEL,
  248. [ 18 ] = KEY_VOLUMEUP,
  249. [ 21 ] = KEY_VOLUMEDOWN,
  250. [ 16 ] = KEY_CHANNELUP,
  251. [ 19 ] = KEY_CHANNELDOWN,
  252. [ 4 ] = KEY_RECORD,
  253. [ 22 ] = KEY_KP1,
  254. [ 23 ] = KEY_KP2,
  255. [ 24 ] = KEY_KP3,
  256. [ 25 ] = KEY_KP4,
  257. [ 26 ] = KEY_KP5,
  258. [ 27 ] = KEY_KP6,
  259. [ 28 ] = KEY_KP7,
  260. [ 29 ] = KEY_KP8,
  261. [ 30 ] = KEY_KP9,
  262. [ 31 ] = KEY_KP0,
  263. [ 32 ] = KEY_LANGUAGE,
  264. [ 33 ] = KEY_SLEEP,
  265. };
  266. /* Michael Tokarev <mjt@tls.msk.ru>
  267. http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
  268. keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
  269. least, and probably other cards too.
  270. The "ascii-art picture" below (in comments, first row
  271. is the keycode in hex, and subsequent row(s) shows
  272. the button labels (several variants when appropriate)
  273. helps to descide which keycodes to assign to the buttons.
  274. */
  275. static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
  276. /* 0x1c 0x12 *
  277. * FUNCTION POWER *
  278. * FM (|) *
  279. * */
  280. [ 0x1c ] = KEY_RADIO, /*XXX*/
  281. [ 0x12 ] = KEY_POWER,
  282. /* 0x01 0x02 0x03 *
  283. * 1 2 3 *
  284. * *
  285. * 0x04 0x05 0x06 *
  286. * 4 5 6 *
  287. * *
  288. * 0x07 0x08 0x09 *
  289. * 7 8 9 *
  290. * */
  291. [ 0x01 ] = KEY_KP1,
  292. [ 0x02 ] = KEY_KP2,
  293. [ 0x03 ] = KEY_KP3,
  294. [ 0x04 ] = KEY_KP4,
  295. [ 0x05 ] = KEY_KP5,
  296. [ 0x06 ] = KEY_KP6,
  297. [ 0x07 ] = KEY_KP7,
  298. [ 0x08 ] = KEY_KP8,
  299. [ 0x09 ] = KEY_KP9,
  300. /* 0x0a 0x00 0x17 *
  301. * RECALL 0 +100 *
  302. * PLUS *
  303. * */
  304. [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */
  305. [ 0x00 ] = KEY_KP0,
  306. [ 0x17 ] = KEY_DIGITS, /*XXX*/
  307. /* 0x14 0x10 *
  308. * MENU INFO *
  309. * OSD */
  310. [ 0x14 ] = KEY_MENU,
  311. [ 0x10 ] = KEY_INFO,
  312. /* 0x0b *
  313. * Up *
  314. * *
  315. * 0x18 0x16 0x0c *
  316. * Left Ok Right *
  317. * *
  318. * 0x015 *
  319. * Down *
  320. * */
  321. [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */
  322. [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */
  323. [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */
  324. [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */
  325. [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */
  326. /* 0x11 0x0d *
  327. * TV/AV MODE *
  328. * SOURCE STEREO *
  329. * */
  330. [ 0x11 ] = KEY_TV, /*XXX*/
  331. [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */
  332. /* 0x0f 0x1b 0x1a *
  333. * AUDIO Vol+ Chan+ *
  334. * TIMESHIFT??? *
  335. * *
  336. * 0x0e 0x1f 0x1e *
  337. * SLEEP Vol- Chan- *
  338. * */
  339. [ 0x0f ] = KEY_AUDIO,
  340. [ 0x1b ] = KEY_VOLUMEUP,
  341. [ 0x1a ] = KEY_CHANNELUP,
  342. [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */
  343. [ 0x1f ] = KEY_VOLUMEDOWN,
  344. [ 0x1e ] = KEY_CHANNELDOWN,
  345. /* 0x13 0x19 *
  346. * MUTE SNAPSHOT*
  347. * */
  348. [ 0x13 ] = KEY_MUTE,
  349. [ 0x19 ] = KEY_RECORD, /*XXX*/
  350. // 0x1d unused ?
  351. };
  352. /* Mike Baikov <mike@baikov.com> */
  353. static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
  354. [ 33 ] = KEY_POWER,
  355. [ 105] = KEY_TV,
  356. [ 51 ] = KEY_KP0,
  357. [ 81 ] = KEY_KP1,
  358. [ 49 ] = KEY_KP2,
  359. [ 113] = KEY_KP3,
  360. [ 59 ] = KEY_KP4,
  361. [ 88 ] = KEY_KP5,
  362. [ 65 ] = KEY_KP6,
  363. [ 72 ] = KEY_KP7,
  364. [ 48 ] = KEY_KP8,
  365. [ 83 ] = KEY_KP9,
  366. [ 115] = KEY_AGAIN, /* LOOP */
  367. [ 10 ] = KEY_AUDIO,
  368. [ 97 ] = KEY_PRINT, /* PREVIEW */
  369. [ 122] = KEY_VIDEO,
  370. [ 32 ] = KEY_CHANNELUP,
  371. [ 64 ] = KEY_CHANNELDOWN,
  372. [ 24 ] = KEY_VOLUMEDOWN,
  373. [ 80 ] = KEY_VOLUMEUP,
  374. [ 16 ] = KEY_MUTE,
  375. [ 74 ] = KEY_SEARCH,
  376. [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
  377. [ 34 ] = KEY_RECORD,
  378. [ 98 ] = KEY_STOP,
  379. [ 120] = KEY_PLAY,
  380. [ 57 ] = KEY_REWIND,
  381. [ 89 ] = KEY_PAUSE,
  382. [ 25 ] = KEY_FORWARD,
  383. [ 9 ] = KEY_ZOOM,
  384. [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
  385. [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
  386. [ 58 ] = KEY_F23, /* TIMESHIFT */
  387. [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
  388. };
  389. static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
  390. [ 0x3 ] = KEY_POWER,
  391. [ 0x6f ] = KEY_MUTE,
  392. [ 0x10 ] = KEY_BACKSPACE, /* Recall */
  393. [ 0x11 ] = KEY_KP0,
  394. [ 0x4 ] = KEY_KP1,
  395. [ 0x5 ] = KEY_KP2,
  396. [ 0x6 ] = KEY_KP3,
  397. [ 0x8 ] = KEY_KP4,
  398. [ 0x9 ] = KEY_KP5,
  399. [ 0xa ] = KEY_KP6,
  400. [ 0xc ] = KEY_KP7,
  401. [ 0xd ] = KEY_KP8,
  402. [ 0xe ] = KEY_KP9,
  403. [ 0x12 ] = KEY_KPDOT, /* 100+ */
  404. [ 0x7 ] = KEY_VOLUMEUP,
  405. [ 0xb ] = KEY_VOLUMEDOWN,
  406. [ 0x1a ] = KEY_KPPLUS,
  407. [ 0x18 ] = KEY_KPMINUS,
  408. [ 0x15 ] = KEY_UP,
  409. [ 0x1d ] = KEY_DOWN,
  410. [ 0xf ] = KEY_CHANNELUP,
  411. [ 0x13 ] = KEY_CHANNELDOWN,
  412. [ 0x48 ] = KEY_ZOOM,
  413. [ 0x1b ] = KEY_VIDEO, /* Video source */
  414. [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
  415. [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
  416. [ 0x4b ] = KEY_RECORD,
  417. [ 0x46 ] = KEY_PLAY,
  418. [ 0x45 ] = KEY_PAUSE, /* Pause */
  419. [ 0x44 ] = KEY_STOP,
  420. [ 0x40 ] = KEY_FORWARD, /* Forward ? */
  421. [ 0x42 ] = KEY_REWIND, /* Backward ? */
  422. };
  423. /* Mapping for the 28 key remote control as seen at
  424. http://www.sednacomputer.com/photo/cardbus-tv.jpg
  425. Pavel Mihaylov <bin@bash.info> */
  426. static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
  427. [ 0 ] = KEY_KP0,
  428. [ 1 ] = KEY_KP1,
  429. [ 2 ] = KEY_KP2,
  430. [ 3 ] = KEY_KP3,
  431. [ 4 ] = KEY_KP4,
  432. [ 5 ] = KEY_KP5,
  433. [ 6 ] = KEY_KP6,
  434. [ 7 ] = KEY_KP7,
  435. [ 8 ] = KEY_KP8,
  436. [ 9 ] = KEY_KP9,
  437. [ 0x0a ] = KEY_AGAIN, /* Recall */
  438. [ 0x0b ] = KEY_CHANNELUP,
  439. [ 0x0c ] = KEY_VOLUMEUP,
  440. [ 0x0d ] = KEY_MODE, /* Stereo */
  441. [ 0x0e ] = KEY_STOP,
  442. [ 0x0f ] = KEY_PREVIOUSSONG,
  443. [ 0x10 ] = KEY_ZOOM,
  444. [ 0x11 ] = KEY_TUNER, /* Source */
  445. [ 0x12 ] = KEY_POWER,
  446. [ 0x13 ] = KEY_MUTE,
  447. [ 0x15 ] = KEY_CHANNELDOWN,
  448. [ 0x18 ] = KEY_VOLUMEDOWN,
  449. [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
  450. [ 0x1a ] = KEY_NEXTSONG,
  451. [ 0x1b ] = KEY_TEXT, /* Time Shift */
  452. [ 0x1c ] = KEY_RADIO, /* FM Radio */
  453. [ 0x1d ] = KEY_RECORD,
  454. [ 0x1e ] = KEY_PAUSE,
  455. };
  456. /* -------------------- GPIO generic keycode builder -------------------- */
  457. static int build_key(struct saa7134_dev *dev)
  458. {
  459. struct saa7134_ir *ir = dev->remote;
  460. u32 gpio, data;
  461. /* rising SAA7134_GPIO_GPRESCAN reads the status */
  462. saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
  463. saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
  464. gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
  465. if (ir->polling) {
  466. if (ir->last_gpio == gpio)
  467. return 0;
  468. ir->last_gpio = gpio;
  469. }
  470. data = ir_extract_bits(gpio, ir->mask_keycode);
  471. dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
  472. gpio, ir->mask_keycode, data);
  473. if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
  474. (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
  475. ir_input_keydown(ir->dev, &ir->ir, data, data);
  476. } else {
  477. ir_input_nokey(ir->dev, &ir->ir);
  478. }
  479. return 0;
  480. }
  481. /* --------------------- Chip specific I2C key builders ----------------- */
  482. static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
  483. {
  484. unsigned char b;
  485. /* poll IR chip */
  486. if (1 != i2c_master_recv(&ir->c,&b,1)) {
  487. i2cdprintk("read error\n");
  488. return -EIO;
  489. }
  490. /* no button press */
  491. if (b==0)
  492. return 0;
  493. /* repeating */
  494. if (b & 0x80)
  495. return 1;
  496. *ir_key = b;
  497. *ir_raw = b;
  498. return 1;
  499. }
  500. void saa7134_input_irq(struct saa7134_dev *dev)
  501. {
  502. struct saa7134_ir *ir = dev->remote;
  503. if (!ir->polling)
  504. build_key(dev);
  505. }
  506. static void saa7134_input_timer(unsigned long data)
  507. {
  508. struct saa7134_dev *dev = (struct saa7134_dev*)data;
  509. struct saa7134_ir *ir = dev->remote;
  510. unsigned long timeout;
  511. build_key(dev);
  512. timeout = jiffies + (ir->polling * HZ / 1000);
  513. mod_timer(&ir->timer, timeout);
  514. }
  515. int saa7134_input_init1(struct saa7134_dev *dev)
  516. {
  517. struct saa7134_ir *ir;
  518. struct input_dev *input_dev;
  519. IR_KEYTAB_TYPE *ir_codes = NULL;
  520. u32 mask_keycode = 0;
  521. u32 mask_keydown = 0;
  522. u32 mask_keyup = 0;
  523. int polling = 0;
  524. int ir_type = IR_TYPE_OTHER;
  525. if (dev->has_remote != SAA7134_REMOTE_GPIO)
  526. return -ENODEV;
  527. if (disable_ir)
  528. return -ENODEV;
  529. /* detect & configure */
  530. switch (dev->board) {
  531. case SAA7134_BOARD_FLYVIDEO2000:
  532. case SAA7134_BOARD_FLYVIDEO3000:
  533. case SAA7134_BOARD_FLYTVPLATINUM_FM:
  534. case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
  535. ir_codes = flyvideo_codes;
  536. mask_keycode = 0xEC00000;
  537. mask_keydown = 0x0040000;
  538. break;
  539. case SAA7134_BOARD_CINERGY400:
  540. case SAA7134_BOARD_CINERGY600:
  541. case SAA7134_BOARD_CINERGY600_MK3:
  542. ir_codes = cinergy_codes;
  543. mask_keycode = 0x00003f;
  544. mask_keyup = 0x040000;
  545. break;
  546. case SAA7134_BOARD_ECS_TVP3XP:
  547. case SAA7134_BOARD_ECS_TVP3XP_4CB5:
  548. ir_codes = eztv_codes;
  549. mask_keycode = 0x00017c;
  550. mask_keyup = 0x000002;
  551. polling = 50; // ms
  552. break;
  553. case SAA7134_BOARD_KWORLD_XPERT:
  554. case SAA7134_BOARD_AVACSSMARTTV:
  555. ir_codes = avacssmart_codes;
  556. mask_keycode = 0x00001F;
  557. mask_keyup = 0x000020;
  558. polling = 50; // ms
  559. break;
  560. case SAA7134_BOARD_MD2819:
  561. case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
  562. case SAA7134_BOARD_AVERMEDIA_305:
  563. case SAA7134_BOARD_AVERMEDIA_307:
  564. case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
  565. case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
  566. case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
  567. ir_codes = md2819_codes;
  568. mask_keycode = 0x0007C8;
  569. mask_keydown = 0x000010;
  570. polling = 50; // ms
  571. /* Set GPIO pin2 to high to enable the IR controller */
  572. saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
  573. saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
  574. break;
  575. case SAA7134_BOARD_KWORLD_TERMINATOR:
  576. ir_codes = avacssmart_codes;
  577. mask_keycode = 0x00001f;
  578. mask_keyup = 0x000060;
  579. polling = 50; // ms
  580. break;
  581. case SAA7134_BOARD_MANLI_MTV001:
  582. case SAA7134_BOARD_MANLI_MTV002:
  583. case SAA7134_BOARD_BEHOLD_409FM:
  584. ir_codes = manli_codes;
  585. mask_keycode = 0x001f00;
  586. mask_keyup = 0x004000;
  587. polling = 50; // ms
  588. break;
  589. case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
  590. ir_codes = pctv_sedna_codes;
  591. mask_keycode = 0x001f00;
  592. mask_keyup = 0x004000;
  593. polling = 50; // ms
  594. break;
  595. case SAA7134_BOARD_GOTVIEW_7135:
  596. ir_codes = gotview7135_codes;
  597. mask_keycode = 0x0003EC;
  598. mask_keyup = 0x008000;
  599. mask_keydown = 0x000010;
  600. polling = 50; // ms
  601. break;
  602. case SAA7134_BOARD_VIDEOMATE_TV_PVR:
  603. case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
  604. case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
  605. ir_codes = videomate_tv_pvr_codes;
  606. mask_keycode = 0x00003F;
  607. mask_keyup = 0x400000;
  608. polling = 50; // ms
  609. break;
  610. case SAA7134_BOARD_VIDEOMATE_DVBT_300:
  611. case SAA7134_BOARD_VIDEOMATE_DVBT_200:
  612. ir_codes = videomate_tv_pvr_codes;
  613. mask_keycode = 0x003F00;
  614. mask_keyup = 0x040000;
  615. break;
  616. }
  617. if (NULL == ir_codes) {
  618. printk("%s: Oops: IR config error [card=%d]\n",
  619. dev->name, dev->board);
  620. return -ENODEV;
  621. }
  622. ir = kzalloc(sizeof(*ir), GFP_KERNEL);
  623. input_dev = input_allocate_device();
  624. if (!ir || !input_dev) {
  625. kfree(ir);
  626. input_free_device(input_dev);
  627. return -ENOMEM;
  628. }
  629. ir->dev = input_dev;
  630. /* init hardware-specific stuff */
  631. ir->mask_keycode = mask_keycode;
  632. ir->mask_keydown = mask_keydown;
  633. ir->mask_keyup = mask_keyup;
  634. ir->polling = polling;
  635. /* init input device */
  636. snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
  637. saa7134_boards[dev->board].name);
  638. snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
  639. pci_name(dev->pci));
  640. ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
  641. input_dev->name = ir->name;
  642. input_dev->phys = ir->phys;
  643. input_dev->id.bustype = BUS_PCI;
  644. input_dev->id.version = 1;
  645. if (dev->pci->subsystem_vendor) {
  646. input_dev->id.vendor = dev->pci->subsystem_vendor;
  647. input_dev->id.product = dev->pci->subsystem_device;
  648. } else {
  649. input_dev->id.vendor = dev->pci->vendor;
  650. input_dev->id.product = dev->pci->device;
  651. }
  652. input_dev->cdev.dev = &dev->pci->dev;
  653. /* all done */
  654. dev->remote = ir;
  655. if (ir->polling) {
  656. init_timer(&ir->timer);
  657. ir->timer.function = saa7134_input_timer;
  658. ir->timer.data = (unsigned long)dev;
  659. ir->timer.expires = jiffies + HZ;
  660. add_timer(&ir->timer);
  661. }
  662. input_register_device(ir->dev);
  663. return 0;
  664. }
  665. void saa7134_input_fini(struct saa7134_dev *dev)
  666. {
  667. if (NULL == dev->remote)
  668. return;
  669. if (dev->remote->polling)
  670. del_timer_sync(&dev->remote->timer);
  671. input_unregister_device(dev->remote->dev);
  672. kfree(dev->remote);
  673. dev->remote = NULL;
  674. }
  675. void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
  676. {
  677. if (disable_ir) {
  678. dprintk("Found supported i2c remote, but IR has been disabled\n");
  679. ir->get_key=NULL;
  680. return;
  681. }
  682. switch (dev->board) {
  683. case SAA7134_BOARD_PINNACLE_PCTV_110i:
  684. snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
  685. ir->get_key = get_key_pinnacle;
  686. ir->ir_codes = ir_codes_pinnacle;
  687. break;
  688. case SAA7134_BOARD_UPMOST_PURPLE_TV:
  689. snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
  690. ir->get_key = get_key_purpletv;
  691. ir->ir_codes = ir_codes_purpletv;
  692. break;
  693. default:
  694. dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
  695. break;
  696. }
  697. }
  698. /* ----------------------------------------------------------------------
  699. * Local variables:
  700. * c-basic-offset: 8
  701. * End:
  702. */