Ejemplo n.º 1
0
static int uinput_create_device(struct uinput_device *udev)
{
	struct input_dev *dev = udev->dev;
	int error;

	if (udev->state != UIST_SETUP_COMPLETE) {
		printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
		return -EINVAL;
	}

	if (udev->ff_effects_max) {
		error = input_ff_create(dev, udev->ff_effects_max);
		if (error)
			goto fail1;

		dev->ff->upload = uinput_dev_upload_effect;
		dev->ff->erase = uinput_dev_erase_effect;
		dev->ff->playback = uinput_dev_playback;
		dev->ff->set_gain = uinput_dev_set_gain;
		dev->ff->set_autocenter = uinput_dev_set_autocenter;
	}

	error = input_register_device(udev->dev);
	if (error)
		goto fail2;

	udev->state = UIST_CREATED;

	return 0;

 fail2:	input_ff_destroy(dev);
 fail1: uinput_destroy_device(udev);
	return error;
}
static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
{
	struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
	struct vibra_info *info;
	int ret;

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = &pdev->dev;
	info->coexist = pdata->coexist;
	INIT_WORK(&info->play_work, vibra_play_work);

	info->input_dev = input_allocate_device();
	if (info->input_dev == NULL) {
		dev_err(&pdev->dev, "couldn't allocate input device\n");
		ret = -ENOMEM;
		goto err_kzalloc;
	}

	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->open = twl4030_vibra_open;
	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");
		goto err_ialloc;
	}

	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);
err_ialloc:
	input_free_device(info->input_dev);
err_kzalloc:
	kfree(info);
	return ret;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
Archivo: xpad.c Proyecto: 19Dan01/linux
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_xpad *xpad;
	struct input_dev *input_dev;
	struct usb_endpoint_descriptor *ep_irq_in;
	int ep_irq_in_idx;
	int i, error;

	for (i = 0; xpad_device[i].idVendor; i++) {
		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
			break;
	}

	if (xpad_device[i].xtype == XTYPE_XBOXONE &&
	    intf->cur_altsetting->desc.bInterfaceNumber != 0) {
		/*
		 * The Xbox One controller lists three interfaces all with the
		 * same interface class, subclass and protocol. Differentiate by
		 * interface number.
		 */
		return -ENODEV;
	}

	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!xpad || !input_dev) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
					 GFP_KERNEL, &xpad->idata_dma);
	if (!xpad->idata) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!xpad->irq_in) {
		error = -ENOMEM;
		goto fail2;
	}

	xpad->udev = udev;
	xpad->intf = intf;
	xpad->mapping = xpad_device[i].mapping;
	xpad->xtype = xpad_device[i].xtype;

	if (xpad->xtype == XTYPE_UNKNOWN) {
		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
				xpad->xtype = XTYPE_XBOX360W;
			else
				xpad->xtype = XTYPE_XBOX360;
		} else
			xpad->xtype = XTYPE_XBOX;

		if (dpad_to_buttons)
			xpad->mapping |= MAP_DPAD_TO_BUTTONS;
		if (triggers_to_buttons)
			xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
		if (sticks_to_null)
			xpad->mapping |= MAP_STICKS_TO_NULL;
	}

	xpad->dev = input_dev;
	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));

	input_dev->name = xpad_device[i].name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);

	if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
		input_dev->evbit[0] |= BIT_MASK(EV_ABS);
		/* set up axes */
		for (i = 0; xpad_abs[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs[i]);
	}

	/* set up standard buttons */
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		__set_bit(xpad_common_btn[i], input_dev->keybit);

	/* set up model-specific ones */
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W ||
	    xpad->xtype == XTYPE_XBOXONE) {
		for (i = 0; xpad360_btn[i] >= 0; i++)
			__set_bit(xpad360_btn[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_btn[i] >= 0; i++)
			__set_bit(xpad_btn[i], input_dev->keybit);
	}

	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			__set_bit(xpad_btn_pad[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
	}

	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
	}

	error = xpad_init_output(intf, xpad);
	if (error)
		goto fail3;

	error = xpad_init_ff(xpad);
	if (error)
		goto fail4;

	error = xpad_led_probe(xpad);
	if (error)
		goto fail5;

	/* Xbox One controller has in/out endpoints swapped. */
	ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
	ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;

	usb_fill_int_urb(xpad->irq_in, udev,
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
			 xpad, ep_irq_in->bInterval);
	xpad->irq_in->transfer_dma = xpad->idata_dma;
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	error = input_register_device(xpad->dev);
	if (error)
		goto fail6;

	usb_set_intfdata(intf, xpad);

	if (xpad->xtype == XTYPE_XBOX360W) {
		/*
		 * Setup the message to set the LEDs on the
		 * controller when it shows up
		 */
		xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
		if (!xpad->bulk_out) {
			error = -ENOMEM;
			goto fail7;
		}

		xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
		if (!xpad->bdata) {
			error = -ENOMEM;
			goto fail8;
		}

		xpad->bdata[2] = 0x08;
		switch (intf->cur_altsetting->desc.bInterfaceNumber) {
		case 0:
			xpad->bdata[3] = 0x42;
			break;
		case 2:
			xpad->bdata[3] = 0x43;
			break;
		case 4:
			xpad->bdata[3] = 0x44;
			break;
		case 6:
			xpad->bdata[3] = 0x45;
		}

		ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
		if (usb_endpoint_is_bulk_out(ep_irq_in)) {
			usb_fill_bulk_urb(xpad->bulk_out, udev,
					  usb_sndbulkpipe(udev,
							  ep_irq_in->bEndpointAddress),
					  xpad->bdata, XPAD_PKT_LEN,
					  xpad_bulk_out, xpad);
		} else {
			usb_fill_int_urb(xpad->bulk_out, udev,
					 usb_sndintpipe(udev,
							ep_irq_in->bEndpointAddress),
					 xpad->bdata, XPAD_PKT_LEN,
					 xpad_bulk_out, xpad, 0);
		}

		/*
		 * Submit the int URB immediately rather than waiting for open
		 * because we get status messages from the device whether
		 * or not any controllers are attached.  In fact, it's
		 * exactly the message that a controller has arrived that
		 * we're waiting for.
		 */
		xpad->irq_in->dev = xpad->udev;
		error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
		if (error)
			goto fail9;
	}

	return 0;

 fail9:	kfree(xpad->bdata);
 fail8:	usb_free_urb(xpad->bulk_out);
 fail7:	input_unregister_device(input_dev);
	input_dev = NULL;
 fail6:	xpad_led_disconnect(xpad);
 fail5:	if (input_dev)
		input_ff_destroy(input_dev);
 fail4:	xpad_deinit_output(xpad);
 fail3:	usb_free_urb(xpad->irq_in);
 fail2:	usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 fail1:	input_free_device(input_dev);
	kfree(xpad);
	return error;

}
Ejemplo n.º 5
0
static int xpad_init_input(struct usb_xpad *xpad)
{
	struct input_dev *input_dev;
	int i, error;

	input_dev = input_allocate_device();
	if (!input_dev)
		return -ENOMEM;

	xpad->dev = input_dev;
	input_dev->name = xpad->name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(xpad->udev, &input_dev->id);
	input_dev->dev.parent = &xpad->intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	__set_bit(EV_KEY, input_dev->evbit);

	if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
		__set_bit(EV_ABS, input_dev->evbit);
		/* set up axes */
		for (i = 0; xpad_abs[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs[i]);
	}

	/* set up standard buttons */
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		__set_bit(xpad_common_btn[i], input_dev->keybit);

	/* set up model-specific ones */
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W ||
	    xpad->xtype == XTYPE_XBOXONE) {
		for (i = 0; xpad360_btn[i] >= 0; i++)
			__set_bit(xpad360_btn[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_btn[i] >= 0; i++)
			__set_bit(xpad_btn[i], input_dev->keybit);
	}

	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			__set_bit(xpad_btn_pad[i], input_dev->keybit);
	}

	/*
	 * This should be a simple else block. However historically
	 * xbox360w has mapped DPAD to buttons while xbox360 did not. This
	 * made no sense, but now we can not just switch back and have to
	 * support both behaviors.
	 */
	if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) ||
	    xpad->xtype == XTYPE_XBOX360W) {
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
	}

	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
	}

	error = xpad_init_ff(xpad);
	if (error)
		goto err_free_input;

	error = xpad_led_probe(xpad);
	if (error)
		goto err_destroy_ff;

	error = input_register_device(xpad->dev);
	if (error)
		goto err_disconnect_led;

	return 0;

