예제 #1
0
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int ret, i;
	struct mt_device *td;
	struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */

	for (i = 0; mt_classes[i].name ; i++) {
		if (id->driver_data == mt_classes[i].name) {
			mtclass = &(mt_classes[i]);
			break;
		}
	}

	/* This allows the driver to correctly support devices
	 * that emit events over several HID messages.
	 */
	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;

	td = kzalloc(sizeof(struct mt_device) +
				mtclass->maxcontacts * sizeof(struct mt_slot),
				GFP_KERNEL);
	if (!td) {
		dev_err(&hdev->dev, "cannot allocate multitouch data\n");
		return -ENOMEM;
	}
	td->mtclass = mtclass;
	td->inputmode = -1;
	hid_set_drvdata(hdev, td);

	ret = hid_parse(hdev);
	if (ret != 0)
		goto fail;

	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (ret)
		goto fail;

	mt_set_input_mode(hdev);

	return 0;

fail:
	kfree(td);
	return ret;
}
예제 #2
0
파일: hid-lenovo.c 프로젝트: 3null/linux
static void lenovo_remove_tpkbd(struct hid_device *hdev)
{
	struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);

	/*
	 * Only the trackpoint half of the keyboard has drvdata and stuff that
	 * needs unregistering.
	 */
	if (data_pointer == NULL)
		return;

	sysfs_remove_group(&hdev->dev.kobj,
			&lenovo_attr_group_tpkbd);

	led_classdev_unregister(&data_pointer->led_micmute);
	led_classdev_unregister(&data_pointer->led_mute);

	hid_set_drvdata(hdev, NULL);
}
예제 #3
0
static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int ret;
	struct mmm_data *md;

	md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
	if (!md) {
		dev_err(&hdev->dev, "cannot allocate 3M data\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, md);

	ret = hid_parse(hdev);
	if (!ret)
		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);

	if (ret)
		kfree(md);
	return ret;
}
예제 #4
0
static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int rc;
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct huion_drvdata *drvdata;

	/* Allocate and assign driver data */
	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
	if (drvdata == NULL) {
		hid_err(hdev, "failed to allocate driver data\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, drvdata);

	switch (id->product) {
	case USB_DEVICE_ID_HUION_TABLET:
		/* If this is the pen interface */
		if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
			rc = huion_tablet_enable(hdev);
			if (rc) {
				hid_err(hdev, "tablet enabling failed\n");
				return rc;
			}
		}
		break;
	}

	rc = hid_parse(hdev);
	if (rc) {
		hid_err(hdev, "parse failed\n");
		return rc;
	}

	rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (rc) {
		hid_err(hdev, "hw start failed\n");
		return rc;
	}

	return 0;
}
예제 #5
0
static int apple_probe(struct hid_device *hdev,
		const struct hid_device_id *id)
{
	unsigned long quirks = id->driver_data;
	struct apple_sc *asc;
	unsigned int connect_mask = HID_CONNECT_DEFAULT;
	int ret;

	asc = kzalloc(sizeof(*asc), GFP_KERNEL);
	if (asc == NULL) {
		dev_err(&hdev->dev, "can't alloc apple descriptor\n");
		return -ENOMEM;
	}

	asc->quirks = quirks;

	hid_set_drvdata(hdev, asc);

	ret = hid_parse(hdev);
	if (ret) {
		dev_err(&hdev->dev, "parse failed\n");
		goto err_free;
	}

	if (quirks & APPLE_HIDDEV)
		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
	if (quirks & APPLE_IGNORE_HIDINPUT)
		connect_mask &= ~HID_CONNECT_HIDINPUT;

	ret = hid_hw_start(hdev, connect_mask);
	if (ret) {
		dev_err(&hdev->dev, "hw start failed\n");
		goto err_free;
	}

	return 0;
err_free:
	kfree(asc);
	return ret;
}
예제 #6
0
파일: hid-sony.c 프로젝트: E-LLP/n900
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int ret;
	unsigned long quirks = id->driver_data;
	struct sony_sc *sc;

	sc = kzalloc(sizeof(*sc), GFP_KERNEL);
	if (sc == NULL) {
		dev_err(&hdev->dev, "can't alloc apple descriptor\n");
		return -ENOMEM;
	}

	sc->quirks = quirks;
	hid_set_drvdata(hdev, sc);

	ret = hid_parse(hdev);
	if (ret) {
		dev_err(&hdev->dev, "parse failed\n");
		goto err_free;
	}

	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
			HID_CONNECT_HIDDEV_FORCE);
	if (ret) {
		dev_err(&hdev->dev, "hw start failed\n");
		goto err_free;
	}

	ret = sony_set_operational(hdev);
	if (ret)
		goto err_stop;

	return 0;
err_stop:
	hid_hw_stop(hdev);
err_free:
	kfree(sc);
	return ret;
}
예제 #7
0
static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int ret;
	struct ntrig_data *nd;

	nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL);
	if (!nd) {
		dev_err(&hdev->dev, "cannot allocate N-Trig data\n");
		return -ENOMEM;
	}
	nd->reading_a_point = 0;
	nd->found_contact_id = 0;
	hid_set_drvdata(hdev, nd);

	ret = hid_parse(hdev);
	if (!ret)
		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);

	if (ret)
		kfree (nd);
	return ret;
}
예제 #8
0
파일: hid-lenovo.c 프로젝트: 3null/linux
static int lenovo_probe_cptkbd(struct hid_device *hdev)
{
	int ret;
	struct lenovo_drvdata_cptkbd *cptkbd_data;

	/* All the custom action happens on the USBMOUSE device for USB */
	if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
			&& hdev->type != HID_TYPE_USBMOUSE) {
		hid_dbg(hdev, "Ignoring keyboard half of device\n");
		return 0;
	}

	cptkbd_data = devm_kzalloc(&hdev->dev,
					sizeof(*cptkbd_data),
					GFP_KERNEL);
	if (cptkbd_data == NULL) {
		hid_err(hdev, "can't alloc keyboard descriptor\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, cptkbd_data);

	/*
	 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into
	 * regular keys
	 */
	ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
	if (ret)
		hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);

	/* Turn Fn-Lock on by default */
	cptkbd_data->fn_lock = true;
	lenovo_features_set_cptkbd(hdev);

	ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
	if (ret)
		hid_warn(hdev, "Could not create sysfs group: %d\n", ret);

	return 0;
}
예제 #9
0
static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
    int ret;
    struct mosart_data *td;


    td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL);
    if (!td) {
        hid_err(hdev, "cannot allocate MosArt data\n");
        return -ENOMEM;
    }
    td->valid = false;
    td->activity = false;
    td->activity_now = false;
    td->first = false;
    hid_set_drvdata(hdev, td);

    /* currently, it's better to have one evdev device only */
#if 0
    hdev->quirks |= HID_QUIRK_MULTI_INPUT;
