root/drivers/media/rc/zx-irdec.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zx_irdec_set_mask
  2. zx_irdec_irq
  3. zx_irdec_probe
  4. zx_irdec_remove

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

/* [<][>][^][v][top][bottom][index][help] */