err_disconnect_led:
	xpad_led_disconnect(xpad);
err_destroy_ff:
	input_ff_destroy(input_dev);
err_free_input:
	input_free_device(input_dev);
	return error;
}
Ejemplo n.º 6
0
static int max77660_haptic_probe(struct platform_device *pdev)
{
	/* we register the parent platform data */
	struct max77660_platform_data *parent_pdata;
	struct max77660_haptic_platform_data *haptic_pdata;
	struct max77660_haptic *chip;
	struct input_dev *input_dev;
	int ret;

	parent_pdata = dev_get_platdata(pdev->dev.parent);
	if (!parent_pdata) {
		dev_err(&pdev->dev, "no haptic parent platform data\n");
		return -EINVAL;
	}
	if ((!parent_pdata->haptic_pdata) ||
		!parent_pdata->haptic_pdata->pdata) {
		dev_err(&pdev->dev, "no haptic platform data\n");
		return -EINVAL;
	}
	haptic_pdata = parent_pdata->haptic_pdata->pdata;

	chip = devm_kzalloc(&pdev->dev, sizeof(struct max77660_haptic),
							GFP_KERNEL);
	if (!chip) {
		dev_err(&pdev->dev, "unable to allocate memory\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev,
			"unable to allocate memory for input dev\n");
		ret = -ENOMEM;
		goto err_input_alloc;
	}

	chip->dev = &pdev->dev;
	chip->input_dev = input_dev;
	chip->type = haptic_pdata->type;
	chip->mode = haptic_pdata->mode;

	if (chip->mode == MAX77660_INTERNAL_MODE) {
		chip->internal_mode_pattern =
				haptic_pdata->internal_mode_pattern;
		chip->pattern_cycle = haptic_pdata->pattern_cycle;
		chip->pattern_signal_period =
				haptic_pdata->pattern_signal_period;
		chip->feedback_duty_cycle =
				haptic_pdata->feedback_duty_cycle;
		chip->invert = haptic_pdata->invert;
		chip->cont_mode = haptic_pdata->cont_mode;
		chip->motor_startup_val = haptic_pdata->motor_startup_val;
		chip->scf_val = haptic_pdata->scf_val;
	}

	if (chip->mode == MAX77660_EXTERNAL_MODE) {
		chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
					"max-vbrtr");
		if (IS_ERR(chip->pwm)) {
			dev_err(&pdev->dev,
				"unable to request PWM for haptic\n");
			ret = PTR_ERR(chip->pwm);
			goto err_pwm;
		}
	}

	chip->regulator = regulator_get(&pdev->dev, "vdd_vbrtr");
	if (IS_ERR(chip->regulator)) {
		dev_err(&pdev->dev, "unable to get regulator\n");
		ret = PTR_ERR(chip->regulator);
		goto err_regulator;
	}

