saa7134-input.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. /* -------------------- GPIO generic keycode builder -------------------- */
  40. static int build_key(struct saa7134_dev *dev)
  41. {
  42. struct saa7134_ir *ir = dev->remote;
  43. u32 gpio, data;
  44. /* rising SAA7134_GPIO_GPRESCAN reads the status */
  45. saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
  46. saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
  47. gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
  48. if (ir->polling) {
  49. if (ir->last_gpio == gpio)
  50. return 0;
  51. ir->last_gpio = gpio;
  52. }
  53. data = ir_extract_bits(gpio, ir->mask_keycode);
  54. dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
  55. gpio, ir->mask_keycode, data);
  56. if (ir->polling) {
  57. if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
  58. (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
  59. ir_input_keydown(ir->dev, &ir->ir, data, data);
  60. } else {
  61. ir_input_nokey(ir->dev, &ir->ir);
  62. }
  63. }
  64. else { /* IRQ driven mode - handle key press and release in one go */
  65. if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
  66. (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
  67. ir_input_keydown(ir->dev, &ir->ir, data, data);
  68. ir_input_nokey(ir->dev, &ir->ir);
  69. }
  70. }
  71. return 0;
  72. }
  73. /* --------------------- Chip specific I2C key builders ----------------- */
  74. static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
  75. {
  76. unsigned char b;
  77. /* poll IR chip */
  78. if (1 != i2c_master_recv(&ir->c,&b,1)) {
  79. i2cdprintk("read error\n");
  80. return -EIO;
  81. }
  82. /* no button press */
  83. if (b==0)
  84. return 0;
  85. /* repeating */
  86. if (b & 0x80)
  87. return 1;
  88. *ir_key = b;
  89. *ir_raw = b;
  90. return 1;
  91. }
  92. void saa7134_input_irq(struct saa7134_dev *dev)
  93. {
  94. struct saa7134_ir *ir = dev->remote;
  95. if (!ir->polling)
  96. build_key(dev);
  97. }
  98. static void saa7134_input_timer(unsigned long data)
  99. {
  100. struct saa7134_dev *dev = (struct saa7134_dev*)data;
  101. struct saa7134_ir *ir = dev->remote;
  102. unsigned long timeout;
  103. build_key(dev);
  104. timeout = jiffies + (ir->polling * HZ / 1000);
  105. mod_timer(&ir->timer, timeout);
  106. }
  107. int saa7134_input_init1(struct saa7134_dev *dev)
  108. {
  109. struct saa7134_ir *ir;
  110. struct input_dev *input_dev;
  111. IR_KEYTAB_TYPE *ir_codes = NULL;
  112. u32 mask_keycode = 0;
  113. u32 mask_keydown = 0;
  114. u32 mask_keyup = 0;
  115. int polling = 0;
  116. int ir_type = IR_TYPE_OTHER;
  117. if (dev->has_remote != SAA7134_REMOTE_GPIO)
  118. return -ENODEV;
  119. if (disable_ir)
  120. return -ENODEV;
  121. /* detect & configure */
  122. switch (dev->board) {
  123. case SAA7134_BOARD_FLYVIDEO2000:
  124. case SAA7134_BOARD_FLYVIDEO3000:
  125. case SAA7134_BOARD_FLYTVPLATINUM_FM:
  126. case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
  127. ir_codes = ir_codes_flyvideo;
  128. mask_keycode = 0xEC00000;
  129. mask_keydown = 0x0040000;
  130. break;
  131. case SAA7134_BOARD_CINERGY400:
  132. case SAA7134_BOARD_CINERGY600:
  133. case SAA7134_BOARD_CINERGY600_MK3:
  134. ir_codes = ir_codes_cinergy;
  135. mask_keycode = 0x00003f;
  136. mask_keyup = 0x040000;
  137. break;
  138. case SAA7134_BOARD_ECS_TVP3XP:
  139. case SAA7134_BOARD_ECS_TVP3XP_4CB5:
  140. ir_codes = ir_codes_eztv;
  141. mask_keycode = 0x00017c;
  142. mask_keyup = 0x000002;
  143. polling = 50; // ms
  144. break;
  145. case SAA7134_BOARD_KWORLD_XPERT:
  146. case SAA7134_BOARD_AVACSSMARTTV:
  147. ir_codes = ir_codes_pixelview;
  148. mask_keycode = 0x00001F;
  149. mask_keyup = 0x000020;
  150. polling = 50; // ms
  151. break;
  152. case SAA7134_BOARD_MD2819:
  153. case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
  154. case SAA7134_BOARD_AVERMEDIA_305:
  155. case SAA7134_BOARD_AVERMEDIA_307:
  156. case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
  157. case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
  158. case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
  159. ir_codes = ir_codes_avermedia;
  160. mask_keycode = 0x0007C8;
  161. mask_keydown = 0x000010;
  162. polling = 50; // ms
  163. /* Set GPIO pin2 to high to enable the IR controller */
  164. saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
  165. saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
  166. break;
  167. case SAA7134_BOARD_KWORLD_TERMINATOR:
  168. ir_codes = ir_codes_pixelview;
  169. mask_keycode = 0x00001f;
  170. mask_keyup = 0x000060;
  171. polling = 50; // ms
  172. break;
  173. case SAA7134_BOARD_MANLI_MTV001:
  174. case SAA7134_BOARD_MANLI_MTV002:
  175. case SAA7134_BOARD_BEHOLD_409FM:
  176. ir_codes = ir_codes_manli;
  177. mask_keycode = 0x001f00;
  178. mask_keyup = 0x004000;
  179. polling = 50; // ms
  180. break;
  181. case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
  182. ir_codes = ir_codes_pctv_sedna;
  183. mask_keycode = 0x001f00;
  184. mask_keyup = 0x004000;
  185. polling = 50; // ms
  186. break;
  187. case SAA7134_BOARD_GOTVIEW_7135:
  188. ir_codes = ir_codes_gotview7135;
  189. mask_keycode = 0x0003EC;
  190. mask_keyup = 0x008000;
  191. mask_keydown = 0x000010;
  192. polling = 50; // ms
  193. break;
  194. case SAA7134_BOARD_VIDEOMATE_TV_PVR:
  195. case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
  196. case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
  197. ir_codes = ir_codes_videomate_tv_pvr;
  198. mask_keycode = 0x00003F;
  199. mask_keyup = 0x400000;
  200. polling = 50; // ms
  201. break;
  202. case SAA7134_BOARD_VIDEOMATE_DVBT_300:
  203. case SAA7134_BOARD_VIDEOMATE_DVBT_200:
  204. ir_codes = ir_codes_videomate_tv_pvr;
  205. mask_keycode = 0x003F00;
  206. mask_keyup = 0x040000;
  207. break;
  208. case SAA7134_BOARD_FLYDVBT_LR301:
  209. case SAA7134_BOARD_FLYDVBTDUO:
  210. ir_codes = ir_codes_flydvb;
  211. mask_keycode = 0x0001F00;
  212. mask_keydown = 0x0040000;
  213. break;
  214. }
  215. if (NULL == ir_codes) {
  216. printk("%s: Oops: IR config error [card=%d]\n",
  217. dev->name, dev->board);
  218. return -ENODEV;
  219. }
  220. ir = kzalloc(sizeof(*ir), GFP_KERNEL);
  221. input_dev = input_allocate_device();
  222. if (!ir || !input_dev) {
  223. kfree(ir);
  224. input_free_device(input_dev);
  225. return -ENOMEM;
  226. }
  227. ir->dev = input_dev;
  228. /* init hardware-specific stuff */
  229. ir->mask_keycode = mask_keycode;
  230. ir->mask_keydown = mask_keydown;
  231. ir->mask_keyup = mask_keyup;
  232. ir->polling = polling;
  233. /* init input device */
  234. snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
  235. saa7134_boards[dev->board].name);
  236. snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
  237. pci_name(dev->pci));
  238. ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
  239. input_dev->name = ir->name;
  240. input_dev->phys = ir->phys;
  241. input_dev->id.bustype = BUS_PCI;
  242. input_dev->id.version = 1;
  243. if (dev->pci->subsystem_vendor) {
  244. input_dev->id.vendor = dev->pci->subsystem_vendor;
  245. input_dev->id.product = dev->pci->subsystem_device;
  246. } else {
  247. input_dev->id.vendor = dev->pci->vendor;
  248. input_dev->id.product = dev->pci->device;
  249. }
  250. input_dev->cdev.dev = &dev->pci->dev;
  251. /* all done */
  252. dev->remote = ir;
  253. if (ir->polling) {
  254. init_timer(&ir->timer);
  255. ir->timer.function = saa7134_input_timer;
  256. ir->timer.data = (unsigned long)dev;
  257. ir->timer.expires = jiffies + HZ;
  258. add_timer(&ir->timer);
  259. }
  260. input_register_device(ir->dev);
  261. return 0;
  262. }
  263. void saa7134_input_fini(struct saa7134_dev *dev)
  264. {
  265. if (NULL == dev->remote)
  266. return;
  267. if (dev->remote->polling)
  268. del_timer_sync(&dev->remote->timer);
  269. input_unregister_device(dev->remote->dev);
  270. kfree(dev->remote);
  271. dev->remote = NULL;
  272. }
  273. void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
  274. {
  275. if (disable_ir) {
  276. dprintk("Found supported i2c remote, but IR has been disabled\n");
  277. ir->get_key=NULL;
  278. return;
  279. }
  280. switch (dev->board) {
  281. case SAA7134_BOARD_PINNACLE_PCTV_110i:
  282. snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
  283. ir->get_key = get_key_pinnacle;
  284. ir->ir_codes = ir_codes_pinnacle;
  285. break;
  286. case SAA7134_BOARD_UPMOST_PURPLE_TV:
  287. snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
  288. ir->get_key = get_key_purpletv;
  289. ir->ir_codes = ir_codes_purpletv;
  290. break;
  291. default:
  292. dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
  293. break;
  294. }
  295. }
  296. /* ----------------------------------------------------------------------
  297. * Local variables:
  298. * c-basic-offset: 8
  299. * End:
  300. */