0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/input.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/io.h>
0012 #include <linux/slab.h>
0013
0014 #include <linux/platform_data/keyboard-pxa930_rotary.h>
0015
0016 #define SBCR (0x04)
0017 #define ERCR (0x0c)
0018
0019 #define SBCR_ERSB (1 << 5)
0020
0021 struct pxa930_rotary {
0022 struct input_dev *input_dev;
0023 void __iomem *mmio_base;
0024 int last_ercr;
0025
0026 struct pxa930_rotary_platform_data *pdata;
0027 };
0028
0029 static void clear_sbcr(struct pxa930_rotary *r)
0030 {
0031 uint32_t sbcr = __raw_readl(r->mmio_base + SBCR);
0032
0033 __raw_writel(sbcr | SBCR_ERSB, r->mmio_base + SBCR);
0034 __raw_writel(sbcr & ~SBCR_ERSB, r->mmio_base + SBCR);
0035 }
0036
0037 static irqreturn_t rotary_irq(int irq, void *dev_id)
0038 {
0039 struct pxa930_rotary *r = dev_id;
0040 struct pxa930_rotary_platform_data *pdata = r->pdata;
0041 int ercr, delta, key;
0042
0043 ercr = __raw_readl(r->mmio_base + ERCR) & 0xf;
0044 clear_sbcr(r);
0045
0046 delta = ercr - r->last_ercr;
0047 if (delta == 0)
0048 return IRQ_HANDLED;
0049
0050 r->last_ercr = ercr;
0051
0052 if (pdata->up_key && pdata->down_key) {
0053 key = (delta > 0) ? pdata->up_key : pdata->down_key;
0054 input_report_key(r->input_dev, key, 1);
0055 input_sync(r->input_dev);
0056 input_report_key(r->input_dev, key, 0);
0057 } else
0058 input_report_rel(r->input_dev, pdata->rel_code, delta);
0059
0060 input_sync(r->input_dev);
0061
0062 return IRQ_HANDLED;
0063 }
0064
0065 static int pxa930_rotary_open(struct input_dev *dev)
0066 {
0067 struct pxa930_rotary *r = input_get_drvdata(dev);
0068
0069 clear_sbcr(r);
0070
0071 return 0;
0072 }
0073
0074 static void pxa930_rotary_close(struct input_dev *dev)
0075 {
0076 struct pxa930_rotary *r = input_get_drvdata(dev);
0077
0078 clear_sbcr(r);
0079 }
0080
0081 static int pxa930_rotary_probe(struct platform_device *pdev)
0082 {
0083 struct pxa930_rotary_platform_data *pdata =
0084 dev_get_platdata(&pdev->dev);
0085 struct pxa930_rotary *r;
0086 struct input_dev *input_dev;
0087 struct resource *res;
0088 int irq;
0089 int err;
0090
0091 irq = platform_get_irq(pdev, 0);
0092 if (irq < 0)
0093 return -ENXIO;
0094
0095 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0096 if (!res) {
0097 dev_err(&pdev->dev, "no I/O memory defined\n");
0098 return -ENXIO;
0099 }
0100
0101 if (!pdata) {
0102 dev_err(&pdev->dev, "no platform data defined\n");
0103 return -EINVAL;
0104 }
0105
0106 r = kzalloc(sizeof(struct pxa930_rotary), GFP_KERNEL);
0107 if (!r)
0108 return -ENOMEM;
0109
0110 r->mmio_base = ioremap(res->start, resource_size(res));
0111 if (r->mmio_base == NULL) {
0112 dev_err(&pdev->dev, "failed to remap IO memory\n");
0113 err = -ENXIO;
0114 goto failed_free;
0115 }
0116
0117 r->pdata = pdata;
0118 platform_set_drvdata(pdev, r);
0119
0120
0121 input_dev = input_allocate_device();
0122 if (!input_dev) {
0123 dev_err(&pdev->dev, "failed to allocate input device\n");
0124 err = -ENOMEM;
0125 goto failed_free_io;
0126 }
0127
0128 input_dev->name = pdev->name;
0129 input_dev->id.bustype = BUS_HOST;
0130 input_dev->open = pxa930_rotary_open;
0131 input_dev->close = pxa930_rotary_close;
0132 input_dev->dev.parent = &pdev->dev;
0133
0134 if (pdata->up_key && pdata->down_key) {
0135 __set_bit(pdata->up_key, input_dev->keybit);
0136 __set_bit(pdata->down_key, input_dev->keybit);
0137 __set_bit(EV_KEY, input_dev->evbit);
0138 } else {
0139 __set_bit(pdata->rel_code, input_dev->relbit);
0140 __set_bit(EV_REL, input_dev->evbit);
0141 }
0142
0143 r->input_dev = input_dev;
0144 input_set_drvdata(input_dev, r);
0145
0146 err = request_irq(irq, rotary_irq, 0,
0147 "enhanced rotary", r);
0148 if (err) {
0149 dev_err(&pdev->dev, "failed to request IRQ\n");
0150 goto failed_free_input;
0151 }
0152
0153 err = input_register_device(input_dev);
0154 if (err) {
0155 dev_err(&pdev->dev, "failed to register input device\n");
0156 goto failed_free_irq;
0157 }
0158
0159 return 0;
0160
0161 failed_free_irq:
0162 free_irq(irq, r);
0163 failed_free_input:
0164 input_free_device(input_dev);
0165 failed_free_io:
0166 iounmap(r->mmio_base);
0167 failed_free:
0168 kfree(r);
0169 return err;
0170 }
0171
0172 static int pxa930_rotary_remove(struct platform_device *pdev)
0173 {
0174 struct pxa930_rotary *r = platform_get_drvdata(pdev);
0175
0176 free_irq(platform_get_irq(pdev, 0), r);
0177 input_unregister_device(r->input_dev);
0178 iounmap(r->mmio_base);
0179 kfree(r);
0180
0181 return 0;
0182 }
0183
0184 static struct platform_driver pxa930_rotary_driver = {
0185 .driver = {
0186 .name = "pxa930-rotary",
0187 },
0188 .probe = pxa930_rotary_probe,
0189 .remove = pxa930_rotary_remove,
0190 };
0191 module_platform_driver(pxa930_rotary_driver);
0192
0193 MODULE_LICENSE("GPL");
0194 MODULE_DESCRIPTION("Driver for PXA93x Enhanced Rotary Controller");
0195 MODULE_AUTHOR("Yao Yong <yaoyong@marvell.com>");