1/* 2 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2012 Intel, Inc. 4 * 5 * This software is licensed under the terms of the GNU General Public 6 * License version 2, as published by the Free Software Foundation, and 7 * may be copied, distributed, and modified under those terms. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15 16#include <linux/module.h> 17#include <linux/interrupt.h> 18#include <linux/types.h> 19#include <linux/input.h> 20#include <linux/kernel.h> 21#include <linux/platform_device.h> 22#include <linux/slab.h> 23#include <linux/irq.h> 24#include <linux/io.h> 25 26enum { 27 REG_READ = 0x00, 28 REG_SET_PAGE = 0x00, 29 REG_LEN = 0x04, 30 REG_DATA = 0x08, 31 32 PAGE_NAME = 0x00000, 33 PAGE_EVBITS = 0x10000, 34 PAGE_ABSDATA = 0x20000 | EV_ABS, 35}; 36 37struct event_dev { 38 struct input_dev *input; 39 int irq; 40 void __iomem *addr; 41 char name[0]; 42}; 43 44static irqreturn_t events_interrupt(int irq, void *dev_id) 45{ 46 struct event_dev *edev = dev_id; 47 unsigned type, code, value; 48 49 type = __raw_readl(edev->addr + REG_READ); 50 code = __raw_readl(edev->addr + REG_READ); 51 value = __raw_readl(edev->addr + REG_READ); 52 53 input_event(edev->input, type, code, value); 54 input_sync(edev->input); 55 return IRQ_HANDLED; 56} 57 58static void events_import_bits(struct event_dev *edev, 59 unsigned long bits[], unsigned type, size_t count) 60{ 61 void __iomem *addr = edev->addr; 62 int i, j; 63 size_t size; 64 uint8_t val; 65 66 __raw_writel(PAGE_EVBITS | type, addr + REG_SET_PAGE); 67 68 size = __raw_readl(addr + REG_LEN) * 8; 69 if (size < count) 70 count = size; 71 72 addr += REG_DATA; 73 for (i = 0; i < count; i += 8) { 74 val = __raw_readb(addr++); 75 for (j = 0; j < 8; j++) 76 if (val & 1 << j) 77 set_bit(i + j, bits); 78 } 79} 80 81static void events_import_abs_params(struct event_dev *edev) 82{ 83 struct input_dev *input_dev = edev->input; 84 void __iomem *addr = edev->addr; 85 u32 val[4]; 86 int count; 87 int i, j; 88 89 __raw_writel(PAGE_ABSDATA, addr + REG_SET_PAGE); 90 91 count = __raw_readl(addr + REG_LEN) / sizeof(val); 92 if (count > ABS_MAX) 93 count = ABS_MAX; 94 95 for (i = 0; i < count; i++) { 96 if (!test_bit(i, input_dev->absbit)) 97 continue; 98 99 for (j = 0; j < ARRAY_SIZE(val); j++) { 100 int offset = (i * ARRAY_SIZE(val) + j) * sizeof(u32); 101 val[j] = __raw_readl(edev->addr + REG_DATA + offset); 102 } 103 104 input_set_abs_params(input_dev, i, 105 val[0], val[1], val[2], val[3]); 106 } 107} 108 109static int events_probe(struct platform_device *pdev) 110{ 111 struct input_dev *input_dev; 112 struct event_dev *edev; 113 struct resource *res; 114 unsigned keymapnamelen; 115 void __iomem *addr; 116 int irq; 117 int i; 118 int error; 119 120 irq = platform_get_irq(pdev, 0); 121 if (irq < 0) 122 return -EINVAL; 123 124 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 125 if (!res) 126 return -EINVAL; 127 128 addr = devm_ioremap(&pdev->dev, res->start, 4096); 129 if (!addr) 130 return -ENOMEM; 131 132 __raw_writel(PAGE_NAME, addr + REG_SET_PAGE); 133 keymapnamelen = __raw_readl(addr + REG_LEN); 134 135 edev = devm_kzalloc(&pdev->dev, 136 sizeof(struct event_dev) + keymapnamelen + 1, 137 GFP_KERNEL); 138 if (!edev) 139 return -ENOMEM; 140 141 input_dev = devm_input_allocate_device(&pdev->dev); 142 if (!input_dev) 143 return -ENOMEM; 144 145 edev->input = input_dev; 146 edev->addr = addr; 147 edev->irq = irq; 148 149 for (i = 0; i < keymapnamelen; i++) 150 edev->name[i] = __raw_readb(edev->addr + REG_DATA + i); 151 152 pr_debug("events_probe() keymap=%s\n", edev->name); 153 154 input_dev->name = edev->name; 155 input_dev->id.bustype = BUS_HOST; 156 157 events_import_bits(edev, input_dev->evbit, EV_SYN, EV_MAX); 158 events_import_bits(edev, input_dev->keybit, EV_KEY, KEY_MAX); 159 events_import_bits(edev, input_dev->relbit, EV_REL, REL_MAX); 160 events_import_bits(edev, input_dev->absbit, EV_ABS, ABS_MAX); 161 events_import_bits(edev, input_dev->mscbit, EV_MSC, MSC_MAX); 162 events_import_bits(edev, input_dev->ledbit, EV_LED, LED_MAX); 163 events_import_bits(edev, input_dev->sndbit, EV_SND, SND_MAX); 164 events_import_bits(edev, input_dev->ffbit, EV_FF, FF_MAX); 165 events_import_bits(edev, input_dev->swbit, EV_SW, SW_MAX); 166 167 events_import_abs_params(edev); 168 169 error = devm_request_irq(&pdev->dev, edev->irq, events_interrupt, 0, 170 "goldfish-events-keypad", edev); 171 if (error) 172 return error; 173 174 error = input_register_device(input_dev); 175 if (error) 176 return error; 177 178 return 0; 179} 180 181static struct platform_driver events_driver = { 182 .probe = events_probe, 183 .driver = { 184 .name = "goldfish_events", 185 }, 186}; 187 188module_platform_driver(events_driver); 189 190MODULE_AUTHOR("Brian Swetland"); 191MODULE_DESCRIPTION("Goldfish Event Device"); 192MODULE_LICENSE("GPL"); 193