0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/clk.h>
0014 #include <linux/errno.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/input.h>
0017 #include <linux/io.h>
0018 #include <linux/irq.h>
0019 #include <linux/kernel.h>
0020 #include <linux/module.h>
0021 #include <linux/of.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/pm_wakeup.h>
0024 #include <linux/slab.h>
0025 #include <linux/types.h>
0026 #include <linux/platform_data/keyboard-spear.h>
0027
0028
0029 #define MODE_CTL_REG 0x00
0030 #define STATUS_REG 0x0C
0031 #define DATA_REG 0x10
0032 #define INTR_MASK 0x54
0033
0034
0035 #define NUM_ROWS 16
0036 #define NUM_COLS 16
0037 #define MODE_CTL_PCLK_FREQ_SHIFT 9
0038 #define MODE_CTL_PCLK_FREQ_MSK 0x7F
0039
0040 #define MODE_CTL_KEYBOARD (0x2 << 0)
0041 #define MODE_CTL_SCAN_RATE_10 (0x0 << 2)
0042 #define MODE_CTL_SCAN_RATE_20 (0x1 << 2)
0043 #define MODE_CTL_SCAN_RATE_40 (0x2 << 2)
0044 #define MODE_CTL_SCAN_RATE_80 (0x3 << 2)
0045 #define MODE_CTL_KEYNUM_SHIFT 6
0046 #define MODE_CTL_START_SCAN (0x1 << 8)
0047
0048 #define STATUS_DATA_AVAIL (0x1 << 1)
0049
0050 #define DATA_ROW_MASK 0xF0
0051 #define DATA_COLUMN_MASK 0x0F
0052
0053 #define ROW_SHIFT 4
0054
0055 struct spear_kbd {
0056 struct input_dev *input;
0057 void __iomem *io_base;
0058 struct clk *clk;
0059 unsigned int irq;
0060 unsigned int mode;
0061 unsigned int suspended_rate;
0062 unsigned short last_key;
0063 unsigned short keycodes[NUM_ROWS * NUM_COLS];
0064 bool rep;
0065 bool irq_wake_enabled;
0066 u32 mode_ctl_reg;
0067 };
0068
0069 static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
0070 {
0071 struct spear_kbd *kbd = dev_id;
0072 struct input_dev *input = kbd->input;
0073 unsigned int key;
0074 u32 sts, val;
0075
0076 sts = readl_relaxed(kbd->io_base + STATUS_REG);
0077 if (!(sts & STATUS_DATA_AVAIL))
0078 return IRQ_NONE;
0079
0080 if (kbd->last_key != KEY_RESERVED) {
0081 input_report_key(input, kbd->last_key, 0);
0082 kbd->last_key = KEY_RESERVED;
0083 }
0084
0085
0086 val = readl_relaxed(kbd->io_base + DATA_REG) &
0087 (DATA_ROW_MASK | DATA_COLUMN_MASK);
0088 key = kbd->keycodes[val];
0089
0090 input_event(input, EV_MSC, MSC_SCAN, val);
0091 input_report_key(input, key, 1);
0092 input_sync(input);
0093
0094 kbd->last_key = key;
0095
0096
0097 writel_relaxed(0, kbd->io_base + STATUS_REG);
0098
0099 return IRQ_HANDLED;
0100 }
0101
0102 static int spear_kbd_open(struct input_dev *dev)
0103 {
0104 struct spear_kbd *kbd = input_get_drvdata(dev);
0105 int error;
0106 u32 val;
0107
0108 kbd->last_key = KEY_RESERVED;
0109
0110 error = clk_enable(kbd->clk);
0111 if (error)
0112 return error;
0113
0114
0115 val = clk_get_rate(kbd->clk) / 1000000 - 1;
0116 val = (val & MODE_CTL_PCLK_FREQ_MSK) << MODE_CTL_PCLK_FREQ_SHIFT;
0117
0118
0119 val = MODE_CTL_SCAN_RATE_80 | MODE_CTL_KEYBOARD | val |
0120 (kbd->mode << MODE_CTL_KEYNUM_SHIFT);
0121 writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
0122 writel_relaxed(1, kbd->io_base + STATUS_REG);
0123
0124
0125 val = readl_relaxed(kbd->io_base + MODE_CTL_REG);
0126 val |= MODE_CTL_START_SCAN;
0127 writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
0128
0129 return 0;
0130 }
0131
0132 static void spear_kbd_close(struct input_dev *dev)
0133 {
0134 struct spear_kbd *kbd = input_get_drvdata(dev);
0135 u32 val;
0136
0137
0138 val = readl_relaxed(kbd->io_base + MODE_CTL_REG);
0139 val &= ~MODE_CTL_START_SCAN;
0140 writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
0141
0142 clk_disable(kbd->clk);
0143
0144 kbd->last_key = KEY_RESERVED;
0145 }
0146
0147 #ifdef CONFIG_OF
0148 static int spear_kbd_parse_dt(struct platform_device *pdev,
0149 struct spear_kbd *kbd)
0150 {
0151 struct device_node *np = pdev->dev.of_node;
0152 int error;
0153 u32 val, suspended_rate;
0154
0155 if (!np) {
0156 dev_err(&pdev->dev, "Missing DT data\n");
0157 return -EINVAL;
0158 }
0159
0160 if (of_property_read_bool(np, "autorepeat"))
0161 kbd->rep = true;
0162
0163 if (of_property_read_u32(np, "suspended_rate", &suspended_rate))
0164 kbd->suspended_rate = suspended_rate;
0165
0166 error = of_property_read_u32(np, "st,mode", &val);
0167 if (error) {
0168 dev_err(&pdev->dev, "DT: Invalid or missing mode\n");
0169 return error;
0170 }
0171
0172 kbd->mode = val;
0173 return 0;
0174 }
0175 #else
0176 static inline int spear_kbd_parse_dt(struct platform_device *pdev,
0177 struct spear_kbd *kbd)
0178 {
0179 return -ENOSYS;
0180 }
0181 #endif
0182
0183 static int spear_kbd_probe(struct platform_device *pdev)
0184 {
0185 struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev);
0186 const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL;
0187 struct spear_kbd *kbd;
0188 struct input_dev *input_dev;
0189 struct resource *res;
0190 int irq;
0191 int error;
0192
0193 irq = platform_get_irq(pdev, 0);
0194 if (irq < 0)
0195 return irq;
0196
0197 kbd = devm_kzalloc(&pdev->dev, sizeof(*kbd), GFP_KERNEL);
0198 if (!kbd) {
0199 dev_err(&pdev->dev, "not enough memory for driver data\n");
0200 return -ENOMEM;
0201 }
0202
0203 input_dev = devm_input_allocate_device(&pdev->dev);
0204 if (!input_dev) {
0205 dev_err(&pdev->dev, "unable to allocate input device\n");
0206 return -ENOMEM;
0207 }
0208
0209 kbd->input = input_dev;
0210 kbd->irq = irq;
0211
0212 if (!pdata) {
0213 error = spear_kbd_parse_dt(pdev, kbd);
0214 if (error)
0215 return error;
0216 } else {
0217 kbd->mode = pdata->mode;
0218 kbd->rep = pdata->rep;
0219 kbd->suspended_rate = pdata->suspended_rate;
0220 }
0221
0222 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0223 kbd->io_base = devm_ioremap_resource(&pdev->dev, res);
0224 if (IS_ERR(kbd->io_base))
0225 return PTR_ERR(kbd->io_base);
0226
0227 kbd->clk = devm_clk_get(&pdev->dev, NULL);
0228 if (IS_ERR(kbd->clk))
0229 return PTR_ERR(kbd->clk);
0230
0231 input_dev->name = "Spear Keyboard";
0232 input_dev->phys = "keyboard/input0";
0233 input_dev->id.bustype = BUS_HOST;
0234 input_dev->id.vendor = 0x0001;
0235 input_dev->id.product = 0x0001;
0236 input_dev->id.version = 0x0100;
0237 input_dev->open = spear_kbd_open;
0238 input_dev->close = spear_kbd_close;
0239
0240 error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS,
0241 kbd->keycodes, input_dev);
0242 if (error) {
0243 dev_err(&pdev->dev, "Failed to build keymap\n");
0244 return error;
0245 }
0246
0247 if (kbd->rep)
0248 __set_bit(EV_REP, input_dev->evbit);
0249 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
0250
0251 input_set_drvdata(input_dev, kbd);
0252
0253 error = devm_request_irq(&pdev->dev, irq, spear_kbd_interrupt, 0,
0254 "keyboard", kbd);
0255 if (error) {
0256 dev_err(&pdev->dev, "request_irq failed\n");
0257 return error;
0258 }
0259
0260 error = clk_prepare(kbd->clk);
0261 if (error)
0262 return error;
0263
0264 error = input_register_device(input_dev);
0265 if (error) {
0266 dev_err(&pdev->dev, "Unable to register keyboard device\n");
0267 clk_unprepare(kbd->clk);
0268 return error;
0269 }
0270
0271 device_init_wakeup(&pdev->dev, 1);
0272 platform_set_drvdata(pdev, kbd);
0273
0274 return 0;
0275 }
0276
0277 static int spear_kbd_remove(struct platform_device *pdev)
0278 {
0279 struct spear_kbd *kbd = platform_get_drvdata(pdev);
0280
0281 input_unregister_device(kbd->input);
0282 clk_unprepare(kbd->clk);
0283
0284 return 0;
0285 }
0286
0287 static int __maybe_unused spear_kbd_suspend(struct device *dev)
0288 {
0289 struct platform_device *pdev = to_platform_device(dev);
0290 struct spear_kbd *kbd = platform_get_drvdata(pdev);
0291 struct input_dev *input_dev = kbd->input;
0292 unsigned int rate = 0, mode_ctl_reg, val;
0293
0294 mutex_lock(&input_dev->mutex);
0295
0296
0297 clk_enable(kbd->clk);
0298
0299 mode_ctl_reg = readl_relaxed(kbd->io_base + MODE_CTL_REG);
0300
0301 if (device_may_wakeup(&pdev->dev)) {
0302 if (!enable_irq_wake(kbd->irq))
0303 kbd->irq_wake_enabled = true;
0304
0305
0306
0307
0308
0309 if (kbd->suspended_rate)
0310 rate = kbd->suspended_rate / 1000000 - 1;
0311 else
0312 rate = clk_get_rate(kbd->clk) / 1000000 - 1;
0313
0314 val = mode_ctl_reg &
0315 ~(MODE_CTL_PCLK_FREQ_MSK << MODE_CTL_PCLK_FREQ_SHIFT);
0316 val |= (rate & MODE_CTL_PCLK_FREQ_MSK)
0317 << MODE_CTL_PCLK_FREQ_SHIFT;
0318 writel_relaxed(val, kbd->io_base + MODE_CTL_REG);
0319
0320 } else {
0321 if (input_device_enabled(input_dev)) {
0322 writel_relaxed(mode_ctl_reg & ~MODE_CTL_START_SCAN,
0323 kbd->io_base + MODE_CTL_REG);
0324 clk_disable(kbd->clk);
0325 }
0326 }
0327
0328
0329 if (input_device_enabled(input_dev))
0330 kbd->mode_ctl_reg = mode_ctl_reg;
0331
0332
0333 clk_disable(kbd->clk);
0334
0335 mutex_unlock(&input_dev->mutex);
0336
0337 return 0;
0338 }
0339
0340 static int __maybe_unused spear_kbd_resume(struct device *dev)
0341 {
0342 struct platform_device *pdev = to_platform_device(dev);
0343 struct spear_kbd *kbd = platform_get_drvdata(pdev);
0344 struct input_dev *input_dev = kbd->input;
0345
0346 mutex_lock(&input_dev->mutex);
0347
0348 if (device_may_wakeup(&pdev->dev)) {
0349 if (kbd->irq_wake_enabled) {
0350 kbd->irq_wake_enabled = false;
0351 disable_irq_wake(kbd->irq);
0352 }
0353 } else {
0354 if (input_device_enabled(input_dev))
0355 clk_enable(kbd->clk);
0356 }
0357
0358
0359 if (input_device_enabled(input_dev))
0360 writel_relaxed(kbd->mode_ctl_reg, kbd->io_base + MODE_CTL_REG);
0361
0362 mutex_unlock(&input_dev->mutex);
0363
0364 return 0;
0365 }
0366
0367 static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume);
0368
0369 #ifdef CONFIG_OF
0370 static const struct of_device_id spear_kbd_id_table[] = {
0371 { .compatible = "st,spear300-kbd" },
0372 {}
0373 };
0374 MODULE_DEVICE_TABLE(of, spear_kbd_id_table);
0375 #endif
0376
0377 static struct platform_driver spear_kbd_driver = {
0378 .probe = spear_kbd_probe,
0379 .remove = spear_kbd_remove,
0380 .driver = {
0381 .name = "keyboard",
0382 .pm = &spear_kbd_pm_ops,
0383 .of_match_table = of_match_ptr(spear_kbd_id_table),
0384 },
0385 };
0386 module_platform_driver(spear_kbd_driver);
0387
0388 MODULE_AUTHOR("Rajeev Kumar");
0389 MODULE_DESCRIPTION("SPEAr Keyboard Driver");
0390 MODULE_LICENSE("GPL");