static int __devinit gpio_keys_probe(struct platform_device *pdev) { const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct gpio_keys_drvdata *ddata; struct device *dev = &pdev->dev; struct gpio_keys_platform_data alt_pdata; struct input_dev *input; int i, error; int wakeup = 0; if (!pdata) { error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); if (error) return error; pdata = &alt_pdata; } ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + pdata->nbuttons * sizeof(struct gpio_button_data), GFP_KERNEL); input = input_allocate_device(); if (!ddata || !input) { dev_err(dev, "failed to allocate state\n"); error = -ENOMEM; goto fail1; } ddata->input = input; ddata->n_buttons = pdata->nbuttons; ddata->enable = pdata->enable; ddata->disable = pdata->disable; #ifdef CONFIG_SENSORS_HALL ddata->gpio_flip_cover = pdata->gpio_flip_cover; ddata->irq_flip_cover = gpio_to_irq(ddata->gpio_flip_cover);; wake_lock_init(&ddata->flip_wake_lock, WAKE_LOCK_SUSPEND, "flip wake lock"); #endif mutex_init(&ddata->disable_lock); platform_set_drvdata(pdev, ddata); input_set_drvdata(input, ddata); input->name = pdata->name ? : pdev->name; input->phys = "gpio-keys/input0"; input->dev.parent = &pdev->dev; #ifdef CONFIG_SENSORS_HALL input->evbit[0] |= BIT_MASK(EV_SW); input_set_capability(input, EV_SW, SW_FLIP); #endif input->open = gpio_keys_open; input->close = gpio_keys_close; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; input->id.version = 0x0100; /* Enable auto repeat feature of Linux input subsystem */ if (pdata->rep) __set_bit(EV_REP, input->evbit); for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_button_data *bdata = &ddata->data[i]; error = gpio_keys_setup_key(pdev, input, bdata, button); if (error) goto fail2; if (button->wakeup) wakeup = 1; #ifdef KEY_BOOSTER if (button->code == KEY_HOMEPAGE) { error = gpio_key_init_dvfs(bdata); if (error < 0) { dev_err(dev, "Fail get dvfs level for touch booster\n"); goto fail2; } } #endif } error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); if (error) { dev_err(dev, "Unable to export keys/switches, error: %d\n", error); goto fail2; } ddata->sec_key = device_create(sec_class, NULL, 0, ddata, "sec_key"); if (IS_ERR(ddata->sec_key)) dev_err(dev, "Failed to create sec_key device\n"); error = sysfs_create_group(&ddata->sec_key->kobj, &sec_key_attr_group); if (error) { dev_err(dev, "Failed to create the test sysfs: %d\n", error); goto fail2; } #ifdef CONFIG_SENSORS_HALL init_hall_ic_irq(input); #endif error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); goto fail3; } /* get current state of buttons */ for (i = 0; i < pdata->nbuttons; i++) gpio_keys_gpio_report_event(&ddata->data[i]); input_sync(input); device_init_wakeup(&pdev->dev, wakeup); return 0; fail3: sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); sysfs_remove_group(&ddata->sec_key->kobj, &sec_key_attr_group); fail2: while (--i >= 0) gpio_remove_key(&ddata->data[i]); platform_set_drvdata(pdev, NULL); #ifdef CONFIG_SENSORS_HALL wake_lock_destroy(&ddata->flip_wake_lock); #endif fail1: input_free_device(input); kfree(ddata); /* If we have no platform_data, we allocated buttons dynamically. */ if (!pdev->dev.platform_data) kfree(pdata->buttons); return error; }
static int hall_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct hall_drvdata *ddata; struct input_dev *input; int error; int wakeup = 0; ddata = kzalloc(sizeof(struct hall_drvdata), GFP_KERNEL); if (!ddata) { dev_err(dev, "failed to allocate state\n"); return -ENOMEM; } #ifdef CONFIG_OF if(dev->of_node) { error = of_hall_data_parsing_dt(ddata); if (error < 0) { pr_info("%s : fail to get the dt (HALL)\n", __func__); goto fail1; } } #endif input = input_allocate_device(); if (!input) { dev_err(dev, "failed to allocate state\n"); error = -ENOMEM; goto fail1; } ddata->input = input; wake_lock_init(&ddata->accessory_wake_lock, WAKE_LOCK_SUSPEND, "hall accessory wake lock"); platform_set_drvdata(pdev, ddata); input_set_drvdata(input, ddata); input->name = "hall accessory"; input->phys = "hall accessory"; input->dev.parent = &pdev->dev; input->evbit[0] |= BIT_MASK(EV_SW); input_set_capability(input, EV_SW, SW_3D_ACC); input->open = hall_open; input->close = hall_close; /* Enable auto repeat feature of Linux input subsystem */ __set_bit(EV_REP, input->evbit); init_hall_ic_irq(input); error = sysfs_create_group(&sec_key->kobj, &hall_attr_group); if (error) { dev_err(dev, "Unable to export keys/switches, error: %d\n", error); goto fail2; } error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); goto fail3; } device_init_wakeup(&pdev->dev, wakeup); return 0; fail3: sysfs_remove_group(&pdev->dev.kobj, &hall_attr_group); fail2: platform_set_drvdata(pdev, NULL); wake_lock_destroy(&ddata->accessory_wake_lock); input_free_device(input); fail1: kfree(ddata); return error; }