Loading Documentation/devicetree/bindings/input/pxa27x-keypad.txt 0 → 100644 +60 −0 Original line number Diff line number Diff line * Marvell PXA Keypad controller Required Properties - compatible : should be "marvell,pxa27x-keypad" - reg : Address and length of the register set for the device - interrupts : The interrupt for the keypad controller - marvell,debounce-interval : How long time the key will be recognized when it is pressed. It is a u32 value, and bit[31:16] is debounce interval for direct key and bit[15:0] is debounce interval for matrix key. The value is in binary number of 2ms Optional Properties For Matrix Keyes Please refer to matrix-keymap.txt Optional Properties for Direct Keyes - marvell,direct-key-count : How many direct keyes are used. - marvell,direct-key-mask : The mask indicates which keyes are used. If bit[X] of the mask is set, the direct key X is used. - marvell,direct-key-low-active : Direct key status register tells the level of pins that connects to the direct keyes. When this property is set, it means that when the pin level is low, the key is pressed(active). - marvell,direct-key-map : It is a u16 array. Each item indicates the linux key-code for the direct key. Optional Properties For Rotary - marvell,rotary0 : It is a u32 value. Bit[31:16] is the linux key-code for rotary up. Bit[15:0] is the linux key-code for rotary down. It is for rotary 0. - marvell,rotary1 : Same as marvell,rotary0. It is for rotary 1. - marvell,rotary-rel-key : When rotary is used for relative axes in the device, the value indicates the key-code for relative axes measurement in the device. It is a u32 value. Bit[31:16] is for rotary 1, and Bit[15:0] is for rotary 0. Examples: keypad: keypad@d4012000 { keypad,num-rows = <3>; keypad,num-columns = <5>; linux,keymap = <0x0000000e /* KEY_BACKSPACE */ 0x0001006b /* KEY_END */ 0x00020061 /* KEY_RIGHTCTRL */ 0x0003000b /* KEY_0 */ 0x00040002 /* KEY_1 */ 0x0100008b /* KEY_MENU */ 0x01010066 /* KEY_HOME */ 0x010200e7 /* KEY_SEND */ 0x01030009 /* KEY_8 */ 0x0104000a /* KEY_9 */ 0x02000160 /* KEY_OK */ 0x02010003 /* KEY_2 */ 0x02020004 /* KEY_3 */ 0x02030005 /* KEY_4 */ 0x02040006>; /* KEY_5 */ marvell,rotary0 = <0x006c0067>; /* KEY_UP & KEY_DOWN */ marvell,direct-key-count = <1>; marvell,direct-key-map = <0x001c>; marvell,debounce-interval = <0x001e001e>; }; drivers/input/keyboard/pxa27x_keypad.c +242 −4 Original line number Diff line number Diff line Loading @@ -118,6 +118,229 @@ struct pxa27x_keypad { unsigned int direct_key_mask; }; #ifdef CONFIG_OF static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct pxa27x_keypad_platform_data *pdata = keypad->pdata; u32 rows, cols; int error; error = matrix_keypad_parse_of_params(dev, &rows, &cols); if (error) return error; if (rows > MAX_MATRIX_KEY_ROWS || cols > MAX_MATRIX_KEY_COLS) { dev_err(dev, "rows or cols exceeds maximum value\n"); return -EINVAL; } pdata->matrix_key_rows = rows; pdata->matrix_key_cols = cols; error = matrix_keypad_build_keymap(NULL, NULL, pdata->matrix_key_rows, pdata->matrix_key_cols, keypad->keycodes, input_dev); if (error) return error; return 0; } static int pxa27x_keypad_direct_key_parse_dt(struct pxa27x_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct pxa27x_keypad_platform_data *pdata = keypad->pdata; struct device_node *np = dev->of_node; const __be16 *prop; unsigned short code; unsigned int proplen, size; int i; int error; error = of_property_read_u32(np, "marvell,direct-key-count", &pdata->direct_key_num); if (error) { /* * If do not have marvel,direct-key-count defined, * it means direct key is not supported. */ return error == -EINVAL ? 0 : error; } error = of_property_read_u32(np, "marvell,direct-key-mask", &pdata->direct_key_mask); if (error) { if (error != -EINVAL) return error; /* * If marvell,direct-key-mask is not defined, driver will use * default value. Default value is set when configure the keypad. */ pdata->direct_key_mask = 0; } pdata->direct_key_low_active = of_property_read_bool(np, "marvell,direct-key-low-active"); prop = of_get_property(np, "marvell,direct-key-map", &proplen); if (!prop) return -EINVAL; if (proplen % sizeof(u16)) return -EINVAL; size = proplen / sizeof(u16); /* Only MAX_DIRECT_KEY_NUM is accepted.*/ if (size > MAX_DIRECT_KEY_NUM) return -EINVAL; for (i = 0; i < size; i++) { code = be16_to_cpup(prop + i); keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = code; __set_bit(code, input_dev->keybit); } return 0; } static int pxa27x_keypad_rotary_parse_dt(struct pxa27x_keypad *keypad) { const __be32 *prop; int i, relkey_ret; unsigned int code, proplen; const char *rotaryname[2] = { "marvell,rotary0", "marvell,rotary1"}; const char relkeyname[] = {"marvell,rotary-rel-key"}; struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct pxa27x_keypad_platform_data *pdata = keypad->pdata; struct device_node *np = dev->of_node; relkey_ret = of_property_read_u32(np, relkeyname, &code); /* if can read correct rotary key-code, we do not need this. */ if (relkey_ret == 0) { unsigned short relcode; /* rotary0 taks lower half, rotary1 taks upper half. */ relcode = code & 0xffff; pdata->rotary0_rel_code = (code & 0xffff); __set_bit(relcode, input_dev->relbit); relcode = code >> 16; pdata->rotary1_rel_code = relcode; __set_bit(relcode, input_dev->relbit); } for (i = 0; i < 2; i++) { prop = of_get_property(np, rotaryname[i], &proplen); /* * If the prop is not set, it means keypad does not need * initialize the rotaryX. */ if (!prop) continue; code = be32_to_cpup(prop); /* * Not all up/down key code are valid. * Now we depends on direct-rel-code. */ if ((!(code & 0xffff) || !(code >> 16)) && relkey_ret) { return relkey_ret; } else { unsigned int n = MAX_MATRIX_KEY_NUM + (i << 1); unsigned short keycode; keycode = code & 0xffff; keypad->keycodes[n] = keycode; __set_bit(keycode, input_dev->keybit); keycode = code >> 16; keypad->keycodes[n + 1] = keycode; __set_bit(keycode, input_dev->keybit); if (i == 0) pdata->rotary0_rel_code = -1; else pdata->rotary1_rel_code = -1; } if (i == 0) pdata->enable_rotary0 = 1; else pdata->enable_rotary1 = 1; } keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; return 0; } static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct device_node *np = dev->of_node; int error; keypad->pdata = devm_kzalloc(dev, sizeof(*keypad->pdata), GFP_KERNEL); if (!keypad->pdata) { dev_err(dev, "failed to allocate memory for pdata\n"); return -ENOMEM; } error = pxa27x_keypad_matrix_key_parse_dt(keypad); if (error) { dev_err(dev, "failed to parse matrix key\n"); return error; } error = pxa27x_keypad_direct_key_parse_dt(keypad); if (error) { dev_err(dev, "failed to parse direct key\n"); return error; } error = pxa27x_keypad_rotary_parse_dt(keypad); if (error) { dev_err(dev, "failed to parse rotary key\n"); return error; } error = of_property_read_u32(np, "marvell,debounce-interval", &keypad->pdata->debounce_interval); if (error) { dev_err(dev, "failed to parse debpunce-interval\n"); return error; } /* * The keycodes may not only includes matrix key but also the direct * key or rotary key. */ input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); return 0; } #else static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad) { dev_info(keypad->input_dev->dev.parent, "missing platform data\n"); return -EINVAL; } #endif static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) { struct pxa27x_keypad_platform_data *pdata = keypad->pdata; Loading Loading @@ -492,15 +715,15 @@ static const struct dev_pm_ops pxa27x_keypad_pm_ops = { static int pxa27x_keypad_probe(struct platform_device *pdev) { struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; struct pxa27x_keypad *keypad; struct input_dev *input_dev; struct resource *res; int irq, error; if (pdata == NULL) { dev_err(&pdev->dev, "no platform data defined\n"); /* Driver need build keycode from device tree or pdata */ if (!np && !pdata) return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { Loading Loading @@ -562,12 +785,18 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); input_set_capability(input_dev, EV_MSC, MSC_SCAN); if (pdata) error = pxa27x_keypad_build_keycode(keypad); else error = pxa27x_keypad_build_keycode_from_dt(keypad); if (error) { dev_err(&pdev->dev, "failed to build keycode\n"); goto failed_put_clk; } /* If device tree is supported, pdata will be allocated. */ pdata = keypad->pdata; if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) || (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) { input_dev->evbit[0] |= BIT_MASK(EV_REL); Loading Loading @@ -628,11 +857,20 @@ static int pxa27x_keypad_remove(struct platform_device *pdev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:pxa27x-keypad"); #ifdef CONFIG_OF static const struct of_device_id pxa27x_keypad_dt_match[] = { { .compatible = "marvell,pxa27x-keypad" }, {}, }; MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match); #endif static struct platform_driver pxa27x_keypad_driver = { .probe = pxa27x_keypad_probe, .remove = pxa27x_keypad_remove, .driver = { .name = "pxa27x-keypad", .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &pxa27x_keypad_pm_ops, Loading Loading
Documentation/devicetree/bindings/input/pxa27x-keypad.txt 0 → 100644 +60 −0 Original line number Diff line number Diff line * Marvell PXA Keypad controller Required Properties - compatible : should be "marvell,pxa27x-keypad" - reg : Address and length of the register set for the device - interrupts : The interrupt for the keypad controller - marvell,debounce-interval : How long time the key will be recognized when it is pressed. It is a u32 value, and bit[31:16] is debounce interval for direct key and bit[15:0] is debounce interval for matrix key. The value is in binary number of 2ms Optional Properties For Matrix Keyes Please refer to matrix-keymap.txt Optional Properties for Direct Keyes - marvell,direct-key-count : How many direct keyes are used. - marvell,direct-key-mask : The mask indicates which keyes are used. If bit[X] of the mask is set, the direct key X is used. - marvell,direct-key-low-active : Direct key status register tells the level of pins that connects to the direct keyes. When this property is set, it means that when the pin level is low, the key is pressed(active). - marvell,direct-key-map : It is a u16 array. Each item indicates the linux key-code for the direct key. Optional Properties For Rotary - marvell,rotary0 : It is a u32 value. Bit[31:16] is the linux key-code for rotary up. Bit[15:0] is the linux key-code for rotary down. It is for rotary 0. - marvell,rotary1 : Same as marvell,rotary0. It is for rotary 1. - marvell,rotary-rel-key : When rotary is used for relative axes in the device, the value indicates the key-code for relative axes measurement in the device. It is a u32 value. Bit[31:16] is for rotary 1, and Bit[15:0] is for rotary 0. Examples: keypad: keypad@d4012000 { keypad,num-rows = <3>; keypad,num-columns = <5>; linux,keymap = <0x0000000e /* KEY_BACKSPACE */ 0x0001006b /* KEY_END */ 0x00020061 /* KEY_RIGHTCTRL */ 0x0003000b /* KEY_0 */ 0x00040002 /* KEY_1 */ 0x0100008b /* KEY_MENU */ 0x01010066 /* KEY_HOME */ 0x010200e7 /* KEY_SEND */ 0x01030009 /* KEY_8 */ 0x0104000a /* KEY_9 */ 0x02000160 /* KEY_OK */ 0x02010003 /* KEY_2 */ 0x02020004 /* KEY_3 */ 0x02030005 /* KEY_4 */ 0x02040006>; /* KEY_5 */ marvell,rotary0 = <0x006c0067>; /* KEY_UP & KEY_DOWN */ marvell,direct-key-count = <1>; marvell,direct-key-map = <0x001c>; marvell,debounce-interval = <0x001e001e>; };
drivers/input/keyboard/pxa27x_keypad.c +242 −4 Original line number Diff line number Diff line Loading @@ -118,6 +118,229 @@ struct pxa27x_keypad { unsigned int direct_key_mask; }; #ifdef CONFIG_OF static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct pxa27x_keypad_platform_data *pdata = keypad->pdata; u32 rows, cols; int error; error = matrix_keypad_parse_of_params(dev, &rows, &cols); if (error) return error; if (rows > MAX_MATRIX_KEY_ROWS || cols > MAX_MATRIX_KEY_COLS) { dev_err(dev, "rows or cols exceeds maximum value\n"); return -EINVAL; } pdata->matrix_key_rows = rows; pdata->matrix_key_cols = cols; error = matrix_keypad_build_keymap(NULL, NULL, pdata->matrix_key_rows, pdata->matrix_key_cols, keypad->keycodes, input_dev); if (error) return error; return 0; } static int pxa27x_keypad_direct_key_parse_dt(struct pxa27x_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct pxa27x_keypad_platform_data *pdata = keypad->pdata; struct device_node *np = dev->of_node; const __be16 *prop; unsigned short code; unsigned int proplen, size; int i; int error; error = of_property_read_u32(np, "marvell,direct-key-count", &pdata->direct_key_num); if (error) { /* * If do not have marvel,direct-key-count defined, * it means direct key is not supported. */ return error == -EINVAL ? 0 : error; } error = of_property_read_u32(np, "marvell,direct-key-mask", &pdata->direct_key_mask); if (error) { if (error != -EINVAL) return error; /* * If marvell,direct-key-mask is not defined, driver will use * default value. Default value is set when configure the keypad. */ pdata->direct_key_mask = 0; } pdata->direct_key_low_active = of_property_read_bool(np, "marvell,direct-key-low-active"); prop = of_get_property(np, "marvell,direct-key-map", &proplen); if (!prop) return -EINVAL; if (proplen % sizeof(u16)) return -EINVAL; size = proplen / sizeof(u16); /* Only MAX_DIRECT_KEY_NUM is accepted.*/ if (size > MAX_DIRECT_KEY_NUM) return -EINVAL; for (i = 0; i < size; i++) { code = be16_to_cpup(prop + i); keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = code; __set_bit(code, input_dev->keybit); } return 0; } static int pxa27x_keypad_rotary_parse_dt(struct pxa27x_keypad *keypad) { const __be32 *prop; int i, relkey_ret; unsigned int code, proplen; const char *rotaryname[2] = { "marvell,rotary0", "marvell,rotary1"}; const char relkeyname[] = {"marvell,rotary-rel-key"}; struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct pxa27x_keypad_platform_data *pdata = keypad->pdata; struct device_node *np = dev->of_node; relkey_ret = of_property_read_u32(np, relkeyname, &code); /* if can read correct rotary key-code, we do not need this. */ if (relkey_ret == 0) { unsigned short relcode; /* rotary0 taks lower half, rotary1 taks upper half. */ relcode = code & 0xffff; pdata->rotary0_rel_code = (code & 0xffff); __set_bit(relcode, input_dev->relbit); relcode = code >> 16; pdata->rotary1_rel_code = relcode; __set_bit(relcode, input_dev->relbit); } for (i = 0; i < 2; i++) { prop = of_get_property(np, rotaryname[i], &proplen); /* * If the prop is not set, it means keypad does not need * initialize the rotaryX. */ if (!prop) continue; code = be32_to_cpup(prop); /* * Not all up/down key code are valid. * Now we depends on direct-rel-code. */ if ((!(code & 0xffff) || !(code >> 16)) && relkey_ret) { return relkey_ret; } else { unsigned int n = MAX_MATRIX_KEY_NUM + (i << 1); unsigned short keycode; keycode = code & 0xffff; keypad->keycodes[n] = keycode; __set_bit(keycode, input_dev->keybit); keycode = code >> 16; keypad->keycodes[n + 1] = keycode; __set_bit(keycode, input_dev->keybit); if (i == 0) pdata->rotary0_rel_code = -1; else pdata->rotary1_rel_code = -1; } if (i == 0) pdata->enable_rotary0 = 1; else pdata->enable_rotary1 = 1; } keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; return 0; } static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; struct device_node *np = dev->of_node; int error; keypad->pdata = devm_kzalloc(dev, sizeof(*keypad->pdata), GFP_KERNEL); if (!keypad->pdata) { dev_err(dev, "failed to allocate memory for pdata\n"); return -ENOMEM; } error = pxa27x_keypad_matrix_key_parse_dt(keypad); if (error) { dev_err(dev, "failed to parse matrix key\n"); return error; } error = pxa27x_keypad_direct_key_parse_dt(keypad); if (error) { dev_err(dev, "failed to parse direct key\n"); return error; } error = pxa27x_keypad_rotary_parse_dt(keypad); if (error) { dev_err(dev, "failed to parse rotary key\n"); return error; } error = of_property_read_u32(np, "marvell,debounce-interval", &keypad->pdata->debounce_interval); if (error) { dev_err(dev, "failed to parse debpunce-interval\n"); return error; } /* * The keycodes may not only includes matrix key but also the direct * key or rotary key. */ input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); return 0; } #else static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad) { dev_info(keypad->input_dev->dev.parent, "missing platform data\n"); return -EINVAL; } #endif static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) { struct pxa27x_keypad_platform_data *pdata = keypad->pdata; Loading Loading @@ -492,15 +715,15 @@ static const struct dev_pm_ops pxa27x_keypad_pm_ops = { static int pxa27x_keypad_probe(struct platform_device *pdev) { struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; struct pxa27x_keypad *keypad; struct input_dev *input_dev; struct resource *res; int irq, error; if (pdata == NULL) { dev_err(&pdev->dev, "no platform data defined\n"); /* Driver need build keycode from device tree or pdata */ if (!np && !pdata) return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { Loading Loading @@ -562,12 +785,18 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); input_set_capability(input_dev, EV_MSC, MSC_SCAN); if (pdata) error = pxa27x_keypad_build_keycode(keypad); else error = pxa27x_keypad_build_keycode_from_dt(keypad); if (error) { dev_err(&pdev->dev, "failed to build keycode\n"); goto failed_put_clk; } /* If device tree is supported, pdata will be allocated. */ pdata = keypad->pdata; if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) || (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) { input_dev->evbit[0] |= BIT_MASK(EV_REL); Loading Loading @@ -628,11 +857,20 @@ static int pxa27x_keypad_remove(struct platform_device *pdev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:pxa27x-keypad"); #ifdef CONFIG_OF static const struct of_device_id pxa27x_keypad_dt_match[] = { { .compatible = "marvell,pxa27x-keypad" }, {}, }; MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match); #endif static struct platform_driver pxa27x_keypad_driver = { .probe = pxa27x_keypad_probe, .remove = pxa27x_keypad_remove, .driver = { .name = "pxa27x-keypad", .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &pxa27x_keypad_pm_ops, Loading