forked from luck/tmp_suning_uos_patched
Input: apanel - switch to using polled mode of input devices
We have added polled mode to the normal input devices with the intent of retiring input_polled_dev. This converts apanel driver to use the polling mode of standard input devices and removes dependency on INPUT_POLLDEV. While at it, let's convert the driver to use devm. Link: https://lore.kernel.org/r/20191017204217.106453-10-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
9584bded0b
commit
071ec845c8
|
@ -257,7 +257,6 @@ config INPUT_MMA8450
|
|||
config INPUT_APANEL
|
||||
tristate "Fujitsu Lifebook Application Panel buttons"
|
||||
depends on X86 && I2C && LEDS_CLASS
|
||||
select INPUT_POLLDEV
|
||||
select CHECK_SIGNATURE
|
||||
help
|
||||
Say Y here for support of the Application Panel buttons, used on
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
|
@ -51,19 +51,28 @@ static enum apanel_chip device_chip[APANEL_DEV_MAX];
|
|||
#define MAX_PANEL_KEYS 12
|
||||
|
||||
struct apanel {
|
||||
struct input_polled_dev *ipdev;
|
||||
struct input_dev *idev;
|
||||
struct i2c_client *client;
|
||||
unsigned short keymap[MAX_PANEL_KEYS];
|
||||
u16 nkeys;
|
||||
u16 nkeys;
|
||||
struct led_classdev mail_led;
|
||||
};
|
||||
|
||||
static const unsigned short apanel_keymap[MAX_PANEL_KEYS] = {
|
||||
[0] = KEY_MAIL,
|
||||
[1] = KEY_WWW,
|
||||
[2] = KEY_PROG2,
|
||||
[3] = KEY_PROG1,
|
||||
|
||||
static int apanel_probe(struct i2c_client *, const struct i2c_device_id *);
|
||||
[8] = KEY_FORWARD,
|
||||
[9] = KEY_REWIND,
|
||||
[10] = KEY_STOPCD,
|
||||
[11] = KEY_PLAYPAUSE,
|
||||
};
|
||||
|
||||
static void report_key(struct input_dev *input, unsigned keycode)
|
||||
{
|
||||
pr_debug(APANEL ": report key %#x\n", keycode);
|
||||
dev_dbg(input->dev.parent, "report key %#x\n", keycode);
|
||||
input_report_key(input, keycode, 1);
|
||||
input_sync(input);
|
||||
|
||||
|
@ -79,10 +88,9 @@ static void report_key(struct input_dev *input, unsigned keycode)
|
|||
* CD keys:
|
||||
* Forward (0x100), Rewind (0x200), Stop (0x400), Pause (0x800)
|
||||
*/
|
||||
static void apanel_poll(struct input_polled_dev *ipdev)
|
||||
static void apanel_poll(struct input_dev *idev)
|
||||
{
|
||||
struct apanel *ap = ipdev->private;
|
||||
struct input_dev *idev = ipdev->input;
|
||||
struct apanel *ap = input_get_drvdata(idev);
|
||||
u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
|
||||
s32 data;
|
||||
int i;
|
||||
|
@ -112,22 +120,76 @@ static int mail_led_set(struct led_classdev *led,
|
|||
return i2c_smbus_write_word_data(ap->client, 0x10, led_bits);
|
||||
}
|
||||
|
||||
static int apanel_remove(struct i2c_client *client)
|
||||
static int apanel_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct apanel *ap = i2c_get_clientdata(client);
|
||||
struct apanel *ap;
|
||||
struct input_dev *idev;
|
||||
u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
|
||||
int i, err;
|
||||
|
||||
if (device_chip[APANEL_DEV_LED] != CHIP_NONE)
|
||||
led_classdev_unregister(&ap->mail_led);
|
||||
ap = devm_kzalloc(&client->dev, sizeof(*ap), GFP_KERNEL);
|
||||
if (!ap)
|
||||
return -ENOMEM;
|
||||
|
||||
input_unregister_polled_device(ap->ipdev);
|
||||
input_free_polled_device(ap->ipdev);
|
||||
idev = devm_input_allocate_device(&client->dev);
|
||||
if (!idev)
|
||||
return -ENOMEM;
|
||||
|
||||
ap->idev = idev;
|
||||
ap->client = client;
|
||||
|
||||
i2c_set_clientdata(client, ap);
|
||||
|
||||
err = i2c_smbus_write_word_data(client, cmd, 0);
|
||||
if (err) {
|
||||
dev_warn(&client->dev, "smbus write error %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
input_set_drvdata(idev, ap);
|
||||
|
||||
idev->name = APANEL_NAME " buttons";
|
||||
idev->phys = "apanel/input0";
|
||||
idev->id.bustype = BUS_HOST;
|
||||
|
||||
memcpy(ap->keymap, apanel_keymap, sizeof(apanel_keymap));
|
||||
idev->keycode = ap->keymap;
|
||||
idev->keycodesize = sizeof(ap->keymap[0]);
|
||||
idev->keycodemax = (device_chip[APANEL_DEV_CDBTN] != CHIP_NONE) ? 12 : 4;
|
||||
|
||||
set_bit(EV_KEY, idev->evbit);
|
||||
for (i = 0; i < idev->keycodemax; i++)
|
||||
if (ap->keymap[i])
|
||||
set_bit(ap->keymap[i], idev->keybit);
|
||||
|
||||
err = input_setup_polling(idev, apanel_poll);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
input_set_poll_interval(idev, POLL_INTERVAL_DEFAULT);
|
||||
|
||||
err = input_register_device(idev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (device_chip[APANEL_DEV_LED] != CHIP_NONE) {
|
||||
ap->mail_led.name = "mail:blue";
|
||||
ap->mail_led.brightness_set_blocking = mail_led_set;
|
||||
err = devm_led_classdev_register(&client->dev, &ap->mail_led);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apanel_shutdown(struct i2c_client *client)
|
||||
{
|
||||
apanel_remove(client);
|
||||
struct apanel *ap = i2c_get_clientdata(client);
|
||||
|
||||
if (device_chip[APANEL_DEV_LED] != CHIP_NONE)
|
||||
led_set_brightness(&ap->mail_led, LED_OFF);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id apanel_id[] = {
|
||||
|
@ -140,98 +202,11 @@ static struct i2c_driver apanel_driver = {
|
|||
.driver = {
|
||||
.name = APANEL,
|
||||
},
|
||||
.probe = &apanel_probe,
|
||||
.remove = &apanel_remove,
|
||||
.shutdown = &apanel_shutdown,
|
||||
.probe = apanel_probe,
|
||||
.shutdown = apanel_shutdown,
|
||||
.id_table = apanel_id,
|
||||
};
|
||||
|
||||
static struct apanel apanel = {
|
||||
.keymap = {
|
||||
[0] = KEY_MAIL,
|
||||
[1] = KEY_WWW,
|
||||
[2] = KEY_PROG2,
|
||||
[3] = KEY_PROG1,
|
||||
|
||||
[8] = KEY_FORWARD,
|
||||
[9] = KEY_REWIND,
|
||||
[10] = KEY_STOPCD,
|
||||
[11] = KEY_PLAYPAUSE,
|
||||
|
||||
},
|
||||
.mail_led = {
|
||||
.name = "mail:blue",
|
||||
.brightness_set_blocking = mail_led_set,
|
||||
},
|
||||
};
|
||||
|
||||
/* NB: Only one panel on the i2c. */
|
||||
static int apanel_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct apanel *ap;
|
||||
struct input_polled_dev *ipdev;
|
||||
struct input_dev *idev;
|
||||
u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
|
||||
int i, err = -ENOMEM;
|
||||
|
||||
ap = &apanel;
|
||||
|
||||
ipdev = input_allocate_polled_device();
|
||||
if (!ipdev)
|
||||
goto out1;
|
||||
|
||||
ap->ipdev = ipdev;
|
||||
ap->client = client;
|
||||
|
||||
i2c_set_clientdata(client, ap);
|
||||
|
||||
err = i2c_smbus_write_word_data(client, cmd, 0);
|
||||
if (err) {
|
||||
dev_warn(&client->dev, APANEL ": smbus write error %d\n",
|
||||
err);
|
||||
goto out3;
|
||||
}
|
||||
|
||||
ipdev->poll = apanel_poll;
|
||||
ipdev->poll_interval = POLL_INTERVAL_DEFAULT;
|
||||
ipdev->private = ap;
|
||||
|
||||
idev = ipdev->input;
|
||||
idev->name = APANEL_NAME " buttons";
|
||||
idev->phys = "apanel/input0";
|
||||
idev->id.bustype = BUS_HOST;
|
||||
idev->dev.parent = &client->dev;
|
||||
|
||||
set_bit(EV_KEY, idev->evbit);
|
||||
|
||||
idev->keycode = ap->keymap;
|
||||
idev->keycodesize = sizeof(ap->keymap[0]);
|
||||
idev->keycodemax = (device_chip[APANEL_DEV_CDBTN] != CHIP_NONE) ? 12 : 4;
|
||||
|
||||
for (i = 0; i < idev->keycodemax; i++)
|
||||
if (ap->keymap[i])
|
||||
set_bit(ap->keymap[i], idev->keybit);
|
||||
|
||||
err = input_register_polled_device(ipdev);
|
||||
if (err)
|
||||
goto out3;
|
||||
|
||||
if (device_chip[APANEL_DEV_LED] != CHIP_NONE) {
|
||||
err = led_classdev_register(&client->dev, &ap->mail_led);
|
||||
if (err)
|
||||
goto out4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out4:
|
||||
input_unregister_polled_device(ipdev);
|
||||
out3:
|
||||
input_free_polled_device(ipdev);
|
||||
out1:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Scan the system ROM for the signature "FJKEYINF" */
|
||||
static __init const void __iomem *bios_signature(const void __iomem *bios)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user