Exemple #1
0
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;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
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));
}
Exemple #5
0
/*
 * 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;
}
Exemple #6
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;
}
Exemple #7
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;
}