register_input:
	dev_set_drvdata(&pdev->dev, chip);
	input_dev->name = MAX77660_HAPTIC_DRIVER_MATCHED_NAME;
	input_dev->id.version = 1;
	input_dev->dev.parent = &pdev->dev;
	input_set_drvdata(input_dev, chip);
	input_set_capability(input_dev, EV_FF, FF_RUMBLE);

	ret = input_ff_create_memless(input_dev, NULL,
				max77660_haptic_play_effect);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to create FF device(ret : %d)\n", ret);
		goto err_ff_memless;
	}
	INIT_WORK(&chip->work,
			max77660_haptic_play_effect_work);

	ret = input_register_device(input_dev);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to register input device(ret : %d)\n", ret);
		goto err_input_register;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &max77660_haptics_attr_group);
	if (ret < 0)
		dev_err(&pdev->dev,
			"unable to create sysfs %d\n", ret);

	return 0;

err_input_register:
	destroy_work_on_stack(&chip->work);
	input_ff_destroy(input_dev);
err_ff_memless:
	regulator_put(chip->regulator);
err_regulator:
	if (chip->mode == MAX77660_EXTERNAL_MODE)
		pwm_free(chip->pwm);
err_pwm:
	input_free_device(input_dev);
err_input_alloc:

	dev_err(&pdev->dev, "Error: %s return ret=%d\n", __func__, ret);
	return ret;
}
static int __devinit max8997_haptic_probe(struct platform_device *pdev)
{
	struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
	const struct max8997_platform_data *pdata =
					dev_get_platdata(iodev->dev);
	const struct max8997_haptic_platform_data *haptic_pdata =
					pdata->haptic_pdata;
	struct max8997_haptic *chip;
	struct input_dev *input_dev;
	int error;

	if (!haptic_pdata) {
		dev_err(&pdev->dev, "no haptic platform data\n");
		return -EINVAL;
	}

	chip = kzalloc(sizeof(struct max8997_haptic), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!chip || !input_dev) {
		dev_err(&pdev->dev, "unable to allocate memory\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	INIT_WORK(&chip->work, max8997_haptic_play_effect_work);
	mutex_init(&chip->mutex);

	chip->client = iodev->haptic;
	chip->dev = &pdev->dev;
	chip->input_dev = input_dev;
	chip->pwm_period = haptic_pdata->pwm_period;
	chip->type = haptic_pdata->type;
	chip->mode = haptic_pdata->mode;
	chip->pwm_divisor = haptic_pdata->pwm_divisor;

	switch (chip->mode) {
	case MAX8997_INTERNAL_MODE:
		chip->internal_mode_pattern =
				haptic_pdata->internal_mode_pattern;
		chip->pattern_cycle = haptic_pdata->pattern_cycle;
		chip->pattern_signal_period =
				haptic_pdata->pattern_signal_period;
		break;

	case MAX8997_EXTERNAL_MODE:
		chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
					"max8997-haptic");
		if (IS_ERR(chip->pwm)) {
			error = PTR_ERR(chip->pwm);
			dev_err(&pdev->dev,
				"unable to request PWM for haptic, error: %d\n",
				error);
			goto err_free_mem;
		}
		break;

	default:
		dev_err(&pdev->dev,
			"Invalid chip mode specified (%d)\n", chip->mode);
		error = -EINVAL;
		goto err_free_mem;
	}

	chip->regulator = regulator_get(&pdev->dev, "inmotor");
	if (IS_ERR(chip->regulator)) {
		error = PTR_ERR(chip->regulator);
		dev_err(&pdev->dev,
			"unable to get regulator, error: %d\n",
			error);
		goto err_free_pwm;
	}

	input_dev->name = "max8997-haptic";
	input_dev->id.version = 1;
	input_dev->dev.parent = &pdev->dev;
	input_dev->close = max8997_haptic_close;
	input_set_drvdata(input_dev, chip);
	input_set_capability(input_dev, EV_FF, FF_RUMBLE);

	error = input_ff_create_memless(input_dev, NULL,
				max8997_haptic_play_effect);
	if (error) {
		dev_err(&pdev->dev,
			"unable to create FF device, error: %d\n",
			error);
		goto err_put_regulator;
	}

	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev,
			"unable to register input device, error: %d\n",
			error);
		goto err_destroy_ff;
	}

	platform_set_drvdata(pdev, chip);
	return 0;

err_destroy_ff:
	input_ff_destroy(input_dev);
err_put_regulator:
	regulator_put(chip->regulator);
err_free_pwm:
	if (chip->mode == MAX8997_EXTERNAL_MODE)
		pwm_free(chip->pwm);
