
Hi Bin,
On 15 September 2015 at 00:11, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Wed, Sep 9, 2015 at 12:32 PM, Simon Glass sjg@chromium.org wrote:
Add a uclass for keyboard input, mirroring the existing stdio methods. This is enabled by a new CONFIG_DM_KEYBOARD option.
Signed-off-by: Simon Glass sjg@chromium.org
common/usb_kbd.c | 6 --- drivers/input/Kconfig | 9 +++++ drivers/input/Makefile | 2 + drivers/input/keyboard-uclass.c | 84 +++++++++++++++++++++++++++++++++++++++++ include/keyboard.h | 78 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 drivers/input/keyboard-uclass.c
diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 8037ebf..05668fc 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -648,12 +648,6 @@ U_BOOT_DRIVER(usb_kbd) = { .probe = usb_kbd_probe, };
-/* TODO(sjg@chromium.org): Move this into a common location */ -UCLASS_DRIVER(keyboard) = {
.id = UCLASS_KEYBOARD,
.name = "keyboard",
-};
static const struct usb_device_id kbd_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index bb00de7..447c4c3 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -1,3 +1,12 @@ +config DM_KEYBOARD
bool "Enable driver model keyboard support"
depends on DM
help
This adds a uclass for keyboards and implements keyboard support
using driver model. The API is implemented by keyboard.h and
includes methods to start/stop the device, check for available
input and update LEDs if the keyboard has them.
config CROS_EC_KEYB bool "Enable Chrome OS EC keyboard support" help diff --git a/drivers/input/Makefile b/drivers/input/Makefile index b1161c5..9388dfe 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -5,6 +5,8 @@ # SPDX-License-Identifier: GPL-2.0+ #
+obj-$(CONFIG_DM_KEYBOARD) += keyboard-uclass.o
obj-$(CONFIG_I8042_KBD) += i8042.o obj-$(CONFIG_TEGRA_KEYBOARD) += tegra-kbc.o obj-$(CONFIG_TWL4030_INPUT) += twl4030.o diff --git a/drivers/input/keyboard-uclass.c b/drivers/input/keyboard-uclass.c new file mode 100644 index 0000000..1c564dc --- /dev/null +++ b/drivers/input/keyboard-uclass.c @@ -0,0 +1,84 @@ +/*
- Copyright (c) 2015 Google, Inc
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <dm.h> +#include <keyboard.h>
+static int keyboard_start(struct stdio_dev *sdev) +{
struct udevice *dev = sdev->priv;
struct keyboard_ops *ops = keyboard_get_ops(dev);
if (ops->start)
return ops->start(dev);
return 0;
Should we return -ENOSYS here?
No, several keyboards don't need to do do anything here.
+}
+static int keyboard_stop(struct stdio_dev *sdev) +{
struct udevice *dev = sdev->priv;
struct keyboard_ops *ops = keyboard_get_ops(dev);
if (ops->stop)
return ops->stop(dev);
return 0;
Ditto.
+}
+static int keyboard_tstc(struct stdio_dev *sdev) +{
struct udevice *dev = sdev->priv;
struct keyboard_priv *priv = dev_get_uclass_priv(dev);
/* Just get input to do this for us if we can */
if (priv->input.dev)
return input_tstc(&priv->input);
else if (op->tstc) return ops->tstc(dev);
?
Well nothing uses it yet, and I'm hoping they won't, but OK.
return -ENOSYS;
+}
+static int keyboard_getc(struct stdio_dev *sdev) +{
struct udevice *dev = sdev->priv;
struct keyboard_priv *priv = dev_get_uclass_priv(dev);
/* Just get input to do this for us if we can */
if (priv->input.dev)
return input_getc(&priv->input);
Ditto.
return -ENOSYS;
+}
+static int keyboard_pre_probe(struct udevice *dev) +{
struct keyboard_priv *priv = dev_get_uclass_priv(dev);
struct stdio_dev *sdev = &priv->sdev;
int ret;
strlcpy(sdev->name, dev->name, sizeof(sdev->name));
sdev->flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
sdev->getc = keyboard_getc;
sdev->tstc = keyboard_tstc;
sdev->start = keyboard_start;
sdev->stop = keyboard_stop;
sdev->priv = dev;
ret = input_init(&priv->input, 0);
if (ret) {
debug("%s: Cannot set up input\n", __func__);
return ret;
}
return 0;
+}
+UCLASS_DRIVER(keyboard) = {
.id = UCLASS_KEYBOARD,
.name = "keyboard",
.pre_probe = keyboard_pre_probe,
.per_device_auto_alloc_size = sizeof(struct keyboard_priv),
+}; diff --git a/include/keyboard.h b/include/keyboard.h index 88ae12b..a8b68cb 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,6 +1,83 @@ #ifndef __KEYBOARD_H #define __KEYBOARD_H
+#ifdef CONFIG_DM_KEYBOARD +#include <input.h> +#include <stdio_dev.h>
+/**
- struct keyboard_priv - information about a keyboard, for the uclass
- @sdev: stdio device
- @input: input configuration (the driver may use this if desired)
- */
+struct keyboard_priv {
struct stdio_dev sdev;
/*
* This is set up by the uclass but will only be used if the driver
* sets input.dev to its device pointer (it is initially NULL).
*/
struct input_config input;
+};
+/**
- struct keyboard_ops - keyboard device operations
- */
+struct keyboard_ops {
/**
* start() - enable the keyboard ready for use
*
* @dev: Device to enable
* @return 0 if OK, -ve on error
*/
int (*start)(struct udevice *dev);
/**
* stop() - disable the keyboard when no-longer needed
*
* @dev: Device to disable
* @return 0 if OK, -ve on error
*/
int (*stop)(struct udevice *dev);
/**
* tstc() - check if a key is available
*
* @dev: Device to check
* @return 0 if no key is available, 1 if a key is available
Should we change the return value to bool?
It can return an error - I'll update the comment.
*/
int (*tstc)(struct udevice *dev);
/**
* getc() - get a key
*
* TODO(sjg@chromium.org): At present this method may wait if it calls
* input_getc().
*
* @dev: Device to read from
* @return -EAGAIN if no key is available, otherwise key value read
* (as ASCII).
*/
int (*getc)(struct udevice *dev);
/**
* update_leds() - update keyboard LEDs
*
* This is called when the LEDs have changed and need to be updated.
* For example, if 'caps lock' is pressed then this method will be
* called with the new LED value.
*
* @dev: Device to update
* @leds: New LED mask (see INPUT_LED_... in input.h)
*/
int (*update_leds)(struct udevice *dev, int leds);
+};
+#define keyboard_get_ops(dev) ((struct keyboard_ops *)(dev)->driver->ops)
+#else
#ifdef CONFIG_PS2MULT #include <ps2mult.h> #endif @@ -18,5 +95,6 @@ extern int kbd_init (void); extern void handle_scancode(unsigned char scancode); extern int kbd_init_hw(void); extern void pckbd_leds(unsigned char leds); +#endif /* !CONFIG_DM_KEYBOARD */
#endif /* __KEYBOARD_H */
Regards, Bin
Regards, Simon