#endif

    ret = hid_parse(hdev);
    if (ret == 0)
        ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);

    if (ret == 0) {
        struct hid_report_enum *re = hdev->report_enum
                                         + HID_FEATURE_REPORT;
        struct hid_report *r = re->report_id_hash[7];

        r->field[0]->value[0] = 0x02;
        usbhid_submit_report(hdev, r, USB_DIR_OUT);
    } else
        kfree(td);

    return ret;
}
예제 #10
0
파일: hid-lg.c 프로젝트: mpalmer/linux-2.6
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	unsigned long quirks = id->driver_data;
	unsigned int connect_mask = HID_CONNECT_DEFAULT;
	int ret;

	hid_set_drvdata(hdev, (void *)quirks);

	if (quirks & LG_NOGET)
		hdev->quirks |= HID_QUIRK_NOGET;

	ret = hid_parse(hdev);
	if (ret) {
		dev_err(&hdev->dev, "parse failed\n");
		goto err_free;
	}

	if (quirks & (LG_FF | LG_FF2))
		connect_mask &= ~HID_CONNECT_FF;

	ret = hid_hw_start(hdev, connect_mask);
	if (ret) {
		dev_err(&hdev->dev, "hw start failed\n");
		goto err_free;
	}

	if (quirks & LG_RESET_LEDS)
		usbhid_set_leds(hdev);

	if (quirks & LG_FF)
		lgff_init(hdev);
	if (quirks & LG_FF2)
		lg2ff_init(hdev);

	return 0;
err_free:
	return ret;
}
예제 #11
0
파일: hid-cypress.c 프로젝트: 020gzh/linux
static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	unsigned long quirks = id->driver_data;
	int ret;

	hid_set_drvdata(hdev, (void *)quirks);

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "parse failed\n");
		goto err_free;
	}

	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (ret) {
		hid_err(hdev, "hw start failed\n");
		goto err_free;
	}

	return 0;
err_free:
	return ret;
}
예제 #12
0
static void picolcd_remove(struct hid_device *hdev)
{
	struct picolcd_data *data = hid_get_drvdata(hdev);
	unsigned long flags;

	dbg_hid(PICOLCD_NAME " hardware remove...\n");
	spin_lock_irqsave(&data->lock, flags);
	data->status |= PICOLCD_FAILED;
	spin_unlock_irqrestore(&data->lock, flags);

	picolcd_exit_devfs(data);
	device_remove_file(&hdev->dev, &dev_attr_operation_mode);
	device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
	hid_hw_close(hdev);
	hid_hw_stop(hdev);

	/* Shortcut potential pending reply that will never arrive */
	spin_lock_irqsave(&data->lock, flags);
	if (data->pending)
		complete(&data->pending->ready);
	spin_unlock_irqrestore(&data->lock, flags);

	/* Cleanup LED */
	picolcd_exit_leds(data);
	/* Clean up the framebuffer */
	picolcd_exit_backlight(data);
	picolcd_exit_lcd(data);
	picolcd_exit_framebuffer(data);
	/* Cleanup input */
	picolcd_exit_cir(data);
	picolcd_exit_keys(data);

	hid_set_drvdata(hdev, NULL);
	mutex_destroy(&data->mutex);
	/* Finally, clean up the picolcd data itself */
	kfree(data);
}
예제 #13
0
static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	int ret;
	struct cando_data *td;

	td = kmalloc(sizeof(struct cando_data), GFP_KERNEL);
	if (!td) {
		hid_err(hdev, "cannot allocate Cando Touch data\n");
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, td);
	td->first = false;
	td->oldest = -1;
	td->valid = false;

	ret = hid_parse(hdev);
	if (!ret)
		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);

	if (ret)
		kfree(td);

	return ret;
}
예제 #14
0
static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	unsigned long quirks = id->driver_data;
	int ret;

	hid_set_drvdata(hdev, (void *)quirks);

	ret = hid_parse(hdev);
	if (ret) {
		dev_err(&hdev->dev, "parse failed\n");
		goto err_free;
	}

	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
		((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0));
	if (ret) {
		dev_err(&hdev->dev, "hw start failed\n");
		goto err_free;
	}

	return 0;
err_free:
	return ret;
}
예제 #15
0
static void egalax_remove(struct hid_device *hdev)
{
	hid_hw_stop(hdev);
	kfree(hid_get_drvdata(hdev));
	hid_set_drvdata(hdev, NULL);
}
static int razer_kbd_probe(struct hid_device *hdev,
			 const struct hid_device_id *id)
{
    int retval;
    struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
    //struct usb_device *usb_dev = interface_to_usbdev(intf);
    struct razer_kbd_device *dev = NULL;

    dev = kzalloc(sizeof(struct razer_kbd_device),GFP_KERNEL);
    if(dev == NULL) {
        dev_err(&intf->dev, "out of memory\n");
        retval = -ENOMEM;
        goto exit;
    }
    
    retval = device_create_file(&hdev->dev, &dev_attr_mode_wave);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_spectrum);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_none);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_reactive);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_breath);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_custom);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_static);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_temp_clear_row);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_set_key_row);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_reset);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_macro_keys);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_set_brightness);
    if (retval)
        goto exit_free;

    hid_set_drvdata(hdev, dev);

    retval = hid_parse(hdev);
    if(retval)	{
    	hid_err(hdev,"parse failed\n");
	   goto exit_free;
    }
    retval = hid_hw_start(hdev,HID_CONNECT_DEFAULT);
    if (retval) {
    	hid_err(hdev,"hw start failed\n");
	   goto exit_free;
    }

    //razer_reset(usb_dev);
    //razer_activate_macro_keys(usb_dev);
    //msleep(3000);
    return 0;
exit:
    return retval;	
exit_free:
    kfree(dev);
    return retval;
}
예제 #17
0
static int logi_dj_probe(struct hid_device *hdev,
			 const struct hid_device_id *id)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct dj_receiver_dev *djrcv_dev;
	int retval;

	if (is_dj_device((struct dj_device *)hdev->driver_data))
		return -ENODEV;

	dbg_hid("%s called for ifnum %d\n", __func__,
		intf->cur_altsetting->desc.bInterfaceNumber);

	/* Ignore interfaces 0 and 1, they will not carry any data, dont create
	 * any hid_device for them */
	if (intf->cur_altsetting->desc.bInterfaceNumber !=
	    LOGITECH_DJ_INTERFACE_NUMBER) {
		dbg_hid("%s: ignoring ifnum %d\n", __func__,
			intf->cur_altsetting->desc.bInterfaceNumber);
		return -ENODEV;
	}

	/* Treat interface 2 */

	djrcv_dev = kzalloc(sizeof(struct dj_receiver_dev), GFP_KERNEL);
	if (!djrcv_dev) {
		dev_err(&hdev->dev,
			"%s:failed allocating dj_receiver_dev\n", __func__);
		return -ENOMEM;
	}
	djrcv_dev->hdev = hdev;
	INIT_WORK(&djrcv_dev->work, delayedwork_callback);
	spin_lock_init(&djrcv_dev->lock);
	if (kfifo_alloc(&djrcv_dev->notif_fifo,
			DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report),
			GFP_KERNEL)) {
		dev_err(&hdev->dev,
			"%s:failed allocating notif_fifo\n", __func__);
		kfree(djrcv_dev);
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, djrcv_dev);

	/* Call  to usbhid to fetch the HID descriptors of interface 2 and
	 * subsequently call to the hid/hid-core to parse the fetched
	 * descriptors, this will in turn create the hidraw and hiddev nodes
	 * for interface 2 of the receiver */
	retval = hid_parse(hdev);
	if (retval) {
		dev_err(&hdev->dev,
			"%s:parse of interface 2 failed\n", __func__);
		goto hid_parse_fail;
	}

	/* Starts the usb device and connects to upper interfaces hiddev and
	 * hidraw */
	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (retval) {
		dev_err(&hdev->dev,
			"%s:hid_hw_start returned error\n", __func__);
		goto hid_hw_start_fail;
	}

	retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
	if (retval < 0) {
		dev_err(&hdev->dev,
			"%s:logi_dj_recv_switch_to_dj_mode returned error:%d\n",
			__func__, retval);
		goto switch_to_dj_mode_fail;
	}

	/* This is enabling the polling urb on the IN endpoint */
	retval = hdev->ll_driver->open(hdev);
	if (retval < 0) {
		dev_err(&hdev->dev, "%s:hdev->ll_driver->open returned "
			"error:%d\n", __func__, retval);
		goto llopen_failed;
	}

	retval = logi_dj_recv_query_paired_devices(djrcv_dev);
	if (retval < 0) {
		dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices "
			"error:%d\n", __func__, retval);
		goto logi_dj_recv_query_paired_devices_failed;
	}

	return retval;

