aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-07-03 11:23:24 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:53:45 -0400
commit294e289602d7827f1389b081535fda3b7553a651 (patch)
tree3920e0586c244724d6953756275d3a9fc3325e25 /drivers/media/video/pwc
parentc11271349ad5d4647e69e511fc481b2dd390efc4 (diff)
[media] pwc: Add v4l2 controls for pan/tilt on Logitech QuickCam Orbit/Sphere
This makes the API for this: 1) v4l2 spec compliant 2) match that of the UVC Logitech QuickCam Sphere models For now this operates in parellel to the sysfs interface for this, but the intend is to deprecate the sysfs interface and remove it. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c2
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c56
-rw-r--r--drivers/media/video/pwc/pwc.h9
3 files changed, 66 insertions, 1 deletions
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 8e0cc537e1e4..d09413c44c86 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -165,7 +165,7 @@ static inline int send_video_command(struct pwc_device *pdev,
165 buf, buflen); 165 buf, buflen);
166} 166}
167 167
168static inline int send_control_msg(struct pwc_device *pdev, 168int send_control_msg(struct pwc_device *pdev,
169 u8 request, u16 value, void *buf, int buflen) 169 u8 request, u16 value, void *buf, int buflen)
170{ 170{
171 return _send_control_msg(pdev, 171 return _send_control_msg(pdev,
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 537657283e79..e9a0e94b9995 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -338,6 +338,22 @@ int pwc_init_controls(struct pwc_device *pdev)
338 if (pdev->restore_factory) 338 if (pdev->restore_factory)
339 pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE; 339 pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
340 340
341 if (!pdev->features & FEATURE_MOTOR_PANTILT)
342 return hdl->error;
343
344 /* Motor pan / tilt / reset */
345 pdev->motor_pan = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
346 V4L2_CID_PAN_RELATIVE, -4480, 4480, 64, 0);
347 if (!pdev->motor_pan)
348 return hdl->error;
349 pdev->motor_tilt = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
350 V4L2_CID_TILT_RELATIVE, -1920, 1920, 64, 0);
351 pdev->motor_pan_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
352 V4L2_CID_PAN_RESET, 0, 0, 0, 0);
353 pdev->motor_tilt_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
354 V4L2_CID_TILT_RESET, 0, 0, 0, 0);
355 v4l2_ctrl_cluster(4, &pdev->motor_pan);
356
341 return hdl->error; 357 return hdl->error;
342} 358}
343 359
@@ -764,6 +780,43 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev)
764 return ret; 780 return ret;
765} 781}
766 782
783static int pwc_set_motor(struct pwc_device *pdev)
784{
785 int ret;
786 u8 buf[4];
787
788 buf[0] = 0;
789 if (pdev->motor_pan_reset->is_new)
790 buf[0] |= 0x01;
791 if (pdev->motor_tilt_reset->is_new)
792 buf[0] |= 0x02;
793 if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
794 ret = send_control_msg(pdev, SET_MPT_CTL,
795 PT_RESET_CONTROL_FORMATTER, buf, 1);
796 if (ret < 0)
797 return ret;
798 }
799
800 memset(buf, 0, sizeof(buf));
801 if (pdev->motor_pan->is_new) {
802 buf[0] = pdev->motor_pan->val & 0xFF;
803 buf[1] = (pdev->motor_pan->val >> 8);
804 }
805 if (pdev->motor_tilt->is_new) {
806 buf[2] = pdev->motor_tilt->val & 0xFF;
807 buf[3] = (pdev->motor_tilt->val >> 8);
808 }
809 if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
810 ret = send_control_msg(pdev, SET_MPT_CTL,
811 PT_RELATIVE_CONTROL_FORMATTER,
812 buf, sizeof(buf));
813 if (ret < 0)
814 return ret;
815 }
816
817 return 0;
818}
819
767static int pwc_s_ctrl(struct v4l2_ctrl *ctrl) 820static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
768{ 821{
769 struct pwc_device *pdev = 822 struct pwc_device *pdev =
@@ -859,6 +912,9 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
859 ret = pwc_button_ctrl(pdev, 912 ret = pwc_button_ctrl(pdev,
860 RESTORE_FACTORY_DEFAULTS_FORMATTER); 913 RESTORE_FACTORY_DEFAULTS_FORMATTER);
861 break; 914 break;
915 case V4L2_CID_PAN_RELATIVE:
916 ret = pwc_set_motor(pdev);
917 break;
862 default: 918 default:
863 ret = -EINVAL; 919 ret = -EINVAL;
864 } 920 }
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index e02dbf745155..8f3607be5a71 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -326,6 +326,13 @@ struct pwc_device
326 struct v4l2_ctrl *save_user; 326 struct v4l2_ctrl *save_user;
327 struct v4l2_ctrl *restore_user; 327 struct v4l2_ctrl *restore_user;
328 struct v4l2_ctrl *restore_factory; 328 struct v4l2_ctrl *restore_factory;
329 struct {
330 /* motor control cluster */
331 struct v4l2_ctrl *motor_pan;
332 struct v4l2_ctrl *motor_tilt;
333 struct v4l2_ctrl *motor_pan_reset;
334 struct v4l2_ctrl *motor_tilt_reset;
335 };
329 /* CODEC3 models have both gain and exposure controlled by autogain */ 336 /* CODEC3 models have both gain and exposure controlled by autogain */
330 struct v4l2_ctrl *autogain_expo_cluster[3]; 337 struct v4l2_ctrl *autogain_expo_cluster[3];
331}; 338};
@@ -350,6 +357,8 @@ extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
350extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt); 357extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
351extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); 358extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
352extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); 359extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
360extern int send_control_msg(struct pwc_device *pdev,
361 u8 request, u16 value, void *buf, int buflen);
353 362
354/* Control get / set helpers */ 363/* Control get / set helpers */
355int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data); 364int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data);