/** * Creates the kernel input device. * * Return: 0 on success, negated errno on failure. */ static int vbg_create_input_device(struct vbg_dev *gdev) { struct input_dev *input; input = devm_input_allocate_device(gdev->dev); if (!input) return -ENOMEM; input->id.bustype = BUS_PCI; input->id.vendor = VBOX_VENDORID; input->id.product = VMMDEV_DEVICEID; input->open = vbg_input_open; input->close = vbg_input_close; input->dev.parent = gdev->dev; input->name = "VirtualBox mouse integration"; input_set_abs_params(input, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0); input_set_abs_params(input, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0); input_set_capability(input, EV_KEY, BTN_MOUSE); input_set_drvdata(input, gdev); gdev->input = input; return input_register_device(gdev->input); }
/** * pimhyp3_request_input_dev - Allocate, populate and register the input device * @ts: our pimhyp3_ts_data pointer * Must be called during probe */ static int pimhyp3_request_input_dev(struct pimhyp3_ts_data *ts) { int error; ts->input_dev = devm_input_allocate_device(&ts->client->dev); if (!ts->input_dev) { dev_err(&ts->client->dev, "Failed to allocate input device."); return -ENOMEM; } /* Set up device parameters */ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); ts->input_dev->name = "Cypress Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0416; ts->input_dev->id.product = ts->id; ts->input_dev->id.version = ts->version; error = input_register_device(ts->input_dev); if (error) { dev_err(&ts->client->dev, "Failed to register input device: %d", error); return error; } return 0; }
static int retu_pwrbutton_probe(struct platform_device *pdev) { struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent); struct input_dev *idev; int irq; int error; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; idev->name = "retu-pwrbutton"; idev->dev.parent = &pdev->dev; input_set_capability(idev, EV_KEY, KEY_POWER); input_set_drvdata(idev, rdev); error = devm_request_threaded_irq(&pdev->dev, irq, NULL, retu_pwrbutton_irq, 0, "retu-pwrbutton", idev); if (error) return error; error = input_register_device(idev); if (error) return error; return 0; }
static int chtdc_ti_pwrbtn_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent); struct input_dev *input; int irq, err; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; input = devm_input_allocate_device(dev); if (!input) return -ENOMEM; input->name = pdev->name; input->phys = "power-button/input0"; input->id.bustype = BUS_HOST; input_set_capability(input, EV_KEY, KEY_POWER); err = input_register_device(input); if (err) return err; dev_set_drvdata(dev, pmic->regmap); err = devm_request_threaded_irq(dev, irq, NULL, chtdc_ti_pwrbtn_interrupt, 0, KBUILD_MODNAME, input); if (err) return err; device_init_wakeup(dev, true); dev_pm_set_wake_irq(dev, irq); return 0; }
static int silead_ts_request_input_dev(struct silead_ts_data *data) { struct device *dev = &data->client->dev; int error; data->input = devm_input_allocate_device(dev); if (!data->input) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } input_set_abs_params(data->input, ABS_MT_POSITION_X, 0, 4095, 0, 0); input_set_abs_params(data->input, ABS_MT_POSITION_Y, 0, 4095, 0, 0); touchscreen_parse_properties(data->input, true, &data->prop); input_mt_init_slots(data->input, data->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); if (device_property_read_bool(dev, "silead,home-button")) input_set_capability(data->input, EV_KEY, KEY_LEFTMETA); data->input->name = SILEAD_TS_NAME; data->input->phys = "input/ts"; data->input->id.bustype = BUS_I2C; error = input_register_device(data->input); if (error) { dev_err(dev, "Failed to register input device: %d\n", error); return error; } return 0; }
static int hall_input_init(struct platform_device *pdev, struct hall_data *data) { int err = -1; data->hall_dev = devm_input_allocate_device(&pdev->dev); if (!data->hall_dev) { dev_err(&data->hall_dev->dev, "input device allocation failed\n"); return -EINVAL; } data->hall_dev->name = LID_DEV_NAME; data->hall_dev->phys = HALL_INPUT; __set_bit(EV_SW, data->hall_dev->evbit); __set_bit(SW_LID, data->hall_dev->swbit); err = input_register_device(data->hall_dev); if (err < 0) { dev_err(&data->hall_dev->dev, "unable to register input device %s\n", LID_DEV_NAME); return err; } return 0; }
static int gpio_vibrator_probe(struct platform_device *pdev) { struct gpio_vibrator *vibrator; int err; vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL); if (!vibrator) return -ENOMEM; vibrator->input = devm_input_allocate_device(&pdev->dev); if (!vibrator->input) return -ENOMEM; vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc"); err = PTR_ERR_OR_ZERO(vibrator->vcc); if (err) { if (err != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to request regulator: %d\n", err); return err; } vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW); err = PTR_ERR_OR_ZERO(vibrator->gpio); if (err) { if (err != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to request main gpio: %d\n", err); return err; } INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work); vibrator->input->name = "gpio-vibrator"; vibrator->input->id.bustype = BUS_HOST; vibrator->input->close = gpio_vibrator_close; input_set_drvdata(vibrator->input, vibrator); input_set_capability(vibrator->input, EV_FF, FF_RUMBLE); err = input_ff_create_memless(vibrator->input, NULL, gpio_vibrator_play_effect); if (err) { dev_err(&pdev->dev, "Couldn't create FF dev: %d\n", err); return err; } err = input_register_device(vibrator->input); if (err) { dev_err(&pdev->dev, "Couldn't register input dev: %d\n", err); return err; } platform_set_drvdata(pdev, vibrator); return 0; }
static int pm8xxx_vib_probe(struct platform_device *pdev) { struct pm8xxx_vib *vib; struct input_dev *input_dev; int error; unsigned int val; vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL); if (!vib) return -ENOMEM; vib->regmap = dev_get_regmap(pdev->dev.parent, NULL); if (!vib->regmap) return -ENODEV; input_dev = devm_input_allocate_device(&pdev->dev); if (!input_dev) return -ENOMEM; INIT_WORK(&vib->work, pm8xxx_work_handler); vib->vib_input_dev = input_dev; /* operate in manual mode */ error = regmap_read(vib->regmap, VIB_DRV, &val); if (error < 0) return error; val &= ~VIB_DRV_EN_MANUAL_MASK; error = regmap_write(vib->regmap, VIB_DRV, val); if (error < 0) return error; vib->reg_vib_drv = val; input_dev->name = "pm8xxx_vib_ffmemless"; input_dev->id.version = 1; input_dev->close = pm8xxx_vib_close; input_set_drvdata(input_dev, vib); input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE); error = input_ff_create_memless(input_dev, NULL, pm8xxx_vib_play_effect); if (error) { dev_err(&pdev->dev, "couldn't register vibrator as FF device\n"); return error; } error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "couldn't register input device\n"); return error; } platform_set_drvdata(pdev, vib); return 0; }
static int twl4030_vibra_probe(struct platform_device *pdev) { struct twl4030_vibra_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *twl4030_core_node = pdev->dev.parent->of_node; struct vibra_info *info; int ret; if (!pdata && !twl4030_core_node) { dev_dbg(&pdev->dev, "platform_data not available\n"); return -EINVAL; } info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); INIT_WORK(&info->play_work, vibra_play_work); info->input_dev = devm_input_allocate_device(&pdev->dev); if (info->input_dev == NULL) { dev_err(&pdev->dev, "couldn't allocate input device\n"); return -ENOMEM; } input_set_drvdata(info->input_dev, info); info->input_dev->name = "twl4030:vibrator"; info->input_dev->id.version = 1; info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->close = twl4030_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); return ret; } ret = input_register_device(info->input_dev); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't register input device\n"); goto err_iff; } vibra_disable_leds(); platform_set_drvdata(pdev, info); return 0; err_iff: input_ff_destroy(info->input_dev); return ret; }
static int cht_pwrbtn_probe(struct platform_device *pdev) { int ret; struct device *dev = &pdev->dev; struct input_dev *input; ret = devm_gpio_request_one(dev, CHT_PWRBTN_GPIO, GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, CHT_PWRBTN_NAME); if (ret) { dev_err(dev, "Failed to request GPIO %d, error %d\n", CHT_PWRBTN_GPIO, ret); return ret; } input = devm_input_allocate_device(dev); if (!input) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } input->name = CHT_PWRBTN_NAME; input->evbit[0] = BIT_MASK(EV_KEY); input_set_capability(input, EV_KEY, KEY_POWER); ret = gpio_to_irq(CHT_PWRBTN_GPIO); if (ret < 0) { dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", CHT_PWRBTN_GPIO, ret); return ret; } ret = devm_request_irq(dev, ret, cht_pwrbtn_irq, (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING), CHT_PWRBTN_NAME, input); if (ret) { dev_err(dev, "Unable to request irq, error: %d\n", ret); return ret; } ret = input_register_device(input); if (ret) { dev_err(dev, "Unable to register input device, error: %d\n", ret); return ret; } platform_set_drvdata(pdev, input); device_init_wakeup(&pdev->dev, 1); dev_info(dev, "Driver successfully loaded"); return 0; }
static int jornada720_kbd_probe(struct platform_device *pdev) { struct jornadakbd *jornadakbd; struct input_dev *input_dev; int i, err, irq; irq = platform_get_irq(pdev, 0); if (irq <= 0) return irq < 0 ? irq : -EINVAL; jornadakbd = devm_kzalloc(&pdev->dev, sizeof(*jornadakbd), GFP_KERNEL); input_dev = devm_input_allocate_device(&pdev->dev); if (!jornadakbd || !input_dev) return -ENOMEM; platform_set_drvdata(pdev, jornadakbd); memcpy(jornadakbd->keymap, jornada_std_keymap, sizeof(jornada_std_keymap)); jornadakbd->input = input_dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->name = "HP Jornada 720 keyboard"; input_dev->phys = "jornadakbd/input0"; input_dev->keycode = jornadakbd->keymap; input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodemax = ARRAY_SIZE(jornada_std_keymap); input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; for (i = 0; i < ARRAY_SIZE(jornadakbd->keymap); i++) __set_bit(jornadakbd->keymap[i], input_dev->keybit); __clear_bit(KEY_RESERVED, input_dev->keybit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); err = devm_request_irq(&pdev->dev, irq, jornada720_kbd_interrupt, IRQF_TRIGGER_FALLING, "jornadakbd", pdev); if (err) { dev_err(&pdev->dev, "unable to grab IRQ%d: %d\n", irq, err); return err; } return input_register_device(jornadakbd->input); };
static int intel_hid_input_setup(struct platform_device *device) { struct intel_hid_priv *priv = dev_get_drvdata(&device->dev); int ret; priv->input_dev = devm_input_allocate_device(&device->dev); if (!priv->input_dev) return -ENOMEM; ret = sparse_keymap_setup(priv->input_dev, intel_hid_keymap, NULL); if (ret) return ret; priv->input_dev->name = "Intel HID events"; priv->input_dev->id.bustype = BUS_HOST; return input_register_device(priv->input_dev); }
static int intel_vbtn_input_setup(struct platform_device *device) { struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); int ret; priv->input_dev = devm_input_allocate_device(&device->dev); if (!priv->input_dev) return -ENOMEM; ret = sparse_keymap_setup(priv->input_dev, intel_vbtn_keymap, NULL); if (ret) return ret; priv->input_dev->dev.parent = &device->dev; priv->input_dev->name = "Intel Virtual Button driver"; priv->input_dev->id.bustype = BUS_HOST; return input_register_device(priv->input_dev); }
static int intel_button_array_input_setup(struct platform_device *device) { struct intel_hid_priv *priv = dev_get_drvdata(&device->dev); int ret; /* Setup input device for 5 button array */ priv->array = devm_input_allocate_device(&device->dev); if (!priv->array) return -ENOMEM; ret = sparse_keymap_setup(priv->array, intel_array_keymap, NULL); if (ret) return ret; priv->array->name = "Intel HID 5 button array"; priv->array->id.bustype = BUS_HOST; return input_register_device(priv->array); }
static int asus_wireless_add(struct acpi_device *adev) { struct asus_wireless_data *data; data = devm_kzalloc(&adev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; adev->driver_data = data; data->idev = devm_input_allocate_device(&adev->dev); if (!data->idev) return -ENOMEM; data->idev->name = "Asus Wireless Radio Control"; data->idev->phys = "asus-wireless/input0"; data->idev->id.bustype = BUS_HOST; data->idev->id.vendor = PCI_VENDOR_ID_ASUSTEK; set_bit(EV_KEY, data->idev->evbit); set_bit(KEY_RFKILL, data->idev->keybit); return input_register_device(data->idev); }
static int silead_ts_request_input_dev(struct silead_ts_data *data) { struct device *dev = &data->client->dev; int ret; data->input_dev = devm_input_allocate_device(dev); if (!data->input_dev) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } data->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_set_abs_params(data->input_dev, ABS_MT_POSITION_X, 0, data->x_max, 0, 0); input_set_abs_params(data->input_dev, ABS_MT_POSITION_Y, 0, data->y_max, 0, 0); input_set_abs_params(data->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(data->input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0); input_mt_init_slots(data->input_dev, data->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); data->input_dev->name = SILEAD_TS_NAME; data->input_dev->phys = "input/ts"; data->input_dev->id.bustype = BUS_I2C; ret = input_register_device(data->input_dev); if (ret) { dev_err(dev, "Failed to register input device: %d\n", ret); return ret; } return 0; }
/** * goodix_request_input_dev - Allocate, populate and register the input device * * @ts: our goodix_ts_data pointer * * Must be called during probe */ static int goodix_request_input_dev(struct goodix_ts_data *ts) { int error; ts->input_dev = devm_input_allocate_device(&ts->client->dev); if (!ts->input_dev) { dev_err(&ts->client->dev, "Failed to allocate input device."); return -ENOMEM; } ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); ts->input_dev->name = "Goodix Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0416; ts->input_dev->id.product = 0x1001; ts->input_dev->id.version = 10427; error = input_register_device(ts->input_dev); if (error) { dev_err(&ts->client->dev, "Failed to register input device: %d", error); return error; } return 0; }
static int gpio_beeper_probe(struct platform_device *pdev) { struct gpio_beeper *beep; struct input_dev *input; int err; beep = devm_kzalloc(&pdev->dev, sizeof(*beep), GFP_KERNEL); if (!beep) return -ENOMEM; beep->desc = devm_gpiod_get(&pdev->dev, NULL); if (IS_ERR(beep->desc)) return PTR_ERR(beep->desc); input = devm_input_allocate_device(&pdev->dev); if (!input) return -ENOMEM; INIT_WORK(&beep->work, gpio_beeper_work); input->name = pdev->name; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; input->id.version = 0x0100; input->close = gpio_beeper_close; input->event = gpio_beeper_event; input_set_capability(input, EV_SND, SND_BELL); err = gpiod_direction_output(beep->desc, 0); if (err) return err; input_set_drvdata(input, beep); return input_register_device(input); }
static int twl4030_pwrbutton_probe(struct platform_device *pdev) { struct input_dev *pwr; int irq = platform_get_irq(pdev, 0); int err; pwr = devm_input_allocate_device(&pdev->dev); if (!pwr) { dev_err(&pdev->dev, "Can't allocate power button\n"); return -ENOMEM; } pwr->evbit[0] = BIT_MASK(EV_KEY); pwr->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); pwr->name = "twl4030_pwrbutton"; pwr->phys = "twl4030_pwrbutton/input0"; pwr->dev.parent = &pdev->dev; err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl4030_pwrbutton", pwr); if (err < 0) { dev_err(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err); return err; } err = input_register_device(pwr); if (err) { dev_err(&pdev->dev, "Can't register power button: %d\n", err); return err; } platform_set_drvdata(pdev, pwr); device_init_wakeup(&pdev->dev, true); return 0; }
static struct input_dev *allocate_and_setup(struct hid_device *hdev, const char *name) { struct input_dev *input_dev; input_dev = devm_input_allocate_device(&hdev->dev); if (!input_dev) return NULL; input_dev->name = name; input_dev->phys = hdev->phys; input_dev->dev.parent = &hdev->dev; input_dev->open = udraw_open; input_dev->close = udraw_close; input_dev->uniq = hdev->uniq; input_dev->id.bustype = hdev->bus; input_dev->id.vendor = hdev->vendor; input_dev->id.product = hdev->product; input_dev->id.version = hdev->version; input_set_drvdata(input_dev, hid_get_drvdata(hdev)); return input_dev; }
static void cs42l52_init_beep(struct snd_soc_codec *codec) { struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); int ret; cs42l52->beep = devm_input_allocate_device(codec->dev); if (!cs42l52->beep) { dev_err(codec->dev, "Failed to allocate beep device\n"); return; } INIT_WORK(&cs42l52->beep_work, cs42l52_beep_work); cs42l52->beep_rate = 0; cs42l52->beep->name = "CS42L52 Beep Generator"; cs42l52->beep->phys = dev_name(codec->dev); cs42l52->beep->id.bustype = BUS_I2C; cs42l52->beep->evbit[0] = BIT_MASK(EV_SND); cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); cs42l52->beep->event = cs42l52_beep_event; cs42l52->beep->dev.parent = codec->dev; input_set_drvdata(cs42l52->beep, codec); ret = input_register_device(cs42l52->beep); if (ret != 0) { cs42l52->beep = NULL; dev_err(codec->dev, "Failed to register beep device\n"); } ret = device_create_file(codec->dev, &dev_attr_beep); if (ret != 0) { dev_err(codec->dev, "Failed to create keyclick file: %d\n", ret); } }
static int adp5520_keys_probe(struct platform_device *pdev) { struct adp5520_keys_platform_data *pdata = dev_get_platdata(&pdev->dev); struct input_dev *input; struct adp5520_keys *dev; int ret, i; unsigned char en_mask, ctl_mask = 0; if (pdev->id != ID_ADP5520) { dev_err(&pdev->dev, "only ADP5520 supports Keypad\n"); return -EINVAL; } if (!pdata) { dev_err(&pdev->dev, "missing platform data\n"); return -EINVAL; } if (!(pdata->rows_en_mask && pdata->cols_en_mask)) return -EINVAL; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) { dev_err(&pdev->dev, "failed to alloc memory\n"); return -ENOMEM; } input = devm_input_allocate_device(&pdev->dev); if (!input) return -ENOMEM; dev->master = pdev->dev.parent; dev->input = input; input->name = pdev->name; input->phys = "adp5520-keys/input0"; input->dev.parent = &pdev->dev; input_set_drvdata(input, dev); input->id.bustype = BUS_I2C; input->id.vendor = 0x0001; input->id.product = 0x5520; input->id.version = 0x0001; input->keycodesize = sizeof(dev->keycode[0]); input->keycodemax = pdata->keymapsize; input->keycode = dev->keycode; memcpy(dev->keycode, pdata->keymap, pdata->keymapsize * input->keycodesize); /* setup input device */ __set_bit(EV_KEY, input->evbit); if (pdata->repeat) __set_bit(EV_REP, input->evbit); for (i = 0; i < input->keycodemax; i++) __set_bit(dev->keycode[i], input->keybit); __clear_bit(KEY_RESERVED, input->keybit); ret = input_register_device(input); if (ret) { dev_err(&pdev->dev, "unable to register input device\n"); return ret; } en_mask = pdata->rows_en_mask | pdata->cols_en_mask; ret = adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_1, en_mask); if (en_mask & ADP5520_COL_C3) ctl_mask |= ADP5520_C3_MODE; if (en_mask & ADP5520_ROW_R3) ctl_mask |= ADP5520_R3_MODE; if (ctl_mask) ret |= adp5520_set_bits(dev->master, ADP5520_LED_CONTROL, ctl_mask); ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP, pdata->rows_en_mask); if (ret) { dev_err(&pdev->dev, "failed to write\n"); return -EIO; } dev->notifier.notifier_call = adp5520_keys_notifier; ret = adp5520_register_notifier(dev->master, &dev->notifier, ADP5520_KP_IEN | ADP5520_KR_IEN); if (ret) { dev_err(&pdev->dev, "failed to register notifier\n"); return ret; } platform_set_drvdata(pdev, dev); return 0; }
static int gpio_keys_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); struct gpio_keys_drvdata *ddata; struct input_dev *input; size_t size; int i, error; int wakeup = 0; if (!pdata) { pdata = gpio_keys_get_devtree_pdata(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } size = sizeof(struct gpio_keys_drvdata) + pdata->nbuttons * sizeof(struct gpio_button_data); ddata = devm_kzalloc(dev, size, GFP_KERNEL); if (!ddata) { dev_err(dev, "failed to allocate state\n"); return -ENOMEM; } input = devm_input_allocate_device(dev); if (!input) { dev_err(dev, "failed to allocate input device\n"); return -ENOMEM; } ddata->pdata = pdata; ddata->input = input; 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; 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++) { const 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) return error; if (button->wakeup) wakeup = 1; } 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); return error; } error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); goto err_remove_group; } device_init_wakeup(&pdev->dev, wakeup); return 0; err_remove_group: sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); return error; }
static int sirfsoc_pwrc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct sirfsoc_pwrc_drvdata *pwrcdrv; int irq; int error; pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata), GFP_KERNEL); if (!pwrcdrv) { dev_info(&pdev->dev, "Not enough memory for the device data\n"); return -ENOMEM; } /* * We can't use of_iomap because pwrc is not mapped in memory, * the so-called base address is only offset in rtciobrg */ error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base); if (error) { dev_err(&pdev->dev, "unable to find base address of pwrc node in dtb\n"); return error; } pwrcdrv->input = devm_input_allocate_device(&pdev->dev); if (!pwrcdrv->input) return -ENOMEM; pwrcdrv->input->name = "sirfsoc pwrckey"; pwrcdrv->input->phys = "pwrc/input0"; pwrcdrv->input->evbit[0] = BIT_MASK(EV_KEY); input_set_capability(pwrcdrv->input, EV_KEY, KEY_POWER); INIT_DELAYED_WORK(&pwrcdrv->work, sirfsoc_pwrc_report_event); pwrcdrv->input->open = sirfsoc_pwrc_open; pwrcdrv->input->close = sirfsoc_pwrc_close; input_set_drvdata(pwrcdrv->input, pwrcdrv); /* Make sure the device is quiesced */ sirfsoc_pwrc_toggle_interrupts(pwrcdrv, false); irq = platform_get_irq(pdev, 0); error = devm_request_irq(&pdev->dev, irq, sirfsoc_pwrc_isr, 0, "sirfsoc_pwrc_int", pwrcdrv); if (error) { dev_err(&pdev->dev, "unable to claim irq %d, error: %d\n", irq, error); return error; } error = input_register_device(pwrcdrv->input); if (error) { dev_err(&pdev->dev, "unable to register input device, error: %d\n", error); return error; } dev_set_drvdata(&pdev->dev, pwrcdrv); device_init_wakeup(&pdev->dev, 1); return 0; }
int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, struct regmap *regmap, int (*tsc200x_cmd)(struct device *dev, u8 cmd)) { const struct tsc2005_platform_data *pdata = dev_get_platdata(dev); struct device_node *np = dev->of_node; struct tsc200x *ts; struct input_dev *input_dev; unsigned int max_x = MAX_12BIT; unsigned int max_y = MAX_12BIT; unsigned int max_p = MAX_12BIT; unsigned int fudge_x = TSC200X_DEF_X_FUZZ; unsigned int fudge_y = TSC200X_DEF_Y_FUZZ; unsigned int fudge_p = TSC200X_DEF_P_FUZZ; unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR; unsigned int esd_timeout; int error; if (!np && !pdata) { dev_err(dev, "no platform data\n"); return -ENODEV; } if (irq <= 0) { dev_err(dev, "no irq\n"); return -ENODEV; } if (IS_ERR(regmap)) return PTR_ERR(regmap); if (!tsc200x_cmd) { dev_err(dev, "no cmd function\n"); return -ENODEV; } if (pdata) { fudge_x = pdata->ts_x_fudge; fudge_y = pdata->ts_y_fudge; fudge_p = pdata->ts_pressure_fudge; max_x = pdata->ts_x_max; max_y = pdata->ts_y_max; max_p = pdata->ts_pressure_max; x_plate_ohm = pdata->ts_x_plate_ohm; esd_timeout = pdata->esd_timeout_ms; } else { x_plate_ohm = TSC200X_DEF_RESISTOR; of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm); esd_timeout = 0; of_property_read_u32(np, "ti,esd-recovery-timeout-ms", &esd_timeout); } ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; input_dev = devm_input_allocate_device(dev); if (!input_dev) return -ENOMEM; ts->irq = irq; ts->dev = dev; ts->idev = input_dev; ts->regmap = regmap; ts->tsc200x_cmd = tsc200x_cmd; ts->x_plate_ohm = x_plate_ohm; ts->esd_timeout = esd_timeout; ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ts->reset_gpio)) { error = PTR_ERR(ts->reset_gpio); dev_err(dev, "error acquiring reset gpio: %d\n", error); return error; } ts->vio = devm_regulator_get_optional(dev, "vio"); if (IS_ERR(ts->vio)) { error = PTR_ERR(ts->vio); dev_err(dev, "vio regulator missing (%d)", error); return error; } if (!ts->reset_gpio && pdata) ts->set_reset = pdata->set_reset; mutex_init(&ts->mutex); spin_lock_init(&ts->lock); setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts); INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work); snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts", dev_name(dev)); if (tsc_id->product == 2004) { input_dev->name = "TSC200X touchscreen"; } else { input_dev->name = devm_kasprintf(dev, GFP_KERNEL, "TSC%04d touchscreen", tsc_id->product); if (!input_dev->name) return -ENOMEM; } input_dev->phys = ts->phys; input_dev->id = *tsc_id; input_dev->dev.parent = dev; input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0); input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); if (np) touchscreen_parse_properties(input_dev, false, NULL); input_dev->open = tsc200x_open; input_dev->close = tsc200x_close; input_set_drvdata(input_dev, ts); /* Ensure the touchscreen is off */ tsc200x_stop_scan(ts); error = devm_request_threaded_irq(dev, irq, NULL, tsc200x_irq_thread, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tsc200x", ts); if (error) { dev_err(dev, "Failed to request irq, err: %d\n", error); return error; } /* enable regulator for DT */ if (ts->vio) { error = regulator_enable(ts->vio); if (error) return error; } dev_set_drvdata(dev, ts); error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group); if (error) { dev_err(dev, "Failed to create sysfs attributes, err: %d\n", error); goto disable_regulator; } error = input_register_device(ts->idev); if (error) { dev_err(dev, "Failed to register input device, err: %d\n", error); goto err_remove_sysfs; } irq_set_irq_wake(irq, 1); return 0; err_remove_sysfs: sysfs_remove_group(&dev->kobj, &tsc200x_attr_group); disable_regulator: if (ts->vio) regulator_disable(ts->vio); return error; }
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)); }
static int fpc1145_probe(struct spi_device *spi) { struct device *dev = &spi->dev; int rc = 0; size_t i; int irqf; struct device_node *np = dev->of_node; u32 val; const char *idev_name; struct fpc1145_data *fpc1145 = devm_kzalloc(dev, sizeof(*fpc1145), GFP_KERNEL); if (!fpc1145) { dev_err(dev, "failed to allocate memory for struct fpc1145_data\n"); rc = -ENOMEM; goto exit; } fpc1145->dev = dev; dev_set_drvdata(dev, fpc1145); fpc1145->spi = spi; if (!np) { dev_err(dev, "no of node found\n"); rc = -EINVAL; goto exit; } rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_irq", &fpc1145->irq_gpio); if (rc) goto exit; rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_cs0", &fpc1145->cs0_gpio); if (rc) goto exit; rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_cs1", &fpc1145->cs1_gpio); if (rc) goto exit; rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_rst", &fpc1145->rst_gpio); if (rc) goto exit; fpc1145->iface_clk = clk_get(dev, "iface_clk"); if (IS_ERR(fpc1145->iface_clk)) { dev_err(dev, "%s: Failed to get iface_clk\n", __func__); rc = -EINVAL; goto exit; } fpc1145->core_clk = clk_get(dev, "core_clk"); if (IS_ERR(fpc1145->core_clk)) { dev_err(dev, "%s: Failed to get core_clk\n", __func__); rc = -EINVAL; goto exit; } rc = of_property_read_u32(np, "spi-qup-id", &val); if (rc < 0) { dev_err(dev, "spi-qup-id not found\n"); goto exit; } fpc1145->qup_id = val; dev_dbg(dev, "spi-qup-id %d\n", fpc1145->qup_id); fpc1145->fingerprint_pinctrl = devm_pinctrl_get(dev); if (IS_ERR(fpc1145->fingerprint_pinctrl)) { if (PTR_ERR(fpc1145->fingerprint_pinctrl) == -EPROBE_DEFER) { dev_info(dev, "pinctrl not ready\n"); rc = -EPROBE_DEFER; goto exit; } dev_err(dev, "Target does not use pinctrl\n"); fpc1145->fingerprint_pinctrl = NULL; rc = -EINVAL; goto exit; } for (i = 0; i < ARRAY_SIZE(fpc1145->pinctrl_state); i++) { const char *n = pctl_names[i]; struct pinctrl_state *state = pinctrl_lookup_state(fpc1145->fingerprint_pinctrl, n); if (IS_ERR(state)) { dev_err(dev, "cannot find '%s'\n", n); rc = -EINVAL; goto exit; } dev_info(dev, "found pin control %s\n", n); fpc1145->pinctrl_state[i] = state; } rc = select_pin_ctl(fpc1145, "fpc1145_reset_reset"); if (rc) goto exit; rc = select_pin_ctl(fpc1145, "fpc1145_cs_low"); if (rc) goto exit; rc = select_pin_ctl(fpc1145, "fpc1145_irq_active"); if (rc) goto exit; rc = select_pin_ctl(fpc1145, "fpc1145_spi_active"); if (rc) goto exit; rc = of_property_read_u32(np, "fpc,event-type", &val); fpc1145->event_type = rc < 0 ? EV_MSC : val; rc = of_property_read_u32(np, "fpc,event-code", &val); fpc1145->event_code = rc < 0 ? MSC_SCAN : val; fpc1145->idev = devm_input_allocate_device(dev); if (!fpc1145->idev) { dev_err(dev, "failed to allocate input device\n"); rc = -ENOMEM; goto exit; } input_set_capability(fpc1145->idev, fpc1145->event_type, fpc1145->event_code); if (!of_property_read_string(np, "input-device-name", &idev_name)) { fpc1145->idev->name = idev_name; } else { snprintf(fpc1145->idev_name, sizeof(fpc1145->idev_name), "fpc1145@%s", dev_name(dev)); fpc1145->idev->name = fpc1145->idev_name; } rc = input_register_device(fpc1145->idev); if (rc) { dev_err(dev, "failed to register input device\n"); goto exit; } irqf = IRQF_TRIGGER_RISING | IRQF_ONESHOT; if (of_property_read_bool(dev->of_node, "fpc,enable-wakeup")) { irqf |= IRQF_NO_SUSPEND; device_init_wakeup(dev, 1); } mutex_init(&fpc1145->lock); rc = devm_request_threaded_irq(dev, gpio_to_irq(fpc1145->irq_gpio), NULL, fpc1145_irq_handler, irqf, dev_name(dev), fpc1145); if (rc) { dev_err(dev, "could not request irq %d\n", gpio_to_irq(fpc1145->irq_gpio)); goto exit; } dev_dbg(dev, "requested irq %d\n", gpio_to_irq(fpc1145->irq_gpio)); rc = sysfs_create_group(&dev->kobj, &attribute_group); if (rc) { dev_err(dev, "could not create sysfs\n"); goto exit; } if (of_property_read_bool(dev->of_node, "fpc,enable-on-boot")) { dev_info(dev, "Enabling hardware\n"); (void)device_prepare(fpc1145, true); } dev_info(dev, "%s: ok\n", __func__); exit: if (rc) mutex_destroy(&fpc1145->lock); return rc; }
static int sis_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct sis_ts_data *ts; struct input_dev *input; int error; ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; ts->client = client; ts->attn_gpio = devm_gpiod_get_optional(&client->dev, "attn", GPIOD_IN); if (IS_ERR(ts->attn_gpio)) { error = PTR_ERR(ts->attn_gpio); if (error != -EPROBE_DEFER) dev_err(&client->dev, "Failed to get attention GPIO: %d\n", error); return error; } ts->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ts->reset_gpio)) { error = PTR_ERR(ts->reset_gpio); if (error != -EPROBE_DEFER) dev_err(&client->dev, "Failed to get reset GPIO: %d\n", error); return error; } sis_ts_reset(ts); ts->input = input = devm_input_allocate_device(&client->dev); if (!input) { dev_err(&client->dev, "Failed to allocate input device\n"); return -ENOMEM; } input->name = "SiS Touchscreen"; input->id.bustype = BUS_I2C; input_set_abs_params(input, ABS_MT_POSITION_X, 0, SIS_MAX_X, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, SIS_MAX_Y, 0, 0); input_set_abs_params(input, ABS_MT_PRESSURE, 0, SIS_MAX_PRESSURE, 0, 0); input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, SIS_AREA_LENGTH_LONGER, 0, 0); input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, SIS_AREA_LENGTH_SHORT, 0, 0); error = input_mt_init_slots(input, SIS_MAX_FINGERS, INPUT_MT_DIRECT); if (error) { dev_err(&client->dev, "Failed to initialize MT slots: %d\n", error); return error; } error = devm_request_threaded_irq(&client->dev, client->irq, NULL, sis_ts_irq_handler, IRQF_ONESHOT, client->name, ts); if (error) { dev_err(&client->dev, "Failed to request IRQ: %d\n", error); return error; } error = input_register_device(ts->input); if (error) { dev_err(&client->dev, "Failed to register input device: %d\n", error); return error; } return 0; }
static int max77693_muic_probe(struct platform_device *pdev) { struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); struct max77693_muic_info *info; struct max77693_reg_data *init_data; int num_init_data; int delay_jiffies; int ret; int i; unsigned int id; info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->max77693 = max77693; if (info->max77693->regmap_muic) { dev_dbg(&pdev->dev, "allocate register map\n"); } else { info->max77693->regmap_muic = devm_regmap_init_i2c( info->max77693->i2c_muic, &max77693_muic_regmap_config); if (IS_ERR(info->max77693->regmap_muic)) { ret = PTR_ERR(info->max77693->regmap_muic); dev_err(max77693->dev, "failed to allocate register map: %d\n", ret); return ret; } } /* Register input device for button of dock device */ info->dock = devm_input_allocate_device(&pdev->dev); if (!info->dock) { dev_err(&pdev->dev, "%s: failed to allocate input\n", __func__); return -ENOMEM; } info->dock->name = "max77693-muic/dock"; info->dock->phys = "max77693-muic/extcon"; info->dock->dev.parent = &pdev->dev; __set_bit(EV_REP, info->dock->evbit); input_set_capability(info->dock, EV_KEY, KEY_VOLUMEUP); input_set_capability(info->dock, EV_KEY, KEY_VOLUMEDOWN); input_set_capability(info->dock, EV_KEY, KEY_PLAYPAUSE); input_set_capability(info->dock, EV_KEY, KEY_PREVIOUSSONG); input_set_capability(info->dock, EV_KEY, KEY_NEXTSONG); ret = input_register_device(info->dock); if (ret < 0) { dev_err(&pdev->dev, "Cannot register input device error(%d)\n", ret); return ret; } platform_set_drvdata(pdev, info); mutex_init(&info->mutex); INIT_WORK(&info->irq_work, max77693_muic_irq_work); /* Support irq domain for MAX77693 MUIC device */ for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) { struct max77693_muic_irq *muic_irq = &muic_irqs[i]; int virq; virq = regmap_irq_get_virq(max77693->irq_data_muic, muic_irq->irq); if (virq <= 0) return -EINVAL; muic_irq->virq = virq; ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, max77693_muic_irq_handler, IRQF_NO_SUSPEND, muic_irq->name, info); if (ret) { dev_err(&pdev->dev, "failed: irq request (IRQ: %d, error :%d)\n", muic_irq->irq, ret); return ret; } } /* Initialize extcon device */ info->edev = devm_extcon_dev_allocate(&pdev->dev, max77693_extcon_cable); if (IS_ERR(info->edev)) { dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); return -ENOMEM; } ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); return ret; } /* Initialize MUIC register by using platform data or default data */ if (pdata && pdata->muic_data) { init_data = pdata->muic_data->init_data; num_init_data = pdata->muic_data->num_init_data; } else { init_data = default_init_data; num_init_data = ARRAY_SIZE(default_init_data); } for (i = 0; i < num_init_data; i++) { regmap_write(info->max77693->regmap_muic, init_data[i].addr, init_data[i].data); } if (pdata && pdata->muic_data) { struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; /* * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB * h/w path of COMP2/COMN1 on CONTROL1 register. */ if (muic_pdata->path_uart) info->path_uart = muic_pdata->path_uart; else info->path_uart = MAX77693_CONTROL1_SW_UART; if (muic_pdata->path_usb) info->path_usb = muic_pdata->path_usb; else info->path_usb = MAX77693_CONTROL1_SW_USB; /* * Default delay time for detecting cable state * after certain time. */ if (muic_pdata->detcable_delay_ms) delay_jiffies = msecs_to_jiffies(muic_pdata->detcable_delay_ms); else delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); } else { info->path_usb = MAX77693_CONTROL1_SW_USB; info->path_uart = MAX77693_CONTROL1_SW_UART; delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); } /* Set initial path for UART */ max77693_muic_set_path(info, info->path_uart, true); /* Check revision number of MUIC device*/ ret = regmap_read(info->max77693->regmap_muic, MAX77693_MUIC_REG_ID, &id); if (ret < 0) { dev_err(&pdev->dev, "failed to read revision number\n"); return ret; } dev_info(info->dev, "device ID : 0x%x\n", id); /* Set ADC debounce time */ max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); /* * Detect accessory after completing the initialization of platform * * - Use delayed workqueue to detect cable state and then * notify cable state to notifiee/platform through uevent. * After completing the booting of platform, the extcon provider * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq); queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, delay_jiffies); return ret; }
static int sun4i_ts_probe(struct platform_device *pdev) { struct sun4i_ts_data *ts; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device *hwmon; int error; u32 reg; bool ts_attached; u32 tp_sensitive_adjust = 15; u32 filter_type = 1; ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); if (!ts) return -ENOMEM; ts->dev = dev; ts->ignore_fifo_data = true; ts->temp_data = -1; if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) { /* Allwinner SDK has temperature (C) = (value / 6) - 271 */ ts->temp_offset = 271000; ts->temp_step = 167; } else if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) { /* * The A10 temperature sensor has quite a wide spread, these * parameters are based on the averaging of the calibration * results of 4 completely different boards, with a spread of * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331. */ ts->temp_offset = 257000; ts->temp_step = 133; } else { /* * The user manuals do not contain the formula for calculating * the temperature. The formula used here is from the AXP209, * which is designed by X-Powers, an affiliate of Allwinner: * * temperature (C) = (value * 0.1) - 144.7 * * Allwinner does not have any documentation whatsoever for * this hardware. Moreover, it is claimed that the sensor * is inaccurate and cannot work properly. */ ts->temp_offset = 144700; ts->temp_step = 100; } ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); if (ts_attached) { ts->input = devm_input_allocate_device(dev); if (!ts->input) return -ENOMEM; ts->input->name = pdev->name; ts->input->phys = "sun4i_ts/input0"; ts->input->open = sun4i_ts_open; ts->input->close = sun4i_ts_close; ts->input->id.bustype = BUS_HOST; ts->input->id.vendor = 0x0001; ts->input->id.product = 0x0001; ts->input->id.version = 0x0100; ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); __set_bit(BTN_TOUCH, ts->input->keybit); input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); input_set_drvdata(ts->input, ts); } ts->base = devm_ioremap_resource(dev, platform_get_resource(pdev, IORESOURCE_MEM, 0)); if (IS_ERR(ts->base)) return PTR_ERR(ts->base); ts->irq = platform_get_irq(pdev, 0); error = devm_request_irq(dev, ts->irq, sun4i_ts_irq, 0, "sun4i-ts", ts); if (error) return error; /* * Select HOSC clk, clkin = clk / 6, adc samplefreq = clkin / 8192, * t_acq = clkin / (16 * 64) */ writel(ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63), ts->base + TP_CTRL0); /* * tp_sensitive_adjust is an optional property * tp_mode = 0 : only x and y coordinates, as we don't use dual touch */ of_property_read_u32(np, "allwinner,tp-sensitive-adjust", &tp_sensitive_adjust); writel(TP_SENSITIVE_ADJUST(tp_sensitive_adjust) | TP_MODE_SELECT(0), ts->base + TP_CTRL2); /* * Enable median and averaging filter, optional property for * filter type. */ of_property_read_u32(np, "allwinner,filter-type", &filter_type); writel(FILTER_EN(1) | FILTER_TYPE(filter_type), ts->base + TP_CTRL3); /* Enable temperature measurement, period 1953 (2 seconds) */ writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR); /* * Set stylus up debounce to aprox 10 ms, enable debounce, and * finally enable tp mode. */ reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1); if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) reg |= SUN6I_TP_MODE_EN(1); else reg |= TP_MODE_EN(1); writel(reg, ts->base + TP_CTRL1); /* * The thermal core does not register hwmon devices for DT-based * thermal zone sensors, such as this one. */ hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", ts, sun4i_ts_groups); if (IS_ERR(hwmon)) return PTR_ERR(hwmon); devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, &sun4i_ts_tz_ops); writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); if (ts_attached) { error = input_register_device(ts->input); if (error) { writel(0, ts->base + TP_INT_FIFOC); return error; } } platform_set_drvdata(pdev, ts); return 0; }