err_free_mem:
	input_free_device(input_dev);
	kfree(chip);

	return error;
}
Ejemplo n.º 8
0
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_xpad *xpad;
	struct input_dev *input_dev;
	struct usb_endpoint_descriptor *ep_irq_in;
	int i, error;

	for (i = 0; xpad_device[i].idVendor; i++) {
		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
			break;
	}

	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!xpad || !input_dev) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
					 GFP_KERNEL, &xpad->idata_dma);
	if (!xpad->idata) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!xpad->irq_in) {
		error = -ENOMEM;
		goto fail2;
	}

	xpad->udev = udev;
	xpad->mapping = xpad_device[i].mapping;
	xpad->xtype = xpad_device[i].xtype;

	if (xpad->xtype == XTYPE_UNKNOWN) {
		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
				xpad->xtype = XTYPE_XBOX360W;
			else
				xpad->xtype = XTYPE_XBOX360;
		} else
			xpad->xtype = XTYPE_XBOX;

		if (dpad_to_buttons)
			xpad->mapping |= MAP_DPAD_TO_BUTTONS;
		if (triggers_to_buttons)
			xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
		if (sticks_to_null)
			xpad->mapping |= MAP_STICKS_TO_NULL;
	}

	xpad->dev = input_dev;
	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));

	input_dev->name = xpad_device[i].name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);

	if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
		input_dev->evbit[0] |= BIT_MASK(EV_ABS);
		
		for (i = 0; xpad_abs[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs[i]);
	}

	
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		__set_bit(xpad_common_btn[i], input_dev->keybit);

	
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
		for (i = 0; xpad360_btn[i] >= 0; i++)
			__set_bit(xpad360_btn[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_btn[i] >= 0; i++)
			__set_bit(xpad_btn[i], input_dev->keybit);
	}

	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			__set_bit(xpad_btn_pad[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
		    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
	}

	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
	}

	error = xpad_init_output(intf, xpad);
	if (error)
		goto fail3;

	error = xpad_init_ff(xpad);
	if (error)
		goto fail4;

	error = xpad_led_probe(xpad);
	if (error)
		goto fail5;

	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
	usb_fill_int_urb(xpad->irq_in, udev,
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
			 xpad, ep_irq_in->bInterval);
	xpad->irq_in->transfer_dma = xpad->idata_dma;
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	error = input_register_device(xpad->dev);
	if (error)
		goto fail6;

	usb_set_intfdata(intf, xpad);

	if (xpad->xtype == XTYPE_XBOX360W) {
		xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
		if (!xpad->bulk_out) {
			error = -ENOMEM;
			goto fail7;
		}

		xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
		if (!xpad->bdata) {
			error = -ENOMEM;
			goto fail8;
		}

		xpad->bdata[2] = 0x08;
		switch (intf->cur_altsetting->desc.bInterfaceNumber) {
		case 0:
			xpad->bdata[3] = 0x42;
			break;
		case 2:
			xpad->bdata[3] = 0x43;
			break;
		case 4:
			xpad->bdata[3] = 0x44;
			break;
		case 6:
			xpad->bdata[3] = 0x45;
		}

		ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
		usb_fill_bulk_urb(xpad->bulk_out, udev,
				usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
				xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);

		xpad->irq_in->dev = xpad->udev;
		error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
		if (error)
			goto fail9;
	}

	return 0;

 fail9:	kfree(xpad->bdata);
 fail8:	usb_free_urb(xpad->bulk_out);
 fail7:	input_unregister_device(input_dev);
	input_dev = NULL;
 fail6:	xpad_led_disconnect(xpad);
 fail5:	if (input_dev)
		input_ff_destroy(input_dev);
 fail4:	xpad_deinit_output(xpad);
 fail3:	usb_free_urb(xpad->irq_in);
 fail2:	usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 fail1:	input_free_device(input_dev);
	kfree(xpad);
	return error;

}
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	struct pm8xxx_vib *vib;
	struct input_dev *input_dev;
	int error;
	u8 val;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!vib || !input_dev) {
		dev_err(&pdev->dev, "couldn't allocate memory\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	INIT_WORK(&vib->work, pm8xxx_work_handler);
	vib->dev = &pdev->dev;
	vib->vib_input_dev = input_dev;

	
	error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (error < 0)
		goto err_free_mem;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
	if (error < 0)
		goto err_free_mem;

	vib->reg_vib_drv = val;

	input_dev->name = "pm8xxx_vib_ffmemless";
	input_dev->id.version = 1;
	input_dev->dev.parent = &pdev->dev;
	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");
		goto err_free_mem;
	}

	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "couldn't register input device\n");
		goto err_destroy_memless;
	}

	platform_set_drvdata(pdev, vib);
	return 0;

err_destroy_memless:
	input_ff_destroy(input_dev);
