zx-irdec.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (C) 2017 Sanechips Technology Co., Ltd.
  3. * Copyright 2017 Linaro Ltd.
  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 version 2 as
  7. * published by the Free Software Foundation.
  8. */
  9. #include <linux/device.h>
  10. #include <linux/err.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/io.h>
  13. #include <linux/module.h>
  14. #include <linux/of_platform.h>
  15. #include <linux/platform_device.h>
  16. #include <media/rc-core.h>
  17. #define DRIVER_NAME "zx-irdec"
  18. #define ZX_IR_ENABLE 0x04
  19. #define ZX_IREN BIT(0)
  20. #define ZX_IR_CTRL 0x08
  21. #define ZX_DEGL_MASK GENMASK(21, 20)
  22. #define ZX_DEGL_VALUE(x) (((x) << 20) & ZX_DEGL_MASK)
  23. #define ZX_WDBEGIN_MASK GENMASK(18, 8)
  24. #define ZX_WDBEGIN_VALUE(x) (((x) << 8) & ZX_WDBEGIN_MASK)
  25. #define ZX_IR_INTEN 0x10
  26. #define ZX_IR_INTSTCLR 0x14
  27. #define ZX_IR_CODE 0x30
  28. #define ZX_IR_CNUM 0x34
  29. #define ZX_NECRPT BIT(16)
  30. struct zx_irdec {
  31. void __iomem *base;
  32. struct rc_dev *rcd;
  33. };
  34. static void zx_irdec_set_mask(struct zx_irdec *irdec, unsigned int reg,
  35. u32 mask, u32 value)
  36. {
  37. u32 data;
  38. data = readl(irdec->base + reg);
  39. data &= ~mask;
  40. data |= value & mask;
  41. writel(data, irdec->base + reg);
  42. }
  43. static irqreturn_t zx_irdec_irq(int irq, void *dev_id)
  44. {
  45. struct zx_irdec *irdec = dev_id;
  46. u8 address, not_address;
  47. u8 command, not_command;
  48. u32 rawcode, scancode;
  49. enum rc_proto rc_proto;
  50. /* Clear interrupt */
  51. writel(1, irdec->base + ZX_IR_INTSTCLR);
  52. /* Check repeat frame */
  53. if (readl(irdec->base + ZX_IR_CNUM) & ZX_NECRPT) {
  54. rc_repeat(irdec->rcd);
  55. goto done;
  56. }
  57. rawcode = readl(irdec->base + ZX_IR_CODE);
  58. not_command = (rawcode >> 24) & 0xff;
  59. command = (rawcode >> 16) & 0xff;
  60. not_address = (rawcode >> 8) & 0xff;
  61. address = rawcode & 0xff;
  62. scancode = ir_nec_bytes_to_scancode(address, not_address,
  63. command, not_command,
  64. &rc_proto);
  65. rc_keydown(irdec->rcd, rc_proto, scancode, 0);
  66. done:
  67. return IRQ_HANDLED;
  68. }
  69. static int zx_irdec_probe(struct platform_device *pdev)
  70. {
  71. struct device *dev = &pdev->dev;
  72. struct zx_irdec *irdec;
  73. struct resource *res;
  74. struct rc_dev *rcd;
  75. int irq;
  76. int ret;
  77. irdec = devm_kzalloc(dev, sizeof(*irdec), GFP_KERNEL);
  78. if (!irdec)
  79. return -ENOMEM;
  80. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  81. irdec->base = devm_ioremap_resource(dev, res);
  82. if (IS_ERR(irdec->base))
  83. return PTR_ERR(irdec->base);
  84. irq = platform_get_irq(pdev, 0);
  85. if (irq < 0)
  86. return irq;
  87. rcd = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE);
  88. if (!rcd) {
  89. dev_err(dev, "failed to allocate rc device\n");
  90. return -ENOMEM;
  91. }
  92. irdec->rcd = rcd;
  93. rcd->priv = irdec;
  94. rcd->input_phys = DRIVER_NAME "/input0";
  95. rcd->input_id.bustype = BUS_HOST;
  96. rcd->map_name = RC_MAP_ZX_IRDEC;
  97. rcd->allowed_protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX |
  98. RC_PROTO_BIT_NEC32;
  99. rcd->driver_name = DRIVER_NAME;
  100. rcd->device_name = DRIVER_NAME;
  101. platform_set_drvdata(pdev, irdec);
  102. ret = devm_rc_register_device(dev, rcd);
  103. if (ret) {
  104. dev_err(dev, "failed to register rc device\n");
  105. return ret;
  106. }
  107. ret = devm_request_irq(dev, irq, zx_irdec_irq, 0, NULL, irdec);
  108. if (ret) {
  109. dev_err(dev, "failed to request irq\n");
  110. return ret;
  111. }
  112. /*
  113. * Initialize deglitch level and watchdog counter beginner as
  114. * recommended by vendor BSP code.
  115. */
  116. zx_irdec_set_mask(irdec, ZX_IR_CTRL, ZX_DEGL_MASK, ZX_DEGL_VALUE(0));
  117. zx_irdec_set_mask(irdec, ZX_IR_CTRL, ZX_WDBEGIN_MASK,
  118. ZX_WDBEGIN_VALUE(0x21c));
  119. /* Enable interrupt */
  120. writel(1, irdec->base + ZX_IR_INTEN);
  121. /* Enable the decoder */
  122. zx_irdec_set_mask(irdec, ZX_IR_ENABLE, ZX_IREN, ZX_IREN);
  123. return 0;
  124. }
  125. static int zx_irdec_remove(struct platform_device *pdev)
  126. {
  127. struct zx_irdec *irdec = platform_get_drvdata(pdev);
  128. /* Disable the decoder */
  129. zx_irdec_set_mask(irdec, ZX_IR_ENABLE, ZX_IREN, 0);
  130. /* Disable interrupt */
  131. writel(0, irdec->base + ZX_IR_INTEN);
  132. return 0;
  133. }
  134. static const struct of_device_id zx_irdec_match[] = {
  135. { .compatible = "zte,zx296718-irdec" },
  136. { },
  137. };
  138. MODULE_DEVICE_TABLE(of, zx_irdec_match);
  139. static struct platform_driver zx_irdec_driver = {
  140. .probe = zx_irdec_probe,
  141. .remove = zx_irdec_remove,
  142. .driver = {
  143. .name = DRIVER_NAME,
  144. .of_match_table = zx_irdec_match,
  145. },
  146. };
  147. module_platform_driver(zx_irdec_driver);
  148. MODULE_DESCRIPTION("ZTE ZX IR remote control driver");
  149. MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  150. MODULE_LICENSE("GPL v2");