0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/slab.h>
0009 #include <linux/input.h>
0010 #include <linux/input/sparse-keymap.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/interrupt.h>
0013
0014 #include <linux/mfd/dm355evm_msp.h>
0015 #include <linux/module.h>
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 struct dm355evm_keys {
0029 struct input_dev *input;
0030 struct device *dev;
0031 };
0032
0033
0034 static const struct key_entry dm355evm_keys[] = {
0035
0036
0037
0038
0039
0040
0041
0042
0043 { KE_KEY, 0x00d8, { KEY_OK } },
0044 { KE_KEY, 0x00b8, { KEY_UP } },
0045 { KE_KEY, 0x00e8, { KEY_DOWN } },
0046 { KE_KEY, 0x0078, { KEY_LEFT } },
0047 { KE_KEY, 0x00f0, { KEY_RIGHT } },
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 { KE_KEY, 0x300c, { KEY_POWER } },
0062 { KE_KEY, 0x3000, { KEY_NUMERIC_0 } },
0063 { KE_KEY, 0x3001, { KEY_NUMERIC_1 } },
0064 { KE_KEY, 0x3002, { KEY_NUMERIC_2 } },
0065 { KE_KEY, 0x3003, { KEY_NUMERIC_3 } },
0066 { KE_KEY, 0x3004, { KEY_NUMERIC_4 } },
0067 { KE_KEY, 0x3005, { KEY_NUMERIC_5 } },
0068 { KE_KEY, 0x3006, { KEY_NUMERIC_6 } },
0069 { KE_KEY, 0x3007, { KEY_NUMERIC_7 } },
0070 { KE_KEY, 0x3008, { KEY_NUMERIC_8 } },
0071 { KE_KEY, 0x3009, { KEY_NUMERIC_9 } },
0072 { KE_KEY, 0x3022, { KEY_ENTER } },
0073 { KE_KEY, 0x30ec, { KEY_MODE } },
0074 { KE_KEY, 0x300f, { KEY_SELECT } },
0075 { KE_KEY, 0x3020, { KEY_CHANNELUP } },
0076 { KE_KEY, 0x302e, { KEY_MENU } },
0077 { KE_KEY, 0x3011, { KEY_VOLUMEDOWN } },
0078 { KE_KEY, 0x300d, { KEY_MUTE } },
0079 { KE_KEY, 0x3010, { KEY_VOLUMEUP } },
0080 { KE_KEY, 0x301e, { KEY_SUBTITLE } },
0081 { KE_KEY, 0x3021, { KEY_CHANNELDOWN } },
0082 { KE_KEY, 0x3022, { KEY_PREVIOUS } },
0083 { KE_KEY, 0x3026, { KEY_SLEEP } },
0084 { KE_KEY, 0x3172, { KEY_REWIND } },
0085 { KE_KEY, 0x3175, { KEY_PLAY } },
0086 { KE_KEY, 0x3174, { KEY_FASTFORWARD } },
0087 { KE_KEY, 0x3177, { KEY_RECORD } },
0088 { KE_KEY, 0x3176, { KEY_STOP } },
0089 { KE_KEY, 0x3169, { KEY_PAUSE } },
0090 };
0091
0092
0093
0094
0095
0096
0097
0098
0099 static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
0100 {
0101 static u16 last_event;
0102 struct dm355evm_keys *keys = _keys;
0103 const struct key_entry *ke;
0104 unsigned int keycode;
0105 int status;
0106 u16 event;
0107
0108
0109
0110
0111
0112 for (;;) {
0113 status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH);
0114 if (status < 0) {
0115 dev_dbg(keys->dev, "input high err %d\n",
0116 status);
0117 break;
0118 }
0119 event = status << 8;
0120
0121 status = dm355evm_msp_read(DM355EVM_MSP_INPUT_LOW);
0122 if (status < 0) {
0123 dev_dbg(keys->dev, "input low err %d\n",
0124 status);
0125 break;
0126 }
0127 event |= status;
0128 if (event == 0xdead)
0129 break;
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 if (event == last_event) {
0143 last_event = 0;
0144 continue;
0145 }
0146 last_event = event;
0147
0148
0149 event &= ~0x0800;
0150
0151
0152 ke = sparse_keymap_entry_from_scancode(keys->input, event);
0153 keycode = ke ? ke->keycode : KEY_UNKNOWN;
0154 dev_dbg(keys->dev,
0155 "input event 0x%04x--> keycode %d\n",
0156 event, keycode);
0157
0158
0159 input_report_key(keys->input, keycode, 1);
0160 input_sync(keys->input);
0161 input_report_key(keys->input, keycode, 0);
0162 input_sync(keys->input);
0163 }
0164
0165 return IRQ_HANDLED;
0166 }
0167
0168
0169
0170 static int dm355evm_keys_probe(struct platform_device *pdev)
0171 {
0172 struct dm355evm_keys *keys;
0173 struct input_dev *input;
0174 int irq;
0175 int error;
0176
0177 keys = devm_kzalloc(&pdev->dev, sizeof (*keys), GFP_KERNEL);
0178 if (!keys)
0179 return -ENOMEM;
0180
0181 input = devm_input_allocate_device(&pdev->dev);
0182 if (!input)
0183 return -ENOMEM;
0184
0185 keys->dev = &pdev->dev;
0186 keys->input = input;
0187
0188 input->name = "DM355 EVM Controls";
0189 input->phys = "dm355evm/input0";
0190
0191 input->id.bustype = BUS_I2C;
0192 input->id.product = 0x0355;
0193 input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
0194
0195 error = sparse_keymap_setup(input, dm355evm_keys, NULL);
0196 if (error)
0197 return error;
0198
0199
0200
0201
0202 irq = platform_get_irq(pdev, 0);
0203 if (irq < 0)
0204 return irq;
0205
0206 error = devm_request_threaded_irq(&pdev->dev, irq,
0207 NULL, dm355evm_keys_irq,
0208 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0209 dev_name(&pdev->dev), keys);
0210 if (error)
0211 return error;
0212
0213
0214 error = input_register_device(input);
0215 if (error)
0216 return error;
0217
0218 return 0;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 static struct platform_driver dm355evm_keys_driver = {
0231 .probe = dm355evm_keys_probe,
0232 .driver = {
0233 .name = "dm355evm_keys",
0234 },
0235 };
0236 module_platform_driver(dm355evm_keys_driver);
0237
0238 MODULE_LICENSE("GPL");