err_free_mem:
	input_free_device(input_dev);
	kfree(vib);

	return error;
}
Ejemplo n.º 10
0
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_xpad *xpad;
	struct input_dev *input_dev;
	struct usb_endpoint_descriptor *ep_irq_in;
	int i, error;

	for (i = 0; xpad_device[i].idVendor; i++) {
		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
			break;
	}

	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!xpad || !input_dev) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
					 GFP_KERNEL, &xpad->idata_dma);
	if (!xpad->idata) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!xpad->irq_in) {
		error = -ENOMEM;
		goto fail2;
	}

	xpad->udev = udev;
	xpad->mapping = xpad_device[i].mapping;
	xpad->xtype = xpad_device[i].xtype;

	if (xpad->xtype == XTYPE_UNKNOWN) {
		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
				xpad->xtype = XTYPE_XBOX360W;
			else
				xpad->xtype = XTYPE_XBOX360;
		} else
			xpad->xtype = XTYPE_XBOX;

		if (dpad_to_buttons)
			xpad->mapping |= MAP_DPAD_TO_BUTTONS;
		if (triggers_to_buttons)
			xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
		if (sticks_to_null)
			xpad->mapping |= MAP_STICKS_TO_NULL;
	}

	xpad->dev = input_dev;
	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));

	input_dev->name = xpad_device[i].name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);

	if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
		input_dev->evbit[0] |= BIT_MASK(EV_ABS);
		/* set up axes */
		for (i = 0; xpad_abs[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs[i]);
	}

	/* set up standard buttons */
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		__set_bit(xpad_common_btn[i], input_dev->keybit);

	/* set up model-specific ones */
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
		for (i = 0; xpad360_btn[i] >= 0; i++)
			__set_bit(xpad360_btn[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_btn[i] >= 0; i++)
			__set_bit(xpad_btn[i], input_dev->keybit);
	}

	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			__set_bit(xpad_btn_pad[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
		    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
	}

	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
	}

	error = xpad_init_output(intf, xpad);
	if (error)
		goto fail3;

	error = xpad_init_ff(xpad);
	if (error)
		goto fail4;

	error = xpad_led_probe(xpad);
	if (error)
		goto fail5;

	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
	usb_fill_int_urb(xpad->irq_in, udev,
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
			 xpad, ep_irq_in->bInterval);
	xpad->irq_in->transfer_dma = xpad->idata_dma;
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	INIT_WORK(&xpad->submit_urb, xpad_do_submit_urb);

	error = input_register_device(xpad->dev);
	if (error)
		goto fail6;

	usb_set_intfdata(intf, xpad);

	xpad->interface_number = intf->cur_altsetting->desc.bInterfaceNumber;

	/*
	 * Submit the int URB immediately rather than waiting for open
	 * because we get status messages from the device whether
	 * or not any controllers are attached.  In fact, it's
	 * exactly the message that a controller has arrived that
	 * we're waiting for.
	 */
	if (xpad->xtype == XTYPE_XBOX360W) {
		xpad->irq_in->dev = xpad->udev;
		error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
		if (error)
			goto fail7;
	}

	return 0;

 fail7:	input_unregister_device(input_dev);
	input_dev = NULL;
 fail6:	xpad_led_disconnect(xpad);
 fail5:	if (input_dev)
		input_ff_destroy(input_dev);
 fail4:	xpad_deinit_output(xpad);
 fail3:	cancel_work_sync(&xpad->submit_urb);
	usb_free_urb(xpad->irq_in);
 fail2:	usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 fail1:	input_free_device(input_dev);
	kfree(xpad);
	return error;

}
Ejemplo n.º 11
0
static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
{
	struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
	struct vibra_info *info;
	int ret;

	if (!pdata) {
		dev_err(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		dev_err(&pdev->dev, "couldn't allocate memory\n");
		return -ENOMEM;
	}

	info->dev = &pdev->dev;
	info->twl6040 = dev_get_drvdata(pdev->dev.parent);
	info->vibldrv_res = pdata->vibldrv_res;
	info->vibrdrv_res = pdata->vibrdrv_res;
	info->viblmotor_res = pdata->viblmotor_res;
	info->vibrmotor_res = pdata->vibrmotor_res;
	if ((!info->vibldrv_res && !info->viblmotor_res) ||
	    (!info->vibrdrv_res && !info->vibrmotor_res)) {
		dev_err(info->dev, "invalid vibra driver/motor resistance\n");
		ret = -EINVAL;
		goto err_kzalloc;
	}

	info->irq = platform_get_irq(pdev, 0);
	if (info->irq < 0) {
		dev_err(info->dev, "invalid irq\n");
		ret = -EINVAL;
		goto err_kzalloc;
	}

	mutex_init(&info->mutex);

	info->input_dev = input_allocate_device();
	if (info->input_dev == NULL) {
		dev_err(info->dev, "couldn't allocate input device\n");
		ret = -ENOMEM;
		goto err_kzalloc;
	}

	input_set_drvdata(info->input_dev, info);

	info->input_dev->name = "twl6040:vibrator";
	info->input_dev->id.version = 1;
	info->input_dev->dev.parent = pdev->dev.parent;
	info->input_dev->close = twl6040_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_err(info->dev, "couldn't register vibrator to FF\n");
		goto err_ialloc;
	}

	ret = input_register_device(info->input_dev);
	if (ret < 0) {
		dev_err(info->dev, "couldn't register input device\n");
		goto err_iff;
	}

	platform_set_drvdata(pdev, info);

	ret = request_threaded_irq(info->irq, NULL, twl6040_vib_irq_handler, 0,
				   "twl6040_irq_vib", info);
	if (ret) {
		dev_err(info->dev, "VIB IRQ request failed: %d\n", ret);
		goto err_irq;
	}

	info->supplies[0].supply = "vddvibl";
	info->supplies[1].supply = "vddvibr";
	ret = regulator_bulk_get(info->dev, ARRAY_SIZE(info->supplies),
				 info->supplies);
	if (ret) {
		dev_err(info->dev, "couldn't get regulators %d\n", ret);
		goto err_regulator;
	}

	if (pdata->vddvibl_uV) {
		ret = regulator_set_voltage(info->supplies[0].consumer,
					    pdata->vddvibl_uV,
					    pdata->vddvibl_uV);
		if (ret) {
			dev_err(info->dev, "failed to set VDDVIBL volt %d\n",
				ret);
			goto err_voltage;
		}
	}

	if (pdata->vddvibr_uV) {
		ret = regulator_set_voltage(info->supplies[1].consumer,
					    pdata->vddvibr_uV,
					    pdata->vddvibr_uV);
		if (ret) {
			dev_err(info->dev, "failed to set VDDVIBR volt %d\n",
				ret);
			goto err_voltage;
		}
	}

	info->workqueue = alloc_workqueue("twl6040-vibra", 0, 0);
	if (info->workqueue == NULL) {
		dev_err(info->dev, "couldn't create workqueue\n");
		ret = -ENOMEM;
		goto err_voltage;
	}
	INIT_WORK(&info->play_work, vibra_play_work);

	return 0;

err_voltage:
	regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies);
err_regulator:
	free_irq(info->irq, info);
err_irq:
	input_unregister_device(info->input_dev);
	info->input_dev = NULL;
err_iff:
	if (info->input_dev)
		input_ff_destroy(info->input_dev);
err_ialloc:
	input_free_device(info->input_dev);
err_kzalloc:
	kfree(info);
	return ret;
}
static int __devinit pmic8058_vib_probe(struct platform_device *pdev)

{
	struct pmic8058_vibrator_pdata *pdata = pdev->dev.platform_data;
	struct pmic8058_vib *vib;
	u8 val;
	int rc;

	struct pm8058_chip	*pm_chip;

	pm_chip = dev_get_drvdata(pdev->parent.dev);
	if (pm_chip == NULL) {
		dev_err(&pdev->dev, "no parent data passed in\n");
		return -EFAULT;
	}

	if (!pdata)
		return -EINVAL;

	if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
			 pdata->level_mV > VIB_MAX_LEVEL_mV)
		return -EINVAL;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->pm_chip	= pm_chip;
	vib->enabled	= 0;
	vib->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, pmic8058_work_handler);

	vib->info = input_allocate_device();

	if (vib->info == NULL) {
		dev_err(&pdev->dev, "couldn't allocate input device\n");
		return -ENOMEM;
	}

	input_set_drvdata(vib->info, vib);

	vib->info->name = "pmic8058:vibrator";
	vib->info->id.version = 1;
	vib->info->dev.parent = pdev->dev.parent;

	__set_bit(FF_RUMBLE, vib->info->ffbit);
	__dump_vib_regs(vib, "boot_vib_default");

	/*                        */
	rc = pmic8058_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pmic8058_vib_write_u8(vib, val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;

	vib->reg_vib_drv = val;

	rc = input_ff_create_memless(vib->info, NULL, pmic8058_vib_play_effect);
	if (rc < 0) {
		dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
		goto create_memless_err;
	}

	platform_set_drvdata(pdev, vib);

	rc = input_register_device(vib->info);
	if (rc < 0) {
		dev_dbg(&pdev->dev, "couldn't register input device\n");
		goto reg_err;
	}

	return 0;

reg_err:
	input_ff_destroy(vib->info);
create_memless_err:
	input_free_device(vib->info);
err_read_vib:
	kfree(vib);
	return rc;
}
Ejemplo n.º 13
0
static int regulator_haptic_probe(struct platform_device *pdev)
{
    struct regulator_haptic *haptic;
    struct input_dev *input_dev;
    char *select_regulator_name;
    int error;

    haptic = kzalloc(sizeof(*haptic), GFP_KERNEL);
    if (!haptic) {
        printk("regulator-haptic : unable to allocate memory for haptic\n");
        return -ENOMEM;
    }

    input_dev = input_allocate_device();
    if (!input_dev) {
        printk("regulator-haptic : unalbe to allocate memory\n");
        error =  -ENOMEM;
        goto err_kfree_mem;
    }

    INIT_WORK(&haptic->work, regulator_haptic_work);
    mutex_init(&haptic->mutex);
    haptic->input_dev = input_dev;
    haptic->dev = &pdev->dev;
    select_regulator_name = get_regulator_name();


    if(!strcmp(select_regulator_name, ERROR_NAME)) {
        pr_info("%s : error regulator_name\n", __func__);
        error = -ENOMEM;
        goto err_kfree_mem;
    }

    haptic->regulator = regulator_get(&pdev->dev, select_regulator_name);
    if (IS_ERR(haptic->regulator)) {
        error = PTR_ERR(haptic->regulator);
        printk("regulator-haptic : unable to get regulator, err : %d\n", error);
        goto err_ifree_mem;
    }
    set_haptic_data(haptic);
    haptic->input_dev->name = "regulator-haptic";
    haptic->input_dev->dev.parent = &pdev->dev;
    haptic->input_dev->close = regulator_haptic_close;
    haptic->enabled = false;
    input_set_drvdata(haptic->input_dev, haptic);
    input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);

    error = input_ff_create_memless(input_dev, NULL,
                                    regulator_haptic_play);
    if (error) {
        printk("regulator-haptic : input_ff_create_memless() failed : %d\n", error);
        goto err_put_regulator;
    }
    error = input_register_device(haptic->input_dev);
    if (error) {
        printk("regulator-haptic : couldn't register input device : %d\n", error);
        goto err_destroy_ff;
    }
    platform_set_drvdata(pdev, haptic);
    return 0;

err_destroy_ff:
    input_ff_destroy(haptic->input_dev);
err_put_regulator:
    regulator_put(haptic->regulator);
err_ifree_mem:
    input_free_device(haptic->input_dev);
err_kfree_mem:
    kfree(haptic);

    return error;
}
Ejemplo n.º 14
0
static int __devinit max77665_haptic_probe(struct platform_device *pdev)
{
	struct max77665_haptic_platform_data *haptic_pdata =
					pdev->dev.platform_data;
	struct max77665_haptic *chip;
	struct edp_manager *battery_manager = NULL;
	struct input_dev *input_dev;
	int ret;

	if (!haptic_pdata) {
		dev_err(&pdev->dev, "no haptic platform data\n");
		return -EINVAL;
	}

	chip = devm_kzalloc(&pdev->dev, sizeof(struct max77665_haptic),
							GFP_KERNEL);
	if (!chip) {
		dev_err(&pdev->dev, "unable to allocate memory\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev,
			"unable to allocate memory for input dev\n");
		ret = -ENOMEM;
		goto err_input_alloc;
	}

	chip->dev = &pdev->dev;
	chip->input_dev = input_dev;
	chip->pwm_period = haptic_pdata->pwm_period;
	chip->type = haptic_pdata->type;
	chip->mode = haptic_pdata->mode;
	chip->pwm_divisor = haptic_pdata->pwm_divisor;

	if (chip->mode == MAX77665_INTERNAL_MODE) {
		chip->internal_mode_pattern =
				haptic_pdata->internal_mode_pattern;
		chip->pattern_cycle = haptic_pdata->pattern_cycle;
		chip->pattern_signal_period =
				haptic_pdata->pattern_signal_period;
		chip->feedback_duty_cycle =
				haptic_pdata->feedback_duty_cycle;
		chip->invert = haptic_pdata->invert;
		chip->cont_mode = haptic_pdata->cont_mode;
		chip->motor_startup_val = haptic_pdata->motor_startup_val;
		chip->scf_val = haptic_pdata->scf_val;
	}

	if (chip->mode == MAX77665_EXTERNAL_MODE) {
		chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
					"max-vbrtr");
		if (IS_ERR(chip->pwm)) {
			dev_err(&pdev->dev,
				"unable to request PWM for haptic\n");
			ret = PTR_ERR(chip->pwm);
			goto err_pwm;
		}
	}

	chip->regulator = regulator_get(&pdev->dev, "vdd_vbrtr");
	if (IS_ERR(chip->regulator)) {
		dev_err(&pdev->dev, "unable to get regulator\n");
		ret = PTR_ERR(chip->regulator);
		goto err_regulator;
	}

	if (haptic_pdata->edp_states == NULL)
		goto register_input;

	chip->haptic_edp_client = devm_kzalloc(&pdev->dev,
				sizeof(struct edp_client), GFP_KERNEL);
	if (IS_ERR_OR_NULL(chip->haptic_edp_client)) {
		dev_err(&pdev->dev, "could not allocate edp client\n");
		goto register_input;
	}

	chip->haptic_edp_client->name[EDP_NAME_LEN - 1] = '\0';
	strncpy(chip->haptic_edp_client->name, "vibrator", EDP_NAME_LEN - 1);
	chip->haptic_edp_client->states = haptic_pdata->edp_states;
	chip->haptic_edp_client->num_states = MAX77665_HAPTIC_EDP_NUM_STATES;
	chip->haptic_edp_client->e0_index = MAX77665_HAPTIC_EDP_LOW;
	chip->haptic_edp_client->priority = EDP_MAX_PRIO + 2;
	chip->haptic_edp_client->throttle = max77665_haptic_throttle;
	chip->haptic_edp_client->private_data = chip;

	battery_manager = edp_get_manager("battery");
	if (!battery_manager) {
		dev_err(&pdev->dev, "unable to get edp manager\n");
	} else {
		ret = edp_register_client(battery_manager,
					chip->haptic_edp_client);
		if (ret) {
			dev_err(&pdev->dev, "unable to register edp client\n");
		} else {
			ret = edp_update_client_request(chip->haptic_edp_client,
				MAX77665_HAPTIC_EDP_LOW, NULL);
			if (ret) {
				dev_err(&pdev->dev,
					"unable to set E0 EDP state\n");
				edp_unregister_client(chip->haptic_edp_client);
			} else {
				goto register_input;
			}
		}
	}

	devm_kfree(&pdev->dev, chip->haptic_edp_client);
	chip->haptic_edp_client = NULL;

register_input:
	dev_set_drvdata(&pdev->dev, chip);
	input_dev->name = "max77665-haptic";
	input_dev->id.version = 1;
	input_dev->dev.parent = &pdev->dev;
	input_set_drvdata(input_dev, chip);
	input_set_capability(input_dev, EV_FF, FF_RUMBLE);

	ret = input_ff_create_memless(input_dev, NULL,
				max77665_haptic_play_effect);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to create FF device(ret : %d)\n", ret);
		goto err_ff_memless;
	}
	INIT_WORK(&chip->work,
			max77665_haptic_play_effect_work);

	ret = input_register_device(input_dev);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to register input device(ret : %d)\n", ret);
		goto err_input_register;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &max77665_haptics_attr_group);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"unable to create sysfs %d\n", ret);
	}

	return 0;

err_input_register:
	destroy_work_on_stack(&chip->work);
	input_ff_destroy(input_dev);
err_ff_memless:
	regulator_put(chip->regulator);
err_regulator:
	if (chip->mode == MAX77665_EXTERNAL_MODE)
		pwm_free(chip->pwm);
err_pwm:
	input_free_device(input_dev);
err_input_alloc:
	kfree(chip);

	return ret;
}
Ejemplo n.º 15
0
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)  //探针函数 相当于设备驱动的主函数
{
    struct usb_device *udev = interface_to_usbdev(intf); //根据usb设备接口获取到usb设备  实际 返回的是 intf->dev.parent 即设备的父亲
    struct usb_xpad *xpad; //自己的定义的手柄设备类型
    struct input_dev *input_dev;//输入设备
    struct usb_endpoint_descriptor *ep_irq_in;  //in endpoint 的描述
    int ep_irq_in_idx;
    int i, error;

    for (i = 0; xpad_device[i].idVendor; i++) //根据实际插入的设备的生产商id和产品id  找到匹配的设备
    {
        if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
                (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
            break;
    }


    xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); //在内核空间为手柄设备申请内存空间
    input_dev = input_allocate_device(); //为输入设备在内核空间申请内存空间  input_allocate_device()这个函数是用kzalloc函数申请了空间后 然后对该内存进行了初始化
    if (!xpad || !input_dev) //申请空间失败
    {
        error = -ENOMEM;
        goto fail1;
    }
    //usb_alloc_coherent (struct usb_device *dev,size_t size,gfp_t mem_flags,dma_addr_t *dma)--allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
     //分配DMA接口的缓冲区 返回 idata_dma  和 idata(raw packet,原始数据包)
    xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
                                     GFP_KERNEL, &xpad->idata_dma);
    if (!xpad->idata) //返回raw packet(原始数据包)失败
    {
        error = -ENOMEM;
        goto fail1;
    }
    //usb_alloc_urb (int iso_packets,gfp_t mem_flags)  create a new urb for a USB driver to use   iso_packets = 0 when use interrupt endpoints
    //创建新的urb给设备使用
    xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
    if (!xpad->irq_in) //urb创建失败
    {
        error = -ENOMEM;
        goto fail2;
    }

    xpad->udev = udev; //保存usb设备信息
    xpad->intf = intf; //保存usb接口信息

    xpad->dev = input_dev;  //保存输入设备信息
    //创建物理路径
    usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
    strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); //input0类型的

    input_dev->name = xpad_device[i].name; //保存输入设备名字
    input_dev->phys = xpad->phys; //保存输入设备的物理路径
    usb_to_input_id(udev, &input_dev->id); //保存输入设备ID
    input_dev->dev.parent = &intf->dev; //保存输入设备的设备 输入设备的父亲是usb接口 , usb接口的父亲 usb设备

    input_set_drvdata(input_dev, xpad);

    input_dev->open = xpad_open; //输入设备的打开函数
    input_dev->close = xpad_close; //输入设备的关闭函数
	//BIT_MASK(nr)  (1UL<<((nr)%BITS_PER_LONG))
    input_dev->evbit[0] = BIT_MASK(EV_KEY);  //注册键盘事件

    input_dev->evbit[0] |= BIT_MASK(EV_REL); //注册相对轴事件
    input_dev->evbit[0] |= BIT_MASK(EV_ABS); //注册绝对轴事件
    /* set up axes */

    for (i = 0; xpad_abs[i] >= 0; i++) ///注册对应的绝对轴
        xpad_set_up_abs(input_dev, xpad_abs[i]);


    xpad_set_up_rel(input_dev, REL_WHEEL); //注册对应的相对轴
    for (i = 0 ; key_need_register[i] >= 0; i++) __set_bit(key_need_register[i], input_dev->keybit);
    //注册按键
    for (i = 0; xpad_common_btn[i] >= 0; i++)
        __set_bit(xpad_common_btn[i], input_dev->keybit);

    //注册游戏手柄按键

    for (i = 0; xpad360_btn[i] >= 0; i++)
        __set_bit(xpad360_btn[i], input_dev->keybit);

    
    //注册LT RT按键
    for (i = 0; xpad_abs_triggers[i] >= 0; i++)
        xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
    //初始化设备输出
    error = xpad_init_output(intf, xpad);
    if (error)
        goto fail3;


    ep_irq_in_idx =   0;
    ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; //根据usb接口得到 in endpoint口的描述信息
    //函数结构 usb_fill_int_urb(struct urb* urb,struct  usb_device * dev,unsigned int pipe,void * transfer_buffer,int  buffer_length,usb_complete_t complete,void * context,int interval)
    //根据 usb设备,usb管道,输入缓冲区的首地址,缓冲区长度,urb入口函数,手柄设备数据信息,in endpoint口的轮换间隔信息 得到 输入的urb
    usb_fill_int_urb(xpad->irq_in, udev,
                     usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
                     xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
                     xpad, ep_irq_in->bInterval);
    xpad->irq_in->transfer_dma = xpad->idata_dma; //传输的DMA接口地址
    xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; //传输标志(允许DMA方式传输) urb->transfer_dma valid on submit
     //根据输入设备信息 注册设备
    error = input_register_device(xpad->dev);
    if (error)
        goto fail5;

    usb_set_intfdata(intf, xpad);



    return 0;


fail5: if (input_dev)
        input_ff_destroy(input_dev);   //free force feedback structures
fail4: xpad_deinit_output(xpad);  //free out urb and out dma
fail3: usb_free_urb(xpad->irq_in); //free in urb
fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);  //free in dma
fail1: input_free_device(input_dev); //free input_dev
    kfree(xpad); //free xpad
    return error;

}