Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/i2c.h>
- #include <linux/delay.h>
- #include <linux/input-polldev.h>
- struct input_dev *global_input_dev = NULL;
- struct nunchuk_dev {
- struct input_polled_dev *polled_input;
- struct i2c_client *i2c_client;
- };
- static int nunchuk_probe(struct i2c_client *client, const struct i2c_device_id *device_id)
- {
- int rv;
- struct input_polled_dev *polled_input;
- struct input_dev *input;
- struct nunchuk_dev *nunchuk;
- pr_warn("nunchuk: inside nunchuk_probe.\n");
- rv = 0;
- nunchuk = devm_kzalloc(&client->dev, sizeof(struct nunchuk_dev), GFP_KERNEL);
- if (!nunchuk) {
- dev_err(&client->dev, "[ERROR] failed to allocate memory for nunchuk_dev\n");
- pr_warn("[ERROR] failed to allocate memory for nunchuk_dev\n");
- rv = -ENOMEM;
- goto final;
- }
- polled_input = input_allocate_polled_device();
- if (!polled_input) {
- dev_err(&client->dev, "[ERROR] failed to allocate input_polled_dev\n");
- pr_warn("[ERROR] failed to allocate input_polled_dev\n");
- rv = -ENOMEM;
- goto final;
- }
- nunchuk->i2c_client = client;
- nunchuk->polled_input = polled_input;
- polled_input->private = nunchuk;
- i2c_set_clientdata(client, nunchuk);
- input = polled_input->input;
- input->dev.parent = &client->dev;
- global_input_dev = input;
- pr_warn("nunchuk_probe(): nunchuk = 0x%x, polled_input = 0x%x, input = 0x%x\n", nunchuk, polled_input, input);
- rv = input_register_polled_device(polled_input);
- if (rv) {
- dev_err(&client->dev, "[ERROR] failed to register input_polled_dev\n");
- pr_warn("[ERROR] failed to register polled_input\n");
- goto cleanup;
- }
- cleanup:
- input_free_polled_device(polled_input);
- final:
- pr_warn("nunchuk_probe(): just before exiting... input = 0x%x\n", input);
- return rv;
- }
- static int nunchuk_remove(struct i2c_client *client)
- {
- struct nunchuk_dev *nunchuk = NULL;
- struct input_polled_dev *polled_input = NULL;
- struct input_dev *input = NULL;
- pr_warn("nunchuk: ENTERING remove()\n");
- nunchuk = i2c_get_clientdata(client);
- input = nunchuk->polled_input->input;
- pr_warn("nunchuk_remove(): nunchuk = 0x%x. nunchuk->polled_input = 0x%x. polled_input->input = 0x%x\n", nunchuk, nunchuk->polled_input, input);
- pr_warn("nunchuk_remove(): global_input_dev = 0x%x\n", global_input_dev);
- if (!nunchuk) {
- pr_warn("[ERROR] remove(): failed to obtain nunchuk_dev\n");
- return -1;
- }
- polled_input = nunchuk->polled_input;
- if (!polled_input) {
- pr_warn("[ERROR] nunchuk_remove(): nunchuk->polled_input is null!\n");
- return -1;
- }
- pr_warn("*** before input_unregister_polled_device()\n");
- input_unregister_polled_device(polled_input);
- pr_warn("*** before input_free_polled_device()\n");
- input_free_polled_device(polled_input);
- pr_warn("*** about to return\n");
- return 0;
- }
- static const struct i2c_device_id nunchuk_id[] = {
- { "nunchuk", 0 },
- { },
- };
- MODULE_DEVICE_TABLE(i2c, nunchuk_id);
- #ifdef CONFIG_OF
- static const struct of_device_id nunchuk_dt_ids[] = {
- { .compatible = "nintendo,nunchuk", },
- { },
- };
- MODULE_DEVICE_TABLE(of, nunchuk_dt_ids);
- #endif
- static struct i2c_driver nunchuk_driver = {
- .probe = nunchuk_probe,
- .remove = nunchuk_remove,
- .id_table = nunchuk_id,
- .driver = {
- .name = "nunchuk",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(nunchuk_dt_ids),
- },
- };
- module_i2c_driver(nunchuk_driver);
- MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement