static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad, struct pxa27x_keypad_platform_data *pdata) { struct input_dev *input_dev = keypad->input_dev; struct device *dev = input_dev->dev.parent; 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 omap4_keypad_parse_dt(struct device *dev, struct omap4_keypad *keypad_data) { struct device_node *np = dev->of_node; int err; err = matrix_keypad_parse_of_params(dev, &keypad_data->rows, &keypad_data->cols); if (err) return err; if (of_get_property(np, "linux,input-no-autorepeat", NULL)) keypad_data->no_autorepeat = true; return 0; }
static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data) { struct device *dev = keypad_data->input_dev->dev.parent; struct device_node *np = dev->of_node; int error; error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows, &keypad_data->n_cols); if (error) { dev_err(dev, "failed to parse keypad params\n"); return error; } of_property_read_u32(np, "st,debounce-us", &keypad_data->debounce_us); dev_dbg(dev, "n_rows=%d n_col=%d debounce=%d\n", keypad_data->n_rows, keypad_data->n_cols, keypad_data->debounce_us); return 0; }
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) { int ret; struct cros_ec_command msg = { .version = 0, .command = EC_CMD_MKBP_STATE, .outdata = NULL, .outsize = 0, .indata = kb_state, .insize = ckdev->cols, }; ret = cros_ec_cmd_xfer_status(ckdev->ec, &msg); return ret; } static irqreturn_t cros_ec_keyb_irq(int irq, void *data) { struct cros_ec_keyb *ckdev = data; struct cros_ec_device *ec = ckdev->ec; int ret; uint8_t kb_state[ckdev->cols]; if (device_may_wakeup(ec->dev)) pm_wakeup_event(ec->dev, 0); ret = cros_ec_keyb_get_state(ckdev, kb_state); if (ret >= 0) cros_ec_keyb_process(ckdev, kb_state, ret); else dev_err(ec->dev, "failed to get keyboard state: %d\n", ret); return IRQ_HANDLED; } static int cros_ec_keyb_open(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); struct cros_ec_device *ec = ckdev->ec; return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "cros_ec_keyb", ckdev); } static void cros_ec_keyb_close(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); struct cros_ec_device *ec = ckdev->ec; free_irq(ec->irq, ckdev); } static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct device *dev = ec->dev; struct cros_ec_keyb *ckdev; struct input_dev *idev; struct device_node *np; int err; np = pdev->dev.of_node; if (!np) return -ENODEV; ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, &ckdev->cols); if (err) return err; ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->old_kb_state) return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; if (!ec->irq) { dev_err(dev, "no EC IRQ specified\n"); return -EINVAL; } ckdev->ec = ec; ckdev->dev = dev; dev_set_drvdata(&pdev->dev, ckdev); idev->name = CROS_EC_DEV_NAME; idev->phys = ec->phys_name; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = &pdev->dev; idev->open = cros_ec_keyb_open; idev->close = cros_ec_keyb_close; ckdev->ghost_filter = of_property_read_bool(np, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, NULL, idev); if (err) { dev_err(dev, "cannot build key matrix\n"); return err; } ckdev->row_shift = get_count_order(ckdev->cols); input_set_capability(idev, EV_MSC, MSC_SCAN); input_set_drvdata(idev, ckdev); ckdev->idev = idev; err = input_register_device(ckdev->idev); if (err) { dev_err(dev, "cannot register input device\n"); return err; } return 0; } #ifdef CONFIG_PM_SLEEP /* Clear any keys in the buffer */ static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) { uint8_t old_state[ckdev->cols]; uint8_t new_state[ckdev->cols]; unsigned long duration; int i, ret; /* * Keep reading until we see that the scan state does not change. * That indicates that we are done. * * Assume that the EC keyscan buffer is at most 32 deep. */ duration = jiffies; ret = cros_ec_keyb_get_state(ckdev, new_state); for (i = 1; !ret && i < 32; i++) { memcpy(old_state, new_state, sizeof(old_state)); ret = cros_ec_keyb_get_state(ckdev, new_state); if (0 == memcmp(old_state, new_state, sizeof(old_state))) break; } duration = jiffies - duration; dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, jiffies_to_usecs(duration)); }
/* * keypad controller should be initialized in the following sequence * only, otherwise it might get into FSM stuck state. * * - Initialize keypad control parameters, like no. of rows, columns, * timing values etc., * - configure rows and column gpios pull up/down. * - set irq edge type. * - enable the keypad controller. */ static int pmic8xxx_kp_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; unsigned int rows, cols; bool repeat; bool wakeup; struct pmic8xxx_kp *kp; int rc; unsigned int ctrl_val; rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); if (rc) return rc; if (cols > PM8XXX_MAX_COLS || rows > PM8XXX_MAX_ROWS || cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } repeat = !of_property_read_bool(np, "linux,input-no-autorepeat"); wakeup = of_property_read_bool(np, "wakeup-source") || /* legacy name */ of_property_read_bool(np, "linux,keypad-wakeup"); kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; kp->regmap = dev_get_regmap(pdev->dev.parent, NULL); if (!kp->regmap) return -ENODEV; platform_set_drvdata(pdev, kp); kp->num_rows = rows; kp->num_cols = cols; kp->dev = &pdev->dev; kp->input = devm_input_allocate_device(&pdev->dev); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); return -ENOMEM; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); return kp->key_sense_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); return kp->key_stuck_irq; } kp->input->name = "PMIC8XXX keypad"; kp->input->phys = "pmic8xxx_keypad/input0"; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; rc = matrix_keypad_build_keymap(NULL, NULL, PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, kp->keycodes, kp->input); if (rc) { dev_err(&pdev->dev, "failed to build keymap\n"); return rc; } if (repeat) __set_bit(EV_REP, kp->input->evbit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp, pdev); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); return rc; } rc = devm_request_any_context_irq(&pdev->dev, kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); return rc; } rc = devm_request_any_context_irq(&pdev->dev, kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); return rc; } rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); return rc; } kp->ctrl_reg = ctrl_val; rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); return rc; } device_init_wakeup(&pdev->dev, wakeup); return 0; }
static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct device *dev = ec->dev; struct cros_ec_keyb *ckdev; struct input_dev *idev; struct device_node *np; int err; np = pdev->dev.of_node; if (!np) return -ENODEV; ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, &ckdev->cols); if (err) return err; ckdev->valid_keys = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->valid_keys) return -ENOMEM; ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->old_kb_state) return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; if (!ec->irq) { dev_err(dev, "no EC IRQ specified\n"); return -EINVAL; } ckdev->ec = ec; ckdev->dev = dev; dev_set_drvdata(&pdev->dev, ckdev); idev->name = ec->ec_name; idev->phys = ec->phys_name; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = &pdev->dev; idev->open = cros_ec_keyb_open; idev->close = cros_ec_keyb_close; ckdev->ghost_filter = of_property_read_bool(np, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, NULL, idev); if (err) { dev_err(dev, "cannot build key matrix\n"); return err; } ckdev->row_shift = get_count_order(ckdev->cols); input_set_capability(idev, EV_MSC, MSC_SCAN); input_set_drvdata(idev, ckdev); ckdev->idev = idev; cros_ec_keyb_compute_valid_keys(ckdev); err = input_register_device(ckdev->idev); if (err) { dev_err(dev, "cannot register input device\n"); return err; } return 0; }
static int tca8418_keypad_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; const struct tca8418_keypad_platform_data *pdata = dev_get_platdata(dev); struct tca8418_keypad *keypad_data; struct input_dev *input; const struct matrix_keymap_data *keymap_data = NULL; u32 rows = 0, cols = 0; bool rep = false; bool irq_is_gpio = false; int irq; int error, row_shift, max_keys; /* Copy the platform data */ if (pdata) { if (!pdata->keymap_data) { dev_err(dev, "no keymap data defined\n"); return -EINVAL; } keymap_data = pdata->keymap_data; rows = pdata->rows; cols = pdata->cols; rep = pdata->rep; irq_is_gpio = pdata->irq_is_gpio; } else { struct device_node *np = dev->of_node; int err; err = matrix_keypad_parse_of_params(dev, &rows, &cols); if (err) return err; rep = of_property_read_bool(np, "keypad,autorepeat"); } if (!rows || rows > TCA8418_MAX_ROWS) { dev_err(dev, "invalid rows\n"); return -EINVAL; } if (!cols || cols > TCA8418_MAX_COLS) { dev_err(dev, "invalid columns\n"); return -EINVAL; } /* Check i2c driver capabilities */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { dev_err(dev, "%s adapter not supported\n", dev_driver_string(&client->adapter->dev)); return -ENODEV; } row_shift = get_count_order(cols); max_keys = rows << row_shift; /* Allocate memory for keypad_data and input device */ keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL); if (!keypad_data) return -ENOMEM; keypad_data->client = client; keypad_data->row_shift = row_shift; /* Initialize the chip or fail if chip isn't present */ error = tca8418_configure(keypad_data, rows, cols); if (error < 0) return error; /* Configure input device */ input = devm_input_allocate_device(dev); if (!input) return -ENOMEM; keypad_data->input = input; input->name = client->name; input->id.bustype = BUS_I2C; input->id.vendor = 0x0001; input->id.product = 0x001; input->id.version = 0x0001; error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, NULL, input); if (error) { dev_err(dev, "Failed to build keymap\n"); return error; } if (rep) __set_bit(EV_REP, input->evbit); input_set_capability(input, EV_MSC, MSC_SCAN); input_set_drvdata(input, keypad_data); irq = client->irq; if (irq_is_gpio) irq = gpio_to_irq(irq); error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, IRQF_TRIGGER_FALLING | IRQF_SHARED | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", client->irq, error); return error; } error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); return error; } return 0; }