logi_dj_recv_query_paired_devices_failed:
	hdev->ll_driver->close(hdev);

llopen_failed:
switch_to_dj_mode_fail:
	hid_hw_stop(hdev);

hid_hw_start_fail:
hid_parse_fail:
	kfifo_free(&djrcv_dev->notif_fifo);
	kfree(djrcv_dev);
	hid_set_drvdata(hdev, NULL);
	return retval;

}
예제 #18
0
static int rmi_hid_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	struct rmi_transport_device *xport = NULL;
	struct rmi_hid_data *data = NULL;
	unsigned int connect_mask = HID_CONNECT_HIDRAW | HID_CONNECT_HIDDEV;
	int ret;

	dev_dbg(&hdev->dev, "%s\n", __func__);

	xport = devm_kzalloc(&hdev->dev, sizeof(struct rmi_transport_device),
				GFP_KERNEL);
	if (!xport) {
		ret = -ENOMEM;
		goto err;
	}

	data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_hid_data),
				GFP_KERNEL);
	if (!data) {
		ret =-ENOMEM;
		goto err;
	}

	data->xport = xport;

	xport->data = data;
	xport->dev = &hdev->dev;

	xport->write_block = rmi_hid_write_block;
	xport->read_block = rmi_hid_read_block;
	xport->info.proto_type = RMI_PROTOCOL_HID;
	xport->info.proto = transport_proto_name;
	xport->post_reset = rmi_hid_post_reset;
	hid_set_drvdata(hdev, xport);

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "parse failed\n");
		goto err;
	}

	data->input_report_size =
		(hdev->report_enum[HID_INPUT_REPORT]
		.report_id_hash[RMI_ATTN_REPORT_ID]->size >> 3)
		+ 1 /* report id */;
	data->output_report_size =
		(hdev->report_enum[HID_OUTPUT_REPORT]
		.report_id_hash[RMI_WRITE_REPORT_ID]->size >> 3)
		+ 1 /* report id */;
	data->feature_report_size =
		(hdev->report_enum[HID_FEATURE_REPORT]
		.report_id_hash[RMI_SET_RMI_MODE_REPORT_ID]->size >> 3)
		+ 1 /* report id */;

	dev_dbg(&hdev->dev, "input report size %d\n", data->input_report_size);
	dev_dbg(&hdev->dev, "output report size %d\n",
		data->output_report_size);
	dev_dbg(&hdev->dev, "feature report size %d\n",
		data->feature_report_size);

	data->input_queue = devm_kzalloc(&hdev->dev, data->input_report_size
				* RMI_HID_INPUT_REPORT_QUEUE_LEN, GFP_KERNEL);
	if (!data->input_queue) {
		ret = -ENOMEM;
		goto err;
	}

	data->writeReport = devm_kzalloc(&hdev->dev, data->output_report_size,
				GFP_KERNEL);
	if (!data->writeReport) {
		ret = -ENOMEM;
		goto err;
	}

	data->readReport = devm_kzalloc(&hdev->dev, data->input_report_size,
				GFP_KERNEL);
	if (!data->readReport) {
		ret = -ENOMEM;
		goto err;
	}

	data->attnReport = devm_kzalloc(&hdev->dev, data->input_report_size,
				GFP_KERNEL);
	if (!data->attnReport) {
		ret = -ENOMEM;
		goto err;
	}

	tp_platformdata.pm_data = hdev;
	xport->dev->platform_data = &tp_platformdata;

#ifdef TOUCHPAD_WAKE_SYSTEM
	if (tp_platformdata.f11_sensor_data[0].sensor_type == rmi_sensor_touchpad) {
		device_init_wakeup(hdev->dev.parent, 1);
	}
#endif

	spin_lock_init(&data->input_queue_consumer_lock);
	spin_lock_init(&data->input_queue_producer_lock);
	data->input_queue_head = 0;
	data->input_queue_tail = 0;
	INIT_WORK(&data->attn_report_work, rmi_hid_attn_report_work);
	INIT_WORK(&data->reset_work, rmi_hid_reset_work);
	init_waitqueue_head(&data->wait);

	mutex_init(&data->page_mutex);

	ret = hid_hw_start(hdev, connect_mask);
	if (ret) {
		hid_err(hdev, "hw start failed\n");
		goto err;
	}

	dev_dbg(&hdev->dev, "Opening low level driver\n");
	hdev->ll_driver->open(hdev);

	/* Allow incoming hid reports */
	hid_device_io_start(hdev);

	ret = rmi_hid_set_mode(hdev, RMI_HID_MODE_ATTN_REPORTS);
	if (ret < 0) {
		dev_err(&hdev->dev, "failed to set rmi mode\n");
		goto rmi_read_failed;
	}

	ret = rmi_set_page(xport, 0);
	if (ret < 0) {
		dev_err(&hdev->dev, "failed to set page select to 0.\n");
		goto rmi_read_failed;
	}

	ret = rmi_register_transport_device(xport);
	if (ret) {
		dev_err(&hdev->dev, "failed to register transport device at %s\n",
			hdev->phys);
		goto rmi_read_failed;
	}

	if (!xport->probe_succeeded) {
		dev_err(&hdev->dev, "Probe failed in rmi_driver\n");
		ret = -ENODEV;
		goto rmi_driver_probe_failed;
	}

	set_bit(RMI_HID_STARTED, &data->flags);

	if (IS_ENABLED(CONFIG_RMI4_DEBUG))
		ret = setup_debugfs(xport->rmi_dev, data);

	dev_info(&hdev->dev, "registered rmi hid driver at %s\n", hdev->phys);

	return 0;

rmi_driver_probe_failed:
	rmi_unregister_transport_device(xport);

rmi_read_failed:
	hdev->ll_driver->close(hdev);
	hid_hw_stop(hdev);

err:
	return ret;
}
/**
 * Probe method is ran whenever a device is binded to the driver
 *
 * TODO remove goto's
 */
static int razer_kbd_probe(struct hid_device *hdev,
             const struct hid_device_id *id)
{
    int retval;
    struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
    struct usb_device *usb_dev = interface_to_usbdev(intf);
    struct razer_kbd_device *dev = NULL;

    dev = kzalloc(sizeof(struct razer_kbd_device), GFP_KERNEL);
    if(dev == NULL) {
        dev_err(&intf->dev, "out of memory\n");
        retval = -ENOMEM;
        goto exit;
    }
    
    if(usb_dev->descriptor.idProduct == USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE_2013)
    {
        retval = device_create_file(&hdev->dev, &dev_attr_mode_pulsate);
            if (retval)
                goto exit_free;
    } else
    {
        retval = device_create_file(&hdev->dev, &dev_attr_mode_wave);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_mode_spectrum);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_mode_none);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_mode_reactive);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_mode_breath);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_mode_custom);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_temp_clear_row);
        if (retval)
            goto exit_free;
        retval = device_create_file(&hdev->dev, &dev_attr_set_key_row);
        if (retval)
            goto exit_free;
    }

    retval = device_create_file(&hdev->dev, &dev_attr_get_serial);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_device_type);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_game);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_mode_static);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_reset);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_macro_keys);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_set_brightness);
    if (retval)
        goto exit_free;
    retval = device_create_file(&hdev->dev, &dev_attr_test);
    if (retval)
        goto exit_free;

    hid_set_drvdata(hdev, dev);


    retval = hid_parse(hdev);
    if(retval)    {
        hid_err(hdev, "parse failed\n");
       goto exit_free;
    }
    retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
    if (retval) {
        hid_err(hdev, "hw start failed\n");
       goto exit_free;
    }


    razer_reset(usb_dev);
    usb_disable_autosuspend(usb_dev);
    //razer_activate_macro_keys(usb_dev);
    //msleep(3000);
    return 0;
exit:
    return retval;
exit_free:
    kfree(dev);
    return retval;
}
예제 #20
0
/**
 * Probe method is ran whenever a device is binded to the driver
 *
 * TODO remove goto's
 */
static int razer_mousemat_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
    int retval = 0;
    struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
    struct usb_device *usb_dev = interface_to_usbdev(intf);
    struct razer_mousemat_device *dev = NULL;

    dev = kzalloc(sizeof(struct razer_mousemat_device), GFP_KERNEL);
    if(dev == NULL) {
        dev_err(&intf->dev, "out of memory\n");
        retval = -ENOMEM;
        goto exit;
    }

    if(intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) {

        switch(usb_dev->descriptor.idProduct) {
        case USB_DEVICE_ID_RAZER_GOLIATHUS_CHROMA:
        case USB_DEVICE_ID_RAZER_GOLIATHUS_CHROMA_EXTENDED:
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_version);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_reactive_trigger);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_serial);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_firmware_version);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_type);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_static);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_brightness);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_mode);

            // Device initial brightness is always 100% anyway
            saved_brightness = 0xFF;
            break;

        default:
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_version);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_reactive_trigger);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wave);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_serial);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_firmware_version);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_type);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_static);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_brightness);
            CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_mode);
            break;
        }

    }

    if (retval)
        goto exit_free;

    hid_set_drvdata(hdev, dev);


    retval = hid_parse(hdev);
    if(retval)    {
        hid_err(hdev, "parse failed\n");
        goto exit_free;
    }
    retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
    if (retval) {
        hid_err(hdev, "hw start failed\n");
        goto exit_free;
    }


    usb_disable_autosuspend(usb_dev);
    return 0;
exit:
    return retval;
