2 Phlips webcam INDI driver
3 Copyright (C) 2003-2005 by Jasem Mutlaq
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 2005.04.29 JM: There is no need for this file for Video 4 Linux 2. It is kept for V4L 1 compatiblity.
23 #include "v4lphilips.h"
24 #include "webcam/pwc-ioctl.h"
26 V4L_Philips::V4L_Philips() : V4L_Driver()
31 V4L_Philips::~V4L_Philips()
36 void V4L_Philips::initCamBase()
38 #ifdef HAVE_LINUX_VIDEODEV2_H
39 v4l_base
= new V4L2_Base();
41 v4l_pwc
= new V4L1_PWC();
42 v4l_base
= (V4L1_Base
*) v4l_pwc
;
46 void V4L_Philips::initProperties(const char *dev
)
50 V4L_Driver::initProperties(dev
);
52 fillSwitch(&BackLightS
[0], "ON", "", ISS_OFF
);
53 fillSwitch(&BackLightS
[1], "OFF", "", ISS_ON
);
54 fillSwitchVector(&BackLightSP
, BackLightS
, NARRAY(BackLightS
), dev
, "Back Light", "", IMAGE_CONTROL
, IP_RW
, ISR_1OFMANY
, 0 , IPS_IDLE
);
56 fillSwitch(&AntiFlickerS
[0], "ON", "", ISS_OFF
);
57 fillSwitch(&AntiFlickerS
[1], "OFF", "", ISS_ON
);
58 fillSwitchVector(&AntiFlickerSP
, AntiFlickerS
, NARRAY(AntiFlickerS
), dev
, "Anti Flicker", "", IMAGE_CONTROL
, IP_RW
, ISR_1OFMANY
, 0 , IPS_IDLE
);
60 fillSwitch(&NoiseReductionS
[0], "None", "", ISS_ON
);
61 fillSwitch(&NoiseReductionS
[1], "Low", "", ISS_OFF
);
62 fillSwitch(&NoiseReductionS
[2], "Medium", "", ISS_OFF
);
63 fillSwitch(&NoiseReductionS
[3], "High", "", ISS_OFF
);
64 fillSwitchVector(&NoiseReductionSP
, NoiseReductionS
, NARRAY(NoiseReductionS
), dev
, "Noise Reduction", "", IMAGE_CONTROL
, IP_RW
, ISR_1OFMANY
, 0, IPS_IDLE
);
66 fillSwitch(&CamSettingS
[0], "Save", "", ISS_OFF
);
67 fillSwitch(&CamSettingS
[1], "Restore", "", ISS_OFF
);
68 fillSwitch(&CamSettingS
[2], "Factory", "", ISS_OFF
);
69 fillSwitchVector(&CamSettingSP
, CamSettingS
, NARRAY(CamSettingS
), dev
, "Settings", "", IMAGE_CONTROL
, IP_RW
, ISR_1OFMANY
, 0, IPS_IDLE
);
71 fillSwitch(&WhiteBalanceModeS
[0], "Auto" , "", ISS_ON
);
72 fillSwitch(&WhiteBalanceModeS
[1], "Manual" , "", ISS_OFF
);
73 fillSwitch(&WhiteBalanceModeS
[2], "Indoor" , "", ISS_OFF
);
74 fillSwitch(&WhiteBalanceModeS
[3], "Outdoor" , "", ISS_OFF
);
75 fillSwitch(&WhiteBalanceModeS
[4], "Fluorescent" , "", ISS_OFF
);
77 fillSwitchVector(&WhiteBalanceModeSP
, WhiteBalanceModeS
, NARRAY(WhiteBalanceModeS
), dev
, "White Balance Mode", "", IMAGE_CONTROL
, IP_RW
, ISR_1OFMANY
, 0, IPS_IDLE
);
79 fillNumber(&WhiteBalanceN
[0], "Manual Red", "", "%0.f", 0., 256., 1., 0.);
80 fillNumber(&WhiteBalanceN
[1], "Manual Blue", "", "%0.f", 0., 256., 1., 0.);
81 fillNumberVector(&WhiteBalanceNP
, WhiteBalanceN
, NARRAY(WhiteBalanceN
), dev
, "White Balance", "", IMAGE_CONTROL
, IP_RW
, 60, IPS_IDLE
);
83 fillNumber(&ShutterSpeedN
[0], "Speed", "", "%0.f", 0., 65535., 100., 0.);
84 fillNumberVector(&ShutterSpeedNP
, ShutterSpeedN
, NARRAY(ShutterSpeedN
), dev
, "Shutter Speed", "", COMM_GROUP
, IP_RW
, 60, IPS_IDLE
);
88 void V4L_Philips::ISGetProperties (const char *dev
)
91 if (dev
&& strcmp (device_name
, dev
))
94 #ifdef HAVE_LINUX_VIDEODEV2_H
95 V4L_Driver::ISGetProperties(dev
);
100 IDDefSwitch(&PowerSP
, NULL
);
101 IDDefText(&PortTP
, NULL
);
102 IDDefText(&camNameTP
, NULL
);
103 IDDefSwitch(&StreamSP
, NULL
);
104 IDDefNumber(&FrameRateNP
, NULL
);
105 IDDefNumber(&ExposeTimeNP
, NULL
);
106 IDDefNumber(&ShutterSpeedNP
, NULL
);
107 IDDefBLOB(&imageBP
, NULL
);
110 IDDefSwitch(&CompressSP
, NULL
);
111 IDDefSwitch(&ImageTypeSP
, NULL
);
112 IDDefNumber(&ImageSizeNP
, NULL
);
113 IDDefNumber(&ImageAdjustNP
, NULL
);
116 IDDefSwitch(&WhiteBalanceModeSP
, NULL
);
117 IDDefNumber(&WhiteBalanceNP
, NULL
);
118 IDDefSwitch(&BackLightSP
, NULL
);
119 IDDefSwitch(&AntiFlickerSP
, NULL
);
120 IDDefSwitch(&NoiseReductionSP
, NULL
);
121 IDDefSwitch(&CamSettingSP
, NULL
);
125 void V4L_Philips::ISNewSwitch (const char *dev
, const char *name
, ISState
*states
, char *names
[], int n
)
127 char errmsg
[ERRMSG_SIZE
];
130 /* ignore if not ours */
131 if (dev
&& strcmp (device_name
, dev
))
134 #ifndef HAVE_LINUX_VIDEODEV2_H
135 /* Anti Flicker control */
136 if (!strcmp (AntiFlickerSP
.name
, name
))
138 if (checkPowerS(&AntiFlickerSP
))
141 AntiFlickerSP
.s
= IPS_IDLE
;
143 IUResetSwitches(&AntiFlickerSP
);
144 IUUpdateSwitches(&AntiFlickerSP
, states
, names
, n
);
146 if (AntiFlickerS
[0].s
== ISS_ON
)
148 if (v4l_pwc
->setFlicker(true, errmsg
) < 0)
150 AntiFlickerS
[0].s
= ISS_OFF
;
151 AntiFlickerS
[1].s
= ISS_ON
;
152 IDSetSwitch(&AntiFlickerSP
, "%s", errmsg
);
156 AntiFlickerSP
.s
= IPS_OK
;
157 IDSetSwitch(&AntiFlickerSP
, NULL
);
161 if (v4l_pwc
->setFlicker(false, errmsg
) < 0)
163 AntiFlickerS
[0].s
= ISS_ON
;
164 AntiFlickerS
[1].s
= ISS_OFF
;
165 IDSetSwitch(&AntiFlickerSP
, "%s", errmsg
);
169 IDSetSwitch(&AntiFlickerSP
, NULL
);
175 /* Back light compensation */
176 if (!strcmp (BackLightSP
.name
, name
))
178 if (checkPowerS(&BackLightSP
))
181 BackLightSP
.s
= IPS_IDLE
;
183 IUResetSwitches(&BackLightSP
);
184 IUUpdateSwitches(&BackLightSP
, states
, names
, n
);
186 if (BackLightS
[0].s
== ISS_ON
)
188 if (v4l_pwc
->setBackLight(true, errmsg
) < 0)
190 BackLightS
[0].s
= ISS_OFF
;
191 BackLightS
[1].s
= ISS_ON
;
192 IDSetSwitch(&BackLightSP
, "%s", errmsg
);
196 BackLightSP
.s
= IPS_OK
;
197 IDSetSwitch(&BackLightSP
, NULL
);
201 if (v4l_pwc
->setBackLight(false, errmsg
) < 0)
203 BackLightS
[0].s
= ISS_ON
;
204 BackLightS
[1].s
= ISS_OFF
;
205 IDSetSwitch(&BackLightSP
, "%s", errmsg
);
209 IDSetSwitch(&BackLightSP
, NULL
);
215 /* Noise reduction control */
216 if (!strcmp (NoiseReductionSP
.name
, name
))
218 if (checkPowerS(&NoiseReductionSP
))
221 NoiseReductionSP
.s
= IPS_IDLE
;
223 IUResetSwitches(&NoiseReductionSP
);
224 IUUpdateSwitches(&NoiseReductionSP
, states
, names
, n
);
226 for (int i
=0; i
< 4; i
++)
227 if (NoiseReductionS
[i
].s
== ISS_ON
)
233 if (v4l_pwc
->setNoiseRemoval(index
, errmsg
) < 0)
235 IUResetSwitches(&NoiseReductionSP
);
236 NoiseReductionS
[0].s
= ISS_ON
;
237 IDSetSwitch(&NoiseReductionSP
, "%s", errmsg
);
241 NoiseReductionSP
.s
= IPS_OK
;
243 IDSetSwitch(&NoiseReductionSP
, NULL
);
247 /* White balace mode */
248 if (!strcmp (WhiteBalanceModeSP
.name
, name
))
250 if (checkPowerS(&WhiteBalanceModeSP
))
253 WhiteBalanceModeSP
.s
= IPS_IDLE
;
255 IUResetSwitches(&WhiteBalanceModeSP
);
256 IUUpdateSwitches(&WhiteBalanceModeSP
, states
, names
, n
);
258 for (int i
=0; i
< 5; i
++)
259 if (WhiteBalanceModeS
[i
].s
== ISS_ON
)
269 if (v4l_pwc
->setWhiteBalanceMode(PWC_WB_AUTO
, errmsg
) < 0)
271 IUResetSwitches(&WhiteBalanceModeSP
),
272 WhiteBalanceModeS
[0].s
= ISS_ON
;
273 IDSetSwitch(&WhiteBalanceModeSP
, "%s", errmsg
);
280 if (v4l_pwc
->setWhiteBalanceMode(PWC_WB_MANUAL
, errmsg
) < 0)
282 IUResetSwitches(&WhiteBalanceModeSP
),
283 WhiteBalanceModeS
[0].s
= ISS_ON
;
284 IDSetSwitch(&WhiteBalanceModeSP
, "%s", errmsg
);
291 if (v4l_pwc
->setWhiteBalanceMode(PWC_WB_INDOOR
, errmsg
) < 0)
293 IUResetSwitches(&WhiteBalanceModeSP
),
294 WhiteBalanceModeS
[0].s
= ISS_ON
;
295 IDSetSwitch(&WhiteBalanceModeSP
, "%s", errmsg
);
302 if (v4l_pwc
->setWhiteBalanceMode(PWC_WB_OUTDOOR
, errmsg
) < 0)
304 IUResetSwitches(&WhiteBalanceModeSP
),
305 WhiteBalanceModeS
[0].s
= ISS_ON
;
306 IDSetSwitch(&WhiteBalanceModeSP
, "%s", errmsg
);
313 if (v4l_pwc
->setWhiteBalanceMode(PWC_WB_FL
, errmsg
) < 0)
315 IUResetSwitches(&WhiteBalanceModeSP
),
316 WhiteBalanceModeS
[0].s
= ISS_ON
;
317 IDSetSwitch(&WhiteBalanceModeSP
, "%s", errmsg
);
324 WhiteBalanceModeSP
.s
= IPS_OK
;
325 IDSetSwitch(&WhiteBalanceModeSP
, NULL
);
330 /* Camera setttings */
331 if (!strcmp (CamSettingSP
.name
, name
))
334 if (checkPowerS(&CamSettingSP
))
337 CamSettingSP
.s
= IPS_IDLE
;
339 IUResetSwitches(&CamSettingSP
);
340 IUUpdateSwitches(&CamSettingSP
, states
, names
, n
);
342 if (CamSettingS
[0].s
== ISS_ON
)
344 if (v4l_pwc
->saveSettings(errmsg
) < 0)
346 IUResetSwitches(&CamSettingSP
);
347 IDSetSwitch(&CamSettingSP
, "%s", errmsg
);
351 CamSettingSP
.s
= IPS_OK
;
352 IDSetSwitch(&CamSettingSP
, "Settings saved.");
356 if (CamSettingS
[1].s
== ISS_ON
)
358 v4l_pwc
->restoreSettings();
359 IUResetSwitches(&CamSettingSP
);
360 CamSettingSP
.s
= IPS_OK
;
361 IDSetSwitch(&CamSettingSP
, "Settings restored.");
362 updateV4L1Controls();
366 if (CamSettingS
[2].s
== ISS_ON
)
368 v4l_pwc
->restoreFactorySettings();
369 IUResetSwitches(&CamSettingSP
);
370 CamSettingSP
.s
= IPS_OK
;
371 IDSetSwitch(&CamSettingSP
, "Factory settings restored.");
372 updateV4L1Controls();
379 V4L_Driver::ISNewSwitch(dev
, name
, states
, names
, n
);
385 void V4L_Philips::ISNewText (const char *dev
, const char *name
, char *texts
[], char *names
[], int n
)
388 V4L_Driver::ISNewText(dev
, name
, texts
, names
, n
);
392 void V4L_Philips::ISNewNumber (const char *dev
, const char *name
, double values
[], char *names
[], int n
)
395 // Nothing for V4L 2 to do here
396 #ifndef HAVE_LINUX_VIDEODEV2_H
397 char errmsg
[ERRMSGSIZ
];
400 if (!strcmp (FrameRateNP
.name
, name
))
402 if (checkPowerN(&FrameRateNP
))
405 FrameRateNP
.s
= IPS_IDLE
;
407 int oldFP
= (int) FrameRateN
[0].value
;
409 if (IUUpdateNumbers(&FrameRateNP
, values
, names
, n
) < 0)
412 if (v4l_pwc
->setFrameRate( (int) FrameRateN
[0].value
, errmsg
) < 0)
414 FrameRateN
[0].value
= oldFP
;
415 IDSetNumber(&FrameRateNP
, "%s", errmsg
);
419 FrameRateNP
.s
= IPS_OK
;
420 IDSetNumber(&FrameRateNP
, NULL
);
424 if (!strcmp (ShutterSpeedNP
.name
, name
))
426 if (checkPowerN(&ShutterSpeedNP
))
429 ShutterSpeedNP
.s
= IPS_IDLE
;
431 if (v4l_pwc
->setExposure( (int) values
[0], errmsg
) < 0)
433 IDSetNumber(&ShutterSpeedNP
, "%s", errmsg
);
437 ShutterSpeedN
[0].value
= values
[0];
438 ShutterSpeedNP
.s
= IPS_OK
;
439 IDSetNumber(&ShutterSpeedNP
, NULL
);
444 if (!strcmp (WhiteBalanceNP
.name
, name
))
446 if (checkPowerN(&WhiteBalanceNP
))
449 WhiteBalanceNP
.s
= IPS_IDLE
;
452 oldBalance
[0] = (int) WhiteBalanceN
[0].value
;
453 oldBalance
[1] = (int) WhiteBalanceN
[1].value
;
455 if (IUUpdateNumbers(&WhiteBalanceNP
, values
, names
, n
) < 0)
458 if (v4l_pwc
->setWhiteBalanceRed( (int) WhiteBalanceN
[0].value
* 256, errmsg
))
460 WhiteBalanceN
[0].value
= oldBalance
[0];
461 WhiteBalanceN
[1].value
= oldBalance
[1];
462 IDSetNumber(&WhiteBalanceNP
, "%s", errmsg
);
465 if (v4l_pwc
->setWhiteBalanceBlue( (int) WhiteBalanceN
[1].value
* 256, errmsg
))
467 WhiteBalanceN
[0].value
= oldBalance
[0];
468 WhiteBalanceN
[1].value
= oldBalance
[1];
469 IDSetNumber(&WhiteBalanceNP
, "%s", errmsg
);
473 IUResetSwitches(&WhiteBalanceModeSP
);
474 WhiteBalanceModeS
[1].s
= ISS_ON
;
475 WhiteBalanceModeSP
.s
= IPS_OK
;
476 WhiteBalanceNP
.s
= IPS_OK
;
477 IDSetSwitch(&WhiteBalanceModeSP
, NULL
);
478 IDSetNumber(&WhiteBalanceNP
, NULL
);
485 V4L_Driver::ISNewNumber(dev
, name
, values
, names
, n
);
489 #ifndef HAVE_LINUX_VIDEODEV2_H
490 /* Retrieves basic data from the device upon connection.*/
491 void V4L_Philips::getBasicData()
494 char errmsg
[ERRMSGSIZ
];
496 int xmax
, ymax
, xmin
, ymin
, index
;
498 v4l_pwc
->getMaxMinSize(xmax
, ymax
, xmin
, ymin
);
501 ImageSizeN
[0].value
= v4l_pwc
->getWidth();
502 ImageSizeN
[0].min
= xmin
;
503 ImageSizeN
[0].max
= xmax
;
506 ImageSizeN
[1].value
= v4l_pwc
->getHeight();
507 ImageSizeN
[1].min
= ymin
;
508 ImageSizeN
[1].max
= ymax
;
510 IDSetNumber(&ImageSizeNP
, NULL
);
511 IUUpdateMinMax(&ImageSizeNP
);
513 IUSaveText(&camNameT
[0], v4l_pwc
->getDeviceName());
514 IDSetText(&camNameTP
, NULL
);
516 IDLog("Raw values\n Contrast: %d \n Brightness %d \n Color %d \n Sharpness %d \n Gain %d \n Gamma %d \n", v4l_pwc
->getContrast(), v4l_pwc
->getBrightness(), v4l_pwc
->getColor(), v4l_pwc
->getSharpness(), v4l_pwc
->getGain(), v4l_pwc
->getGama());
518 updateV4L1Controls();
520 if (v4l_pwc
->setFrameRate( (int) FrameRateN
[0].value
, errmsg
) < 0)
522 FrameRateNP
.s
= IPS_ALERT
;
523 IDSetNumber(&FrameRateNP
, "%s", errmsg
);
527 FrameRateNP
.s
= IPS_OK
;
528 IDSetNumber(&FrameRateNP
, NULL
);
531 result
= v4l_pwc
->getBackLight();
534 BackLightS
[0].s
= ISS_ON
;
535 BackLightS
[1].s
= ISS_OFF
;
539 BackLightS
[0].s
= ISS_OFF
;
540 BackLightS
[1].s
= ISS_ON
;
542 IDSetSwitch(&BackLightSP
, NULL
);
544 result
= v4l_pwc
->getFlicker();
547 AntiFlickerS
[0].s
= ISS_ON
;
548 AntiFlickerS
[1].s
= ISS_OFF
;
552 AntiFlickerS
[0].s
= ISS_OFF
;
553 AntiFlickerS
[1].s
= ISS_ON
;
555 IDSetSwitch(&AntiFlickerSP
, NULL
);
557 index
= v4l_pwc
->getNoiseRemoval();
558 IUResetSwitches(&NoiseReductionSP
);
559 NoiseReductionS
[index
].s
= ISS_ON
;
560 IDSetSwitch(&NoiseReductionSP
, NULL
);
562 index
= v4l_pwc
->getWhiteBalance();
563 IUResetSwitches(&WhiteBalanceModeSP
);
567 WhiteBalanceModeS
[0].s
= ISS_ON
;
570 WhiteBalanceModeS
[1].s
= ISS_ON
;
573 WhiteBalanceModeS
[2].s
= ISS_ON
;
576 WhiteBalanceModeS
[3].s
= ISS_ON
;
579 WhiteBalanceModeS
[3].s
= ISS_ON
;
582 IDSetSwitch(&WhiteBalanceModeSP
, NULL
);
587 #ifndef HAVE_LINUX_VIDEODEV2_H
588 void V4L_Philips::updateV4L1Controls()
592 ImageAdjustN
[0].value
= v4l_pwc
->getContrast() / 256.;
593 ImageAdjustN
[1].value
= v4l_pwc
->getBrightness() / 256.;
594 ImageAdjustN
[2].value
= v4l_pwc
->getColor() / 256.;
595 index
= v4l_pwc
->getSharpness();
597 ImageAdjustN
[3].value
= -1;
599 ImageAdjustN
[3].value
= v4l_pwc
->getSharpness() / 256.;
601 ImageAdjustN
[4].value
= v4l_pwc
->getGain() / 256.;
602 ImageAdjustN
[5].value
= v4l_pwc
->getGama() / 256.;
604 ImageAdjustNP
.s
= IPS_OK
;
605 IDSetNumber(&ImageAdjustNP
, NULL
);