diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2016-02-12 11:27:41 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2016-02-16 14:40:37 -0500 |
commit | c58ac3a88d1e8a44fed152e80bf525a66a5647e2 (patch) | |
tree | a62350ca600235e767894b2082656e07d82e4e2e | |
parent | 7e129783b02081a866a7264473bc784cdfe69265 (diff) |
HID: wacom: break out parsing of device and registering of input
Simplifies the .probe() and will allow to reuse this path in the future.
Few things are reshuffled in .probe():
- init wacom struct earlier
- then retrieve the report descriptor
- then parse it and allocate/register inputs.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/wacom_sys.c | 136 |
1 files changed, 75 insertions, 61 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 5cb21dd91094..92a2c81c7bdf 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -1685,61 +1685,21 @@ static void wacom_update_name(struct wacom *wacom) | |||
1685 | "%s Pad", name); | 1685 | "%s Pad", name); |
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | static int wacom_probe(struct hid_device *hdev, | 1688 | static int wacom_parse_and_register(struct wacom *wacom) |
1689 | const struct hid_device_id *id) | ||
1690 | { | 1689 | { |
1691 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 1690 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
1692 | struct usb_device *dev = interface_to_usbdev(intf); | 1691 | struct wacom_features *features = &wacom_wac->features; |
1693 | struct wacom *wacom; | 1692 | struct hid_device *hdev = wacom->hdev; |
1694 | struct wacom_wac *wacom_wac; | ||
1695 | struct wacom_features *features; | ||
1696 | int error; | 1693 | int error; |
1697 | unsigned int connect_mask = HID_CONNECT_HIDRAW; | 1694 | unsigned int connect_mask = HID_CONNECT_HIDRAW; |
1698 | 1695 | ||
1699 | if (!id->driver_data) | ||
1700 | return -EINVAL; | ||
1701 | |||
1702 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
1703 | |||
1704 | /* hid-core sets this quirk for the boot interface */ | ||
1705 | hdev->quirks &= ~HID_QUIRK_NOGET; | ||
1706 | |||
1707 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | ||
1708 | if (!wacom) | ||
1709 | return -ENOMEM; | ||
1710 | |||
1711 | hid_set_drvdata(hdev, wacom); | ||
1712 | wacom->hdev = hdev; | ||
1713 | |||
1714 | /* ask for the report descriptor to be loaded by HID */ | ||
1715 | error = hid_parse(hdev); | ||
1716 | if (error) { | ||
1717 | hid_err(hdev, "parse failed\n"); | ||
1718 | goto fail_parse; | ||
1719 | } | ||
1720 | |||
1721 | wacom_wac = &wacom->wacom_wac; | ||
1722 | wacom_wac->features = *((struct wacom_features *)id->driver_data); | ||
1723 | features = &wacom_wac->features; | ||
1724 | features->pktlen = wacom_compute_pktlen(hdev); | 1696 | features->pktlen = wacom_compute_pktlen(hdev); |
1725 | if (features->pktlen > WACOM_PKGLEN_MAX) { | 1697 | if (features->pktlen > WACOM_PKGLEN_MAX) |
1726 | error = -EINVAL; | 1698 | return -EINVAL; |
1727 | goto fail_pktlen; | ||
1728 | } | ||
1729 | |||
1730 | if (features->check_for_hid_type && features->hid_type != hdev->type) { | ||
1731 | error = -ENODEV; | ||
1732 | goto fail_type; | ||
1733 | } | ||
1734 | |||
1735 | wacom->usbdev = dev; | ||
1736 | wacom->intf = intf; | ||
1737 | mutex_init(&wacom->lock); | ||
1738 | INIT_WORK(&wacom->work, wacom_wireless_work); | ||
1739 | 1699 | ||
1740 | error = wacom_allocate_inputs(wacom); | 1700 | error = wacom_allocate_inputs(wacom); |
1741 | if (error) | 1701 | if (error) |
1742 | goto fail_allocate_inputs; | 1702 | return error; |
1743 | 1703 | ||
1744 | /* | 1704 | /* |
1745 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it | 1705 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it |
@@ -1752,7 +1712,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
1752 | } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) && | 1712 | } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) && |
1753 | (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) { | 1713 | (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) { |
1754 | error = -ENODEV; | 1714 | error = -ENODEV; |
1755 | goto fail_shared_data; | 1715 | goto fail_allocate_inputs; |
1756 | } | 1716 | } |
1757 | } | 1717 | } |
1758 | 1718 | ||
@@ -1772,7 +1732,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
1772 | error ? "Ignoring" : "Assuming pen"); | 1732 | error ? "Ignoring" : "Assuming pen"); |
1773 | 1733 | ||
1774 | if (error) | 1734 | if (error) |
1775 | goto fail_shared_data; | 1735 | goto fail_parsed; |
1776 | 1736 | ||
1777 | features->device_type |= WACOM_DEVICETYPE_PEN; | 1737 | features->device_type |= WACOM_DEVICETYPE_PEN; |
1778 | } | 1738 | } |
@@ -1796,14 +1756,6 @@ static int wacom_probe(struct hid_device *hdev, | |||
1796 | if (error) | 1756 | if (error) |
1797 | goto fail_register_inputs; | 1757 | goto fail_register_inputs; |
1798 | 1758 | ||
1799 | if (hdev->bus == BUS_BLUETOOTH) { | ||
1800 | error = device_create_file(&hdev->dev, &dev_attr_speed); | ||
1801 | if (error) | ||
1802 | hid_warn(hdev, | ||
1803 | "can't create sysfs speed attribute err: %d\n", | ||
1804 | error); | ||
1805 | } | ||
1806 | |||
1807 | if (features->type == HID_GENERIC) | 1759 | if (features->type == HID_GENERIC) |
1808 | connect_mask |= HID_CONNECT_DRIVER; | 1760 | connect_mask |= HID_CONNECT_DRIVER; |
1809 | 1761 | ||
@@ -1844,18 +1796,80 @@ static int wacom_probe(struct hid_device *hdev, | |||
1844 | return 0; | 1796 | return 0; |
1845 | 1797 | ||
1846 | fail_hw_start: | 1798 | fail_hw_start: |
1847 | if (hdev->bus == BUS_BLUETOOTH) | 1799 | hid_hw_stop(hdev); |
1848 | device_remove_file(&hdev->dev, &dev_attr_speed); | ||
1849 | fail_register_inputs: | 1800 | fail_register_inputs: |
1850 | wacom_clean_inputs(wacom); | 1801 | wacom_clean_inputs(wacom); |
1851 | wacom_destroy_battery(wacom); | 1802 | wacom_destroy_battery(wacom); |
1852 | fail_battery: | 1803 | fail_battery: |
1853 | wacom_remove_shared_data(wacom); | 1804 | wacom_remove_shared_data(wacom); |
1854 | fail_shared_data: | 1805 | fail_shared_data: |
1855 | wacom_clean_inputs(wacom); | 1806 | fail_parsed: |
1856 | fail_allocate_inputs: | 1807 | fail_allocate_inputs: |
1808 | wacom_clean_inputs(wacom); | ||
1809 | return error; | ||
1810 | } | ||
1811 | |||
1812 | static int wacom_probe(struct hid_device *hdev, | ||
1813 | const struct hid_device_id *id) | ||
1814 | { | ||
1815 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
1816 | struct usb_device *dev = interface_to_usbdev(intf); | ||
1817 | struct wacom *wacom; | ||
1818 | struct wacom_wac *wacom_wac; | ||
1819 | struct wacom_features *features; | ||
1820 | int error; | ||
1821 | |||
1822 | if (!id->driver_data) | ||
1823 | return -EINVAL; | ||
1824 | |||
1825 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
1826 | |||
1827 | /* hid-core sets this quirk for the boot interface */ | ||
1828 | hdev->quirks &= ~HID_QUIRK_NOGET; | ||
1829 | |||
1830 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | ||
1831 | if (!wacom) | ||
1832 | return -ENOMEM; | ||
1833 | |||
1834 | hid_set_drvdata(hdev, wacom); | ||
1835 | wacom->hdev = hdev; | ||
1836 | |||
1837 | wacom_wac = &wacom->wacom_wac; | ||
1838 | wacom_wac->features = *((struct wacom_features *)id->driver_data); | ||
1839 | features = &wacom_wac->features; | ||
1840 | |||
1841 | if (features->check_for_hid_type && features->hid_type != hdev->type) { | ||
1842 | error = -ENODEV; | ||
1843 | goto fail_type; | ||
1844 | } | ||
1845 | |||
1846 | wacom->usbdev = dev; | ||
1847 | wacom->intf = intf; | ||
1848 | mutex_init(&wacom->lock); | ||
1849 | INIT_WORK(&wacom->work, wacom_wireless_work); | ||
1850 | |||
1851 | /* ask for the report descriptor to be loaded by HID */ | ||
1852 | error = hid_parse(hdev); | ||
1853 | if (error) { | ||
1854 | hid_err(hdev, "parse failed\n"); | ||
1855 | goto fail_parse; | ||
1856 | } | ||
1857 | |||
1858 | error = wacom_parse_and_register(wacom); | ||
1859 | if (error) | ||
1860 | goto fail_parse; | ||
1861 | |||
1862 | if (hdev->bus == BUS_BLUETOOTH) { | ||
1863 | error = device_create_file(&hdev->dev, &dev_attr_speed); | ||
1864 | if (error) | ||
1865 | hid_warn(hdev, | ||
1866 | "can't create sysfs speed attribute err: %d\n", | ||
1867 | error); | ||
1868 | } | ||
1869 | |||
1870 | return 0; | ||
1871 | |||
1857 | fail_type: | 1872 | fail_type: |
1858 | fail_pktlen: | ||
1859 | fail_parse: | 1873 | fail_parse: |
1860 | kfree(wacom); | 1874 | kfree(wacom); |
1861 | hid_set_drvdata(hdev, NULL); | 1875 | hid_set_drvdata(hdev, NULL); |