exit_free:
    kfree(dev);
    return retval;
}
예제 #21
0
파일: hid-g19.c 프로젝트: tanktarta/lg4l
static int g19_probe(struct hid_device *hdev,
		     const struct hid_device_id *id)
{
        unsigned long irq_flags;
	int error;
	struct g19_data *data;
	int i;
	int led_num;
	struct usb_interface *intf;
	struct usb_device *usbdev;
	struct list_head *feature_report_list =
		&hdev->report_enum[HID_FEATURE_REPORT].report_list;
	struct hid_report *report;
	char *led_name;

	dev_dbg(&hdev->dev, "Logitech G19 HID hardware probe...");

	/* Get the usb device to send the start report on */
	intf = to_usb_interface(hdev->dev.parent);
	usbdev = interface_to_usbdev(intf);

	/*
	 * Let's allocate the g19 data structure, set some reasonable
	 * defaults, and associate it with the device
	 */
	data = kzalloc(sizeof(struct g19_data), GFP_KERNEL);
	if (data == NULL) {
		dev_err(&hdev->dev, "can't allocate space for Logitech G19 device attributes\n");
		error = -ENOMEM;
		goto err_no_cleanup;
	}

	spin_lock_init(&data->lock);

	init_completion(&data->ready);

	data->hdev = hdev;

	data->ep1_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (data->ep1_urb == NULL) {
		dev_err(&hdev->dev, G19_NAME ": ERROR: can't alloc ep1 urb stuff\n");
		error = -ENOMEM;
		goto err_cleanup_data;
	}

	hid_set_drvdata(hdev, data);

	dbg_hid("Preparing to parse " G19_NAME " hid reports\n");

	/* Parse the device reports and start it up */
	error = hid_parse(hdev);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " device report parse failed\n");
		error = -EINVAL;
		goto err_cleanup_ep1_urb;
	}

	error = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDINPUT_FORCE);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " hardware start failed\n");
		error = -EINVAL;
		goto err_cleanup_ep1_urb;
	}

	dbg_hid(G19_NAME " claimed: %d\n", hdev->claimed);

	error = hdev->ll_driver->open(hdev);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " failed to open input interrupt pipe for key and joystick events\n");
		error = -EINVAL;
		goto err_cleanup_ep1_urb;
	}

	/* Set up the input device for the key I/O */
	data->input_dev = input_allocate_device();
	if (data->input_dev == NULL) {
		dev_err(&hdev->dev, G19_NAME " error initializing the input device");
		error = -ENOMEM;
		goto err_cleanup_ep1_urb;
	}

	input_set_drvdata(data->input_dev, hdev);

	data->input_dev->name = G19_NAME;
	data->input_dev->phys = hdev->phys;
	data->input_dev->uniq = hdev->uniq;
	data->input_dev->id.bustype = hdev->bus;
	data->input_dev->id.vendor = hdev->vendor;
	data->input_dev->id.product = hdev->product;
	data->input_dev->id.version = hdev->version;
	data->input_dev->dev.parent = hdev->dev.parent;
	data->input_dev->keycode = data->keycode;
	data->input_dev->keycodemax = G19_KEYMAP_SIZE;
	data->input_dev->keycodesize = sizeof(int);
	data->input_dev->setkeycode = g19_input_setkeycode;
	data->input_dev->getkeycode = g19_input_getkeycode;

	input_set_capability(data->input_dev, EV_KEY, KEY_UNKNOWN);
	data->input_dev->evbit[0] |= BIT_MASK(EV_REP);

	g19_initialize_keymap(data);

	error = input_register_device(data->input_dev);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " error registering the input device");
		error = -EINVAL;
		goto err_cleanup_input_dev;
	}

	if (list_empty(feature_report_list)) {
		dev_err(&hdev->dev, "no feature report found\n");
		error = -ENODEV;
		goto err_cleanup_input_dev_reg;
	}
	dbg_hid(G19_NAME " feature report found\n");

	list_for_each_entry(report, feature_report_list, list) {
		switch (report->id) {
		case 0x04:
			data->feature_report_4 = report;
			break;
		case 0x05:
			data->led_report = report;
			break;
		case 0x06:
			data->start_input_report = report;
			break;
		case 0x07:
			data->backlight_report = report;
			break;
		default:
			break;
		}
		dbg_hid(G19_NAME " Feature report: id=%u type=%u size=%u maxfield=%u report_count=%u\n",
			report->id, report->type, report->size,
			report->maxfield, report->field[0]->report_count);
	}

	dbg_hid("Found all reports\n");

	/* Create the LED structures */
	for (i = 0; i < LED_COUNT; i++) {
		data->led_cdev[i] = kzalloc(sizeof(struct led_classdev), GFP_KERNEL);
		if (data->led_cdev[i] == NULL) {
			dev_err(&hdev->dev, G19_NAME " error allocating memory for led %d", i);
			error = -ENOMEM;
			goto err_cleanup_led_structs;
		}
		/* Set the accessor functions by copying from template*/
		*(data->led_cdev[i]) = g19_led_cdevs[i];

		/*
		 * Allocate memory for the LED name
		 *
		 * Since led_classdev->name is a const char* we'll use an
		 * intermediate until the name is formatted with sprintf().
		 */
		led_name = kzalloc(sizeof(char)*20, GFP_KERNEL);
		if (led_name == NULL) {
			dev_err(&hdev->dev, G19_NAME " error allocating memory for led %d name", i);
			error = -ENOMEM;
			goto err_cleanup_led_structs;
		}
		switch (i) {
		case G19_LED_M1:
		case G19_LED_M2:
		case G19_LED_M3:
			sprintf(led_name, "g19_%d:orange:m%d", hdev->minor, i+1);
			break;
		case G19_LED_MR:
			sprintf(led_name, "g19_%d:red:mr", hdev->minor);
			break;
		case G19_LED_BL_R:
			sprintf(led_name, "g19_%d:red:bl", hdev->minor);
			break;
		case G19_LED_BL_G:
			sprintf(led_name, "g19_%d:green:bl", hdev->minor);
			break;
		case G19_LED_BL_B:
			sprintf(led_name, "g19_%d:blue:bl", hdev->minor);
			break;
		case G19_LED_BL_SCREEN:
			sprintf(led_name, "g19_%d:white:screen", hdev->minor);
			break;

		}
		data->led_cdev[i]->name = led_name;
	}

	for (i = 0; i < LED_COUNT; i++) {
		led_num = i;
		error = led_classdev_register(&hdev->dev, data->led_cdev[i]);
		if (error < 0) {
			dev_err(&hdev->dev, G19_NAME " error registering led %d", i);
			error = -EINVAL;
			goto err_cleanup_registered_leds;
		}
	}

	data->gfb_data = gfb_probe(hdev, GFB_PANEL_TYPE_320_240_16);
	if (data->gfb_data == NULL) {
		dev_err(&hdev->dev, G19_NAME " error registering framebuffer\n");
		goto err_cleanup_registered_leds;
	}

	dbg_hid("Waiting for G19 to activate\n");

	/* Add the sysfs attributes */
	error = sysfs_create_group(&(hdev->dev.kobj), &g19_attr_group);
	if (error) {
		dev_err(&hdev->dev, G19_NAME " failed to create sysfs group attributes\n");
		goto err_cleanup_registered_leds;
	}

	/*
	 * Wait here for stage 1 (substages 1-3) to complete
	 */
	wait_for_completion_timeout(&data->ready, HZ);

	/* Protect data->ready_stages before checking whether we're ready to proceed */
	spin_lock_irqsave(&data->lock, irq_flags);
	if (data->ready_stages != G19_READY_STAGE_1) {
		dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 1 yet, forging ahead with initialization\n");
		/* Force the stage */
		data->ready_stages = G19_READY_STAGE_1;
	}
	init_completion(&data->ready);
	data->ready_stages |= G19_READY_SUBSTAGE_4;
	spin_unlock_irqrestore(&data->lock, irq_flags);

	/*
	 * Send the init report, then follow with the input report to trigger
	 * report 6 and wait for us to get a response.
	 */
	g19_feature_report_4_send(hdev, G19_REPORT_4_INIT);
	usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN);
	wait_for_completion_timeout(&data->ready, HZ);

	/* Protect data->ready_stages before checking whether we're ready to proceed */
	spin_lock_irqsave(&data->lock, irq_flags);
	if (data->ready_stages != G19_READY_STAGE_2) {
		dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 2 yet, forging ahead with initialization\n");
		/* Force the stage */
		data->ready_stages = G19_READY_STAGE_2;
	}
	init_completion(&data->ready);
	data->ready_stages |= G19_READY_SUBSTAGE_6;
	spin_unlock_irqrestore(&data->lock, irq_flags);

	/*
	 * Clear the LEDs
	 */
	g19_led_send(hdev);

	data->rgb[0] = G19_DEFAULT_RED;
	data->rgb[1] = G19_DEFAULT_GREEN;
	data->rgb[2] = G19_DEFAULT_BLUE;
	g19_rgb_send(hdev);

	data->screen_bl = G19_DEFAULT_BRIGHTNESS;
	g19_screen_bl_send(hdev);

	/*
	 * Send the finalize report, then follow with the input report to trigger
	 * report 6 and wait for us to get a response.
	 */
	g19_feature_report_4_send(hdev, G19_REPORT_4_FINALIZE);
	usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN);
	usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN);
	wait_for_completion_timeout(&data->ready, HZ);

	/* Protect data->ready_stages before checking whether we're ready to proceed */
	spin_lock_irqsave(&data->lock, irq_flags);

	if (data->ready_stages != G19_READY_STAGE_3) {
		dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 3 yet, forging ahead with initialization\n");
		/* Force the stage */
		data->ready_stages = G19_READY_STAGE_3;
	} else {
		dbg_hid(G19_NAME " stage 3 complete\n");
	}

	spin_unlock_irqrestore(&data->lock, irq_flags);

	g19_set_keymap_switching(hdev, 1);

	g19_ep1_read(hdev);

	dbg_hid("G19 activated and initialized\n");

	/* Everything went well */
	return 0;

err_cleanup_registered_leds:
	for (i = 0; i < led_num; i++)
		led_classdev_unregister(data->led_cdev[i]);

err_cleanup_led_structs:
	for (i = 0; i < LED_COUNT; i++) {
		if (data->led_cdev[i] != NULL) {
			if (data->led_cdev[i]->name != NULL)
				kfree(data->led_cdev[i]->name);
			kfree(data->led_cdev[i]);
		}
	}

err_cleanup_input_dev_reg:
	input_unregister_device(data->input_dev);

err_cleanup_input_dev:
	input_free_device(data->input_dev);

err_cleanup_ep1_urb:
	usb_free_urb(data->ep1_urb);



err_cleanup_data:
	/* Make sure we clean up the allocated data structure */
	kfree(data);

err_no_cleanup:

	hid_set_drvdata(hdev, NULL);

	return error;
}
예제 #22
0
static int ntrig_usbhid_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	char				phys_path[256];
	int 				ret;
	struct ntrig_usbhid_data*	nd;
	struct usb_interface*		intf;
	struct usb_device* 		dev;
	struct usb_host_interface*	interface;
	struct usb_endpoint_descriptor*	endpoint;
	struct _ntrig_dev_ncp_func	ncp_func;
	struct _ntrig_dev_hid_func	hid_func;


	intf 	 = to_usb_interface(hdev->dev.parent);
	dev	 = interface_to_usbdev(intf);
	interface= intf->cur_altsetting;
	endpoint = &interface->endpoint[0].desc;
	nd = kmalloc(sizeof(struct ntrig_usbhid_data), GFP_KERNEL);
	if (!nd) {
		dev_err(&hdev->dev, "cannot allocate N-Trig data\n");
		return -ENOMEM;
	} 
	if(DTRG_NO_ERROR != allocate_device(&nd->ntrig_dispatcher)){
		dev_err(&hdev->dev, "cannot allocate N-Trig dispatcher\n");
		return DTRG_FAILED;
	}

	hid_set_drvdata(hdev, nd);
	ret = hid_parse(hdev);
	if (ret) {
		dev_err(&hdev->dev, "parse failed, error code=%d\n", ret);
		goto err_free;
	}

	if (NCP_EP_ADDRESS == endpoint->bEndpointAddress) {
		ret = hid_hw_start(hdev, ~HID_QUIRK_MULTI_INPUT);
		if (ret) {
			dev_err(&hdev->dev, "hw start failed NCP, error code=%d\n", ret);
			goto err_free;
		}

		/* register device in the dispatcher - set device and function pointers for ncp
		set sensor id in the device data structure */	  
	// NOTE: registration of ncp_read, ncp_write & dev is linked. 
	//  It's the resposibility of this function to set these parameters together
		ncp_func.dev = (void *) hdev;
		ncp_func.read = NTRIGReadNCP;
		ncp_func.write = NTRIGWriteNCP;
		nd->sensor_id = RegNtrigDispatcher(TYPE_BUS_USB_HID, hdev->uniq, &ncp_func, NULL);
		// TODO: define behavior in case of fail
		if (nd->sensor_id == DTRG_FAILED) {
			ntrig_dbg("%s: Cannot register device to dispatcher\n", __FUNCTION__);
			goto err_free;
		}
		ntrig_dbg("%s NCP dev registered with dispatcher, bus_id = %s, sensor_id = %d\n", __FUNCTION__, hdev->uniq, nd->sensor_id);
		return 0;
	}

	else {
		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
		if (ret) {
			dev_err(&hdev->dev, "hw start failed TOUCH, error code=%d\n", ret);
			goto err_free;
		}
		ret = ntrig_usbhid_send_report(hdev, REPORTID_DRIVER_ALIVE, NULL, 0);
		if (ret < 0) {
			dev_err(&hdev->dev, "send set feature failed, error code=%d\n", ret);
			goto err_free;
		}

		/* register device in the dispatcher - no need to set device and function pointers for touch events
		   set sensor id in the device data structure */	  
	// NOTE: registration of ncp_read, ncp_write & dev is linked. 
	//  It's the resposibility of this function to set these parameters together
		hid_func.dev = (void *)hdev;
		hid_func.read = NTRIGReadSensor;
		hid_func.write = NTRIGWriteSensor;
		nd->sensor_id = RegNtrigDispatcher(TYPE_BUS_USB_HID, hdev->uniq, NULL, &hid_func); 
		// TODO: define behavior in case of fail
		if (nd->sensor_id == DTRG_FAILED) {
			ntrig_dbg("%s: Cannot register device to dispatcher\n", __FUNCTION__);
			goto err_free;
		}
		ntrig_dbg("%s HID dev registered with dispatcher, bus_id = %s, sensor_id = %d\n", __FUNCTION__, hdev->uniq, nd->sensor_id);
	}
	/**
	 * Create additional single touch queue
         */

	usb_make_path(dev, phys_path, sizeof(phys_path));
	strlcat(phys_path, "/input0", sizeof(phys_path));
	
	nd->ntrig_dispatcher->phys = phys_path;
	nd->ntrig_dispatcher->name = "USBHID";
	nd->ntrig_dispatcher->pressure_min= 0;
	nd->ntrig_dispatcher->pressure_max= 0xFF;
	create_single_touch(nd->ntrig_dispatcher, nd->sensor_id);
	create_multi_touch (nd->ntrig_dispatcher, nd->sensor_id);

	nd->battery_status = PEN_BUTTON_BATTERY_NOT_AVAILABLE;

	ntrig_dbg("Iside %s, bus_id = %d, name = %s, phys = %s, uniq = %s\n", __FUNCTION__, hdev->bus, hdev->name, hdev->phys, hdev->uniq );

	ntrig_dbg("End of %s\n", __FUNCTION__);
	return DTRG_NO_ERROR;
err_free:
	ntrig_dbg("Error End of %s\n", __FUNCTION__);
	remove_device(&nd->ntrig_dispatcher);	
	kfree(nd);
	return DTRG_FAILED;
}
예제 #23
0
파일: hid-lg.c 프로젝트: 7799/linux
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	unsigned int connect_mask = HID_CONNECT_DEFAULT;
	struct lg_drv_data *drv_data;
	int ret;

	drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
	if (!drv_data) {
		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
		return -ENOMEM;
	}
	drv_data->quirks = id->driver_data;

	hid_set_drvdata(hdev, (void *)drv_data);

	if (drv_data->quirks & LG_NOGET)
		hdev->quirks |= HID_QUIRK_NOGET;

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "parse failed\n");
		goto err_free;
	}

	if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
		connect_mask &= ~HID_CONNECT_FF;

	ret = hid_hw_start(hdev, connect_mask);
	if (ret) {
		hid_err(hdev, "hw start failed\n");
		goto err_free;
	}

	/* Setup wireless link with Logitech Wii wheel */
	if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
		unsigned char buf[] = { 0x00, 0xAF,  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

		ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
					HID_FEATURE_REPORT, HID_REQ_SET_REPORT);

		if (ret >= 0) {
			/* insert a little delay of 10 jiffies ~ 40ms */
			wait_queue_head_t wait;
			init_waitqueue_head (&wait);
			wait_event_interruptible_timeout(wait, 0, 10);

			/* Select random Address */
			buf[1] = 0xB2;
			get_random_bytes(&buf[2], 2);

			ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
					HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
		}
	}

	if (drv_data->quirks & LG_FF)
		lgff_init(hdev);
	if (drv_data->quirks & LG_FF2)
		lg2ff_init(hdev);
	if (drv_data->quirks & LG_FF3)
		lg3ff_init(hdev);
	if (drv_data->quirks & LG_FF4)
		lg4ff_init(hdev);

	return 0;
