diff options
Diffstat (limited to 'drivers/media/usb/uvc/uvc_ctrl.c')
-rw-r--r-- | drivers/media/usb/uvc/uvc_ctrl.c | 114 |
1 files changed, 70 insertions, 44 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 20397aba6849..102594ec3e97 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c | |||
@@ -366,10 +366,10 @@ static struct uvc_menu_info exposure_auto_controls[] = { | |||
366 | { 8, "Aperture Priority Mode" }, | 366 | { 8, "Aperture Priority Mode" }, |
367 | }; | 367 | }; |
368 | 368 | ||
369 | static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, | 369 | static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, |
370 | __u8 query, const __u8 *data) | 370 | u8 query, const u8 *data) |
371 | { | 371 | { |
372 | __s8 zoom = (__s8)data[0]; | 372 | s8 zoom = (s8)data[0]; |
373 | 373 | ||
374 | switch (query) { | 374 | switch (query) { |
375 | case UVC_GET_CUR: | 375 | case UVC_GET_CUR: |
@@ -385,17 +385,17 @@ static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, | |||
385 | } | 385 | } |
386 | 386 | ||
387 | static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping, | 387 | static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping, |
388 | __s32 value, __u8 *data) | 388 | s32 value, u8 *data) |
389 | { | 389 | { |
390 | data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; | 390 | data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; |
391 | data[2] = min((int)abs(value), 0xff); | 391 | data[2] = min((int)abs(value), 0xff); |
392 | } | 392 | } |
393 | 393 | ||
394 | static __s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, | 394 | static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, |
395 | __u8 query, const __u8 *data) | 395 | u8 query, const u8 *data) |
396 | { | 396 | { |
397 | unsigned int first = mapping->offset / 8; | 397 | unsigned int first = mapping->offset / 8; |
398 | __s8 rel = (__s8)data[first]; | 398 | s8 rel = (s8)data[first]; |
399 | 399 | ||
400 | switch (query) { | 400 | switch (query) { |
401 | case UVC_GET_CUR: | 401 | case UVC_GET_CUR: |
@@ -412,7 +412,7 @@ static __s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, | |||
412 | } | 412 | } |
413 | 413 | ||
414 | static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping, | 414 | static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping, |
415 | __s32 value, __u8 *data) | 415 | s32 value, u8 *data) |
416 | { | 416 | { |
417 | unsigned int first = mapping->offset / 8; | 417 | unsigned int first = mapping->offset / 8; |
418 | 418 | ||
@@ -745,17 +745,17 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { | |||
745 | * Utility functions | 745 | * Utility functions |
746 | */ | 746 | */ |
747 | 747 | ||
748 | static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) | 748 | static inline u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) |
749 | { | 749 | { |
750 | return ctrl->uvc_data + id * ctrl->info.size; | 750 | return ctrl->uvc_data + id * ctrl->info.size; |
751 | } | 751 | } |
752 | 752 | ||
753 | static inline int uvc_test_bit(const __u8 *data, int bit) | 753 | static inline int uvc_test_bit(const u8 *data, int bit) |
754 | { | 754 | { |
755 | return (data[bit >> 3] >> (bit & 7)) & 1; | 755 | return (data[bit >> 3] >> (bit & 7)) & 1; |
756 | } | 756 | } |
757 | 757 | ||
758 | static inline void uvc_clear_bit(__u8 *data, int bit) | 758 | static inline void uvc_clear_bit(u8 *data, int bit) |
759 | { | 759 | { |
760 | data[bit >> 3] &= ~(1 << (bit & 7)); | 760 | data[bit >> 3] &= ~(1 << (bit & 7)); |
761 | } | 761 | } |
@@ -765,20 +765,20 @@ static inline void uvc_clear_bit(__u8 *data, int bit) | |||
765 | * a signed 32bit integer. Sign extension will be performed if the mapping | 765 | * a signed 32bit integer. Sign extension will be performed if the mapping |
766 | * references a signed data type. | 766 | * references a signed data type. |
767 | */ | 767 | */ |
768 | static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, | 768 | static s32 uvc_get_le_value(struct uvc_control_mapping *mapping, |
769 | __u8 query, const __u8 *data) | 769 | u8 query, const u8 *data) |
770 | { | 770 | { |
771 | int bits = mapping->size; | 771 | int bits = mapping->size; |
772 | int offset = mapping->offset; | 772 | int offset = mapping->offset; |
773 | __s32 value = 0; | 773 | s32 value = 0; |
774 | __u8 mask; | 774 | u8 mask; |
775 | 775 | ||
776 | data += offset / 8; | 776 | data += offset / 8; |
777 | offset &= 7; | 777 | offset &= 7; |
778 | mask = ((1LL << bits) - 1) << offset; | 778 | mask = ((1LL << bits) - 1) << offset; |
779 | 779 | ||
780 | for (; bits > 0; data++) { | 780 | for (; bits > 0; data++) { |
781 | __u8 byte = *data & mask; | 781 | u8 byte = *data & mask; |
782 | value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); | 782 | value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); |
783 | bits -= 8 - (offset > 0 ? offset : 0); | 783 | bits -= 8 - (offset > 0 ? offset : 0); |
784 | offset -= 8; | 784 | offset -= 8; |
@@ -796,11 +796,11 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, | |||
796 | * in the little-endian data stored at 'data' to the value 'value'. | 796 | * in the little-endian data stored at 'data' to the value 'value'. |
797 | */ | 797 | */ |
798 | static void uvc_set_le_value(struct uvc_control_mapping *mapping, | 798 | static void uvc_set_le_value(struct uvc_control_mapping *mapping, |
799 | __s32 value, __u8 *data) | 799 | s32 value, u8 *data) |
800 | { | 800 | { |
801 | int bits = mapping->size; | 801 | int bits = mapping->size; |
802 | int offset = mapping->offset; | 802 | int offset = mapping->offset; |
803 | __u8 mask; | 803 | u8 mask; |
804 | 804 | ||
805 | /* According to the v4l2 spec, writing any value to a button control | 805 | /* According to the v4l2 spec, writing any value to a button control |
806 | * should result in the action belonging to the button control being | 806 | * should result in the action belonging to the button control being |
@@ -826,13 +826,13 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping, | |||
826 | * Terminal and unit management | 826 | * Terminal and unit management |
827 | */ | 827 | */ |
828 | 828 | ||
829 | static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; | 829 | static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; |
830 | static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; | 830 | static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; |
831 | static const __u8 uvc_media_transport_input_guid[16] = | 831 | static const u8 uvc_media_transport_input_guid[16] = |
832 | UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; | 832 | UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; |
833 | 833 | ||
834 | static int uvc_entity_match_guid(const struct uvc_entity *entity, | 834 | static int uvc_entity_match_guid(const struct uvc_entity *entity, |
835 | const __u8 guid[16]) | 835 | const u8 guid[16]) |
836 | { | 836 | { |
837 | switch (UVC_ENTITY_TYPE(entity)) { | 837 | switch (UVC_ENTITY_TYPE(entity)) { |
838 | case UVC_ITT_CAMERA: | 838 | case UVC_ITT_CAMERA: |
@@ -857,7 +857,7 @@ static int uvc_entity_match_guid(const struct uvc_entity *entity, | |||
857 | * UVC Controls | 857 | * UVC Controls |
858 | */ | 858 | */ |
859 | 859 | ||
860 | static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | 860 | static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id, |
861 | struct uvc_control_mapping **mapping, struct uvc_control **control, | 861 | struct uvc_control_mapping **mapping, struct uvc_control **control, |
862 | int next) | 862 | int next) |
863 | { | 863 | { |
@@ -890,7 +890,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
890 | } | 890 | } |
891 | 891 | ||
892 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | 892 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, |
893 | __u32 v4l2_id, struct uvc_control_mapping **mapping) | 893 | u32 v4l2_id, struct uvc_control_mapping **mapping) |
894 | { | 894 | { |
895 | struct uvc_control *ctrl = NULL; | 895 | struct uvc_control *ctrl = NULL; |
896 | struct uvc_entity *entity; | 896 | struct uvc_entity *entity; |
@@ -1019,10 +1019,10 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
1019 | struct uvc_menu_info *menu; | 1019 | struct uvc_menu_info *menu; |
1020 | unsigned int i; | 1020 | unsigned int i; |
1021 | 1021 | ||
1022 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 1022 | memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); |
1023 | v4l2_ctrl->id = mapping->id; | 1023 | v4l2_ctrl->id = mapping->id; |
1024 | v4l2_ctrl->type = mapping->v4l2_type; | 1024 | v4l2_ctrl->type = mapping->v4l2_type; |
1025 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); | 1025 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof(v4l2_ctrl->name)); |
1026 | v4l2_ctrl->flags = 0; | 1026 | v4l2_ctrl->flags = 0; |
1027 | 1027 | ||
1028 | if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) | 1028 | if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) |
@@ -1182,7 +1182,7 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | |||
1182 | } | 1182 | } |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | 1185 | strlcpy(query_menu->name, menu_info->name, sizeof(query_menu->name)); |
1186 | 1186 | ||
1187 | done: | 1187 | done: |
1188 | mutex_unlock(&chain->ctrl_mutex); | 1188 | mutex_unlock(&chain->ctrl_mutex); |
@@ -1590,6 +1590,36 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1590 | * Dynamic controls | 1590 | * Dynamic controls |
1591 | */ | 1591 | */ |
1592 | 1592 | ||
1593 | /* | ||
1594 | * Retrieve flags for a given control | ||
1595 | */ | ||
1596 | static int uvc_ctrl_get_flags(struct uvc_device *dev, | ||
1597 | const struct uvc_control *ctrl, | ||
1598 | struct uvc_control_info *info) | ||
1599 | { | ||
1600 | u8 *data; | ||
1601 | int ret; | ||
1602 | |||
1603 | data = kmalloc(1, GFP_KERNEL); | ||
1604 | if (data == NULL) | ||
1605 | return -ENOMEM; | ||
1606 | |||
1607 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, | ||
1608 | info->selector, data, 1); | ||
1609 | if (!ret) | ||
1610 | info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX | ||
1611 | | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF | ||
1612 | | (data[0] & UVC_CONTROL_CAP_GET ? | ||
1613 | UVC_CTRL_FLAG_GET_CUR : 0) | ||
1614 | | (data[0] & UVC_CONTROL_CAP_SET ? | ||
1615 | UVC_CTRL_FLAG_SET_CUR : 0) | ||
1616 | | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? | ||
1617 | UVC_CTRL_FLAG_AUTO_UPDATE : 0); | ||
1618 | |||
1619 | kfree(data); | ||
1620 | return ret; | ||
1621 | } | ||
1622 | |||
1593 | static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev, | 1623 | static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev, |
1594 | const struct uvc_control *ctrl, struct uvc_control_info *info) | 1624 | const struct uvc_control *ctrl, struct uvc_control_info *info) |
1595 | { | 1625 | { |
@@ -1659,25 +1689,14 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev, | |||
1659 | 1689 | ||
1660 | info->size = le16_to_cpup((__le16 *)data); | 1690 | info->size = le16_to_cpup((__le16 *)data); |
1661 | 1691 | ||
1662 | /* Query the control information (GET_INFO) */ | 1692 | ret = uvc_ctrl_get_flags(dev, ctrl, info); |
1663 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, | ||
1664 | info->selector, data, 1); | ||
1665 | if (ret < 0) { | 1693 | if (ret < 0) { |
1666 | uvc_trace(UVC_TRACE_CONTROL, | 1694 | uvc_trace(UVC_TRACE_CONTROL, |
1667 | "GET_INFO failed on control %pUl/%u (%d).\n", | 1695 | "Failed to get flags for control %pUl/%u (%d).\n", |
1668 | info->entity, info->selector, ret); | 1696 | info->entity, info->selector, ret); |
1669 | goto done; | 1697 | goto done; |
1670 | } | 1698 | } |
1671 | 1699 | ||
1672 | info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX | ||
1673 | | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF | ||
1674 | | (data[0] & UVC_CONTROL_CAP_GET ? | ||
1675 | UVC_CTRL_FLAG_GET_CUR : 0) | ||
1676 | | (data[0] & UVC_CONTROL_CAP_SET ? | ||
1677 | UVC_CTRL_FLAG_SET_CUR : 0) | ||
1678 | | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? | ||
1679 | UVC_CTRL_FLAG_AUTO_UPDATE : 0); | ||
1680 | |||
1681 | uvc_ctrl_fixup_xu_info(dev, ctrl, info); | 1700 | uvc_ctrl_fixup_xu_info(dev, ctrl, info); |
1682 | 1701 | ||
1683 | uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " | 1702 | uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " |
@@ -1723,9 +1742,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1723 | struct uvc_entity *entity; | 1742 | struct uvc_entity *entity; |
1724 | struct uvc_control *ctrl; | 1743 | struct uvc_control *ctrl; |
1725 | unsigned int i, found = 0; | 1744 | unsigned int i, found = 0; |
1726 | __u32 reqflags; | 1745 | u32 reqflags; |
1727 | __u16 size; | 1746 | u16 size; |
1728 | __u8 *data = NULL; | 1747 | u8 *data = NULL; |
1729 | int ret; | 1748 | int ret; |
1730 | 1749 | ||
1731 | /* Find the extension unit. */ | 1750 | /* Find the extension unit. */ |
@@ -1902,6 +1921,13 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, | |||
1902 | goto done; | 1921 | goto done; |
1903 | } | 1922 | } |
1904 | 1923 | ||
1924 | /* | ||
1925 | * Retrieve control flags from the device. Ignore errors and work with | ||
1926 | * default flag values from the uvc_ctrl array when the device doesn't | ||
1927 | * properly implement GET_INFO on standard controls. | ||
1928 | */ | ||
1929 | uvc_ctrl_get_flags(dev, ctrl, &ctrl->info); | ||
1930 | |||
1905 | ctrl->initialized = 1; | 1931 | ctrl->initialized = 1; |
1906 | 1932 | ||
1907 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " | 1933 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " |
@@ -2150,7 +2176,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) | |||
2150 | list_for_each_entry(entity, &dev->entities, list) { | 2176 | list_for_each_entry(entity, &dev->entities, list) { |
2151 | struct uvc_control *ctrl; | 2177 | struct uvc_control *ctrl; |
2152 | unsigned int bControlSize = 0, ncontrols; | 2178 | unsigned int bControlSize = 0, ncontrols; |
2153 | __u8 *bmControls = NULL; | 2179 | u8 *bmControls = NULL; |
2154 | 2180 | ||
2155 | if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { | 2181 | if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { |
2156 | bmControls = entity->extension.bmControls; | 2182 | bmControls = entity->extension.bmControls; |