err_free:
	kfree(drv_data);
	return ret;
}
예제 #24
0
파일: hid-g15.c 프로젝트: Cightline/lg4l
static int g15_probe(struct hid_device *hdev,
		     const struct hid_device_id *id)
{
	unsigned long irq_flags;
	int error;
	struct gcommon_data *gdata;
	struct g15_data *g15data;
	int i;
	int led_num;
	struct usb_interface *intf;
	struct usb_device *usbdev;
	struct list_head *feature_report_list =
		&hdev->report_enum[HID_FEATURE_REPORT].report_list;
	struct list_head *output_report_list =
			&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
	struct hid_report *report;
	char *led_name;

	dev_dbg(&hdev->dev, "Logitech G15 HID hardware probe...");

	/* Get the usb device to send the start report on */
	intf = to_usb_interface(hdev->dev.parent);
	usbdev = interface_to_usbdev(intf);

	/*
	 * Let's allocate the g15 data structure, set some reasonable
	 * defaults, and associate it with the device
	 */
	gdata = kzalloc(sizeof(struct gcommon_data), GFP_KERNEL);
	if (gdata == NULL) {
		dev_err(&hdev->dev, "can't allocate space for Logitech G15 device attributes\n");
		error = -ENOMEM;
		goto err_no_cleanup;
	}

	g15data = kzalloc(sizeof(struct g15_data), GFP_KERNEL);
	if (g15data == NULL) {
		dev_err(&hdev->dev, "can't allocate space for Logitech G15 device attributes\n");
		error = -ENOMEM;
		goto err_cleanup_gdata;
	}
        gdata->data = g15data;

	spin_lock_init(&gdata->lock);

	init_completion(&g15data->ready);

	gdata->hdev = hdev;

	hid_set_drvdata(hdev, gdata);

	dbg_hid("Preparing to parse " G15_NAME " hid reports\n");

	/* Parse the device reports and start it up */
	error = hid_parse(hdev);
	if (error) {
		dev_err(&hdev->dev, G15_NAME " device report parse failed\n");
		error = -EINVAL;
		goto err_cleanup_g15data;
	}

	error = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDINPUT_FORCE);
	if (error) {
		dev_err(&hdev->dev, G15_NAME " hardware start failed\n");
		error = -EINVAL;
		goto err_cleanup_g15data;
	}

	dbg_hid(G15_NAME " claimed: %d\n", hdev->claimed);

	error = hdev->ll_driver->open(hdev);
	if (error) {
		dev_err(&hdev->dev, G15_NAME " failed to open input interrupt pipe for key and joystick events\n");
		error = -EINVAL;
		goto err_cleanup_g15data;
	}

	/* Set up the input device for the key I/O */
	gdata->input_dev = input_allocate_device();
	if (gdata->input_dev == NULL) {
		dev_err(&hdev->dev, G15_NAME " error initializing the input device");
		error = -ENOMEM;
		goto err_cleanup_g15data;
	}

	input_set_drvdata(gdata->input_dev, gdata);

	gdata->input_dev->name = G15_NAME;
	gdata->input_dev->phys = hdev->phys;
	gdata->input_dev->uniq = hdev->uniq;
	gdata->input_dev->id.bustype = hdev->bus;
	gdata->input_dev->id.vendor = hdev->vendor;
	gdata->input_dev->id.product = hdev->product;
	gdata->input_dev->id.version = hdev->version;
	gdata->input_dev->dev.parent = hdev->dev.parent;
	gdata->input_dev->keycode = gdata->input_data.keycode;
	gdata->input_dev->keycodemax = G15_KEYMAP_SIZE;
	gdata->input_dev->keycodesize = sizeof(int);
	gdata->input_dev->setkeycode = ginput_setkeycode;
	gdata->input_dev->getkeycode = ginput_getkeycode;

	input_set_capability(gdata->input_dev, EV_KEY, KEY_UNKNOWN);
	gdata->input_dev->evbit[0] |= BIT_MASK(EV_REP);

        gdata->input_data.notify_keymap_switched = g15_notify_keymap_switched;

        error = ginput_alloc(gdata, G15_KEYS);
        if (error) {
		dev_err(&hdev->dev, G15_NAME " error allocating memory for the input device");
                goto err_cleanup_input_dev;
        }

	g15_initialize_keymap(gdata);

	error = input_register_device(gdata->input_dev);
	if (error) {
		dev_err(&hdev->dev, G15_NAME " error registering the input device");
		error = -EINVAL;
		goto err_cleanup_input_dev_data;
	}

	dbg_hid(KERN_INFO G15_NAME " allocated framebuffer\n");

	dbg_hid(KERN_INFO G15_NAME " allocated deferred IO structure\n");

	if (list_empty(feature_report_list)) {
		dev_err(&hdev->dev, "no feature report found\n");
		error = -ENODEV;
		goto err_cleanup_input_dev_reg;
	}
	dbg_hid(G15_NAME " feature report found\n");

	list_for_each_entry(report, feature_report_list, list) {
		switch (report->id) {
		case 0x02: /* G15 has only one feature report 0x02 */
			g15data->feature_report_4
                          = g15data->led_report
                          = g15data->start_input_report
                          = g15data->backlight_report
                          = report;
			break;
		default:
			break;
		}
		dbg_hid(G15_NAME " Feature report: id=%u type=%u size=%u maxfield=%u report_count=%u\n",
			report->id, report->type, report->size,
			report->maxfield, report->field[0]->report_count);
	}

	if (list_empty(output_report_list)) {
		dev_err(&hdev->dev, "no output report found\n");
		error = -ENODEV;
		goto err_cleanup_input_dev_reg;
	}
	dbg_hid(G15_NAME " output report found\n");

	list_for_each_entry(report, output_report_list, list) {
		dbg_hid(G15_NAME " output report %d found size=%u maxfield=%u\n", report->id, report->size, report->maxfield);
		if (report->maxfield > 0) {
			dbg_hid(G15_NAME " offset=%u size=%u count=%u type=%u\n",
			       report->field[0]->report_offset,
			       report->field[0]->report_size,
			       report->field[0]->report_count,
			       report->field[0]->report_type);
		}
		switch (report->id) {
		case 0x03:
			g15data->output_report_3 = report;
			break;
		}
	}
예제 #25
0
/**
 * Probe method is ran whenever a device is binded to the driver
 *
 * TODO remove goto's
 */
static int razer_core_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
    int retval = 0;
    struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
    struct usb_device *usb_dev = interface_to_usbdev(intf);
    struct razer_core_device *dev = NULL;

    dev = kzalloc(sizeof(struct razer_core_device), GFP_KERNEL);
    if(dev == NULL) {
        dev_err(&intf->dev, "out of memory\n");
        retval = -ENOMEM;
        goto exit;
    }

    // Initialise mutex
    mutex_init(&dev->lock);
    // Setup values
    dev->usb_dev = usb_dev;

    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_version);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wave);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_serial);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_firmware_version);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_type);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_static);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_brightness);
    CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_mode);

    if (retval) {
        goto exit_free;
    }

    dev_set_drvdata(&hdev->dev, dev);
    hid_set_drvdata(hdev, dev);


    retval = hid_parse(hdev);
    if(retval)    {
        hid_err(hdev, "parse failed\n");
        goto exit_free;
    }
    retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
    if (retval) {
        hid_err(hdev, "hw start failed\n");
        goto exit_free;
    }


    usb_disable_autosuspend(usb_dev);
    return 0;
exit:
    return retval;
exit_free:
    kfree(dev);
    return retval;
}
예제 #26
0
static int logi_dj_probe(struct hid_device *hdev,
			 const struct hid_device_id *id)
{
	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
	struct dj_receiver_dev *djrcv_dev;
	int retval;

	if (is_dj_device((struct dj_device *)hdev->driver_data))
		return -ENODEV;

	dbg_hid("%s called for ifnum %d\n", __func__,
		intf->cur_altsetting->desc.bInterfaceNumber);

	if (intf->cur_altsetting->desc.bInterfaceNumber !=
	    LOGITECH_DJ_INTERFACE_NUMBER) {
		dbg_hid("%s: ignoring ifnum %d\n", __func__,
			intf->cur_altsetting->desc.bInterfaceNumber);
		return -ENODEV;
	}

	

	djrcv_dev = kzalloc(sizeof(struct dj_receiver_dev), GFP_KERNEL);
	if (!djrcv_dev) {
		dev_err(&hdev->dev,
			"%s:failed allocating dj_receiver_dev\n", __func__);
		return -ENOMEM;
	}
	djrcv_dev->hdev = hdev;
	INIT_WORK(&djrcv_dev->work, delayedwork_callback);
	spin_lock_init(&djrcv_dev->lock);
	if (kfifo_alloc(&djrcv_dev->notif_fifo,
			DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report),
			GFP_KERNEL)) {
		dev_err(&hdev->dev,
			"%s:failed allocating notif_fifo\n", __func__);
		kfree(djrcv_dev);
		return -ENOMEM;
	}
	hid_set_drvdata(hdev, djrcv_dev);

	retval = hid_parse(hdev);
	if (retval) {
		dev_err(&hdev->dev,
			"%s:parse of interface 2 failed\n", __func__);
		goto hid_parse_fail;
	}

	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
	if (retval) {
		dev_err(&hdev->dev,
			"%s:hid_hw_start returned error\n", __func__);
		goto hid_hw_start_fail;
	}

	retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
	if (retval < 0) {
		dev_err(&hdev->dev,
			"%s:logi_dj_recv_switch_to_dj_mode returned error:%d\n",
			__func__, retval);
		goto switch_to_dj_mode_fail;
	}

	
	retval = hdev->ll_driver->open(hdev);
	if (retval < 0) {
		dev_err(&hdev->dev, "%s:hdev->ll_driver->open returned "
			"error:%d\n", __func__, retval);
		goto llopen_failed;
	}

	retval = logi_dj_recv_query_paired_devices(djrcv_dev);
	if (retval < 0) {
		dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices "
			"error:%d\n", __func__, retval);
		goto logi_dj_recv_query_paired_devices_failed;
	}

	return retval;

logi_dj_recv_query_paired_devices_failed:
	hdev->ll_driver->close(hdev);

llopen_failed:
switch_to_dj_mode_fail:
	hid_hw_stop(hdev);

hid_hw_start_fail:
hid_parse_fail:
	kfifo_free(&djrcv_dev->notif_fifo);
	kfree(djrcv_dev);
	hid_set_drvdata(hdev, NULL);
	return retval;

}
예제 #27
0
파일: hid-lg.c 프로젝트: acton393/linux
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
	__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	unsigned int connect_mask = HID_CONNECT_DEFAULT;
	struct lg_drv_data *drv_data;
	int ret;

	/* G29 only work with the 1st interface */
	if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) &&
	    (iface_num != 0)) {
		dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
		return -ENODEV;
	}

	drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
	if (!drv_data) {
		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
		return -ENOMEM;
	}
	drv_data->quirks = id->driver_data;

	hid_set_drvdata(hdev, (void *)drv_data);

	if (drv_data->quirks & LG_NOGET)
		hdev->quirks |= HID_QUIRK_NOGET;

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "parse failed\n");
		goto err_free;
	}

	if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
		connect_mask &= ~HID_CONNECT_FF;

	ret = hid_hw_start(hdev, connect_mask);
	if (ret) {
		hid_err(hdev, "hw start failed\n");
		goto err_free;
	}

	/* Setup wireless link with Logitech Wii wheel */
	if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
		unsigned char buf[] = { 0x00, 0xAF,  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

		ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
					HID_FEATURE_REPORT, HID_REQ_SET_REPORT);

		if (ret >= 0) {
			/* insert a little delay of 10 jiffies ~ 40ms */
			wait_queue_head_t wait;
			init_waitqueue_head (&wait);
			wait_event_interruptible_timeout(wait, 0,
							 msecs_to_jiffies(40));

			/* Select random Address */
			buf[1] = 0xB2;
			get_random_bytes(&buf[2], 2);

			ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
					HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
		}
	}

	if (drv_data->quirks & LG_FF)
		ret = lgff_init(hdev);
	else if (drv_data->quirks & LG_FF2)
		ret = lg2ff_init(hdev);
	else if (drv_data->quirks & LG_FF3)
		ret = lg3ff_init(hdev);
	else if (drv_data->quirks & LG_FF4)
		ret = lg4ff_init(hdev);

	if (ret)
		goto err_free;

	return 0;
err_free:
	kfree(drv_data);
	return ret;
}
예제 #28
0
static void gfrm_remove(struct hid_device *hdev)
{
	hid_hw_stop(hdev);
	hid_set_drvdata(hdev, NULL);
}
예제 #29
0
static int mousevsc_probe(struct hv_device *device,
			const struct hv_vmbus_device_id *dev_id)
{
	int ret;
	struct mousevsc_dev *input_dev;
	struct hid_device *hid_dev;

	input_dev = mousevsc_alloc_device(device);

	if (!input_dev)
		return -ENOMEM;

	ret = vmbus_open(device->channel,
		INPUTVSC_SEND_RING_BUFFER_SIZE,
		INPUTVSC_RECV_RING_BUFFER_SIZE,
		NULL,
		0,
		mousevsc_on_channel_callback,
		device
		);

	if (ret)
		goto probe_err0;

	ret = mousevsc_connect_to_vsp(device);

	if (ret)
		goto probe_err1;

	/* workaround SA-167 */
	if (input_dev->report_desc[14] == 0x25)
		input_dev->report_desc[14] = 0x29;

	hid_dev = hid_allocate_device();
	if (IS_ERR(hid_dev)) {
		ret = PTR_ERR(hid_dev);
		goto probe_err1;
	}

	hid_dev->ll_driver = &mousevsc_ll_driver;
	hid_dev->driver = &mousevsc_hid_driver;
	hid_dev->bus = BUS_VIRTUAL;
	hid_dev->vendor = input_dev->hid_dev_info.vendor;
	hid_dev->product = input_dev->hid_dev_info.product;
	hid_dev->version = input_dev->hid_dev_info.version;
	input_dev->hid_device = hid_dev;

	sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse");

	hid_set_drvdata(hid_dev, device);

	ret = hid_add_device(hid_dev);
	if (ret)
		goto probe_err1;


	ret = hid_parse(hid_dev);
	if (ret) {
		hid_err(hid_dev, "parse failed\n");
		goto probe_err2;
	}

	ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);

	if (ret) {
		hid_err(hid_dev, "hw start failed\n");
		goto probe_err2;
	}

	input_dev->connected = true;
	input_dev->init_complete = true;

	return ret;

probe_err2:
	hid_destroy_device(hid_dev);

probe_err1:
	vmbus_close(device->channel);

probe_err0:
	mousevsc_free_device(input_dev);

	return ret;
}
예제 #30
0
파일: hid-lenovo.c 프로젝트: 3null/linux
static int lenovo_probe_tpkbd(struct hid_device *hdev)
{
	struct device *dev = &hdev->dev;
	struct lenovo_drvdata_tpkbd *data_pointer;
	size_t name_sz = strlen(dev_name(dev)) + 16;
	char *name_mute, *name_micmute;
	int i;
	int ret;

	/*
	 * Only register extra settings against subdevice where input_mapping
	 * set drvdata to 1, i.e. the trackpoint.
	 */
	if (!hid_get_drvdata(hdev))
		return 0;

	hid_set_drvdata(hdev, NULL);

	/* Validate required reports. */
	for (i = 0; i < 4; i++) {
		if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
			return -ENODEV;
	}
	if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
		return -ENODEV;

	ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd);
	if (ret)
		hid_warn(hdev, "Could not create sysfs group: %d\n", ret);

	data_pointer = devm_kzalloc(&hdev->dev,
				    sizeof(struct lenovo_drvdata_tpkbd),
				    GFP_KERNEL);
	if (data_pointer == NULL) {
		hid_err(hdev, "Could not allocate memory for driver data\n");
		return -ENOMEM;
	}

	// set same default values as windows driver
	data_pointer->sensitivity = 0xa0;
	data_pointer->press_speed = 0x38;

	name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
	name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
	if (name_mute == NULL || name_micmute == NULL) {
		hid_err(hdev, "Could not allocate memory for led data\n");
		return -ENOMEM;
	}
	snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
	snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));

	hid_set_drvdata(hdev, data_pointer);

	data_pointer->led_mute.name = name_mute;
	data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd;
	data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd;
	data_pointer->led_mute.dev = dev;
	led_classdev_register(dev, &data_pointer->led_mute);

	data_pointer->led_micmute.name = name_micmute;
	data_pointer->led_micmute.brightness_get =
		lenovo_led_brightness_get_tpkbd;
	data_pointer->led_micmute.brightness_set =
		lenovo_led_brightness_set_tpkbd;
	data_pointer->led_micmute.dev = dev;
	led_classdev_register(dev, &data_pointer->led_micmute);

	lenovo_features_set_tpkbd(hdev);

	return 0;
}