2 * Flashlight applet (widget) for Maemo.
3 * Copyright (C) 2009 Roman Moravcik
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <sys/ioctl.h>
31 #include <asm/types.h>
32 #include <linux/videodev2.h>
34 #include "flashlight_lib.h"
37 int flashlight_get_status (FlashlightContext_t *flashlight, int *status)
39 struct v4l2_control ctrl;
41 printf ("flashlight_get_status()\n");
43 if (flashlight == NULL) {
44 printf ("flashlight_get_status: flashlight context is not valid\n");
48 if (flashlight->fd == -1) {
49 printf ("flashlight_get_status: device not openned\n");
55 /* check short circuit fault */
56 ctrl.id = V4L2_CID_FLASH_ADP1653_FAULT_SCP;
57 if (ioctl (flashlight->fd, VIDIOC_G_CTRL, &ctrl) == -1) {
58 printf ("flashlight_set_intensity: cannot get circuit fault status (%s)\n", strerror (errno));
63 *status |= FLASHLIGHT_STATUS_SHORT_CIRCUT_FAULT;
65 *status &= ~FLASHLIGHT_STATUS_SHORT_CIRCUT_FAULT;
67 /* check overtemperature fault */
68 ctrl.id = V4L2_CID_FLASH_ADP1653_FAULT_OT;
69 if (ioctl (flashlight->fd, VIDIOC_G_CTRL, &ctrl) == -1) {
70 printf ("flashlight_set_intensity: cannot get overtemperature fault status (%s)\n", strerror (errno));
75 *status |= FLASHLIGHT_STATUS_OVERTEMPERATURE_FAULT;
77 *status &= ~FLASHLIGHT_STATUS_OVERTEMPERATURE_FAULT;
79 /* check timeout fault */
80 ctrl.id = V4L2_CID_FLASH_ADP1653_FAULT_TMR;
81 if (ioctl (flashlight->fd, VIDIOC_G_CTRL, &ctrl) == -1) {
82 printf ("flashlight_set_intensity: cannot get timeout fault status (%s)\n", strerror (errno));
87 *status |= FLASHLIGHT_STATUS_TIMEOUT_FAULT;
89 *status &= ~FLASHLIGHT_STATUS_TIMEOUT_FAULT;
91 /* check overtemperature fault */
92 ctrl.id = V4L2_CID_FLASH_ADP1653_FAULT_OV;
93 if (ioctl (flashlight->fd, VIDIOC_G_CTRL, &ctrl) == -1) {
94 printf ("flashlight_set_intensity: cannot get overvoltage fault status (%s)\n", strerror (errno));
99 *status |= FLASHLIGHT_STATUS_OVERVOLTAGE_FAULT;
101 *status &= ~FLASHLIGHT_STATUS_OVERVOLTAGE_FAULT;
106 int flashlight_set_intensity (FlashlightContext_t *flashlight, int intensity)
108 struct v4l2_control ctrl;
109 enum v4l2_buf_type type;
112 printf ("flashlight_set_intensity(%d)\n", intensity);
114 if (flashlight == NULL) {
115 printf ("flashlight_set_intensity: flashlight context is not valid\n");
119 if (flashlight->fd == -1) {
120 printf ("flashlight_set_intensity: device not openned\n");
124 if (intensity > flashlight->max_intensity)
125 intensity = flashlight->max_intensity;
127 ctrl.id = V4L2_CID_TORCH_INTENSITY;
128 ctrl.value = intensity;
130 if (ioctl (flashlight->fd, VIDIOC_S_CTRL, &ctrl) == -1) {
131 printf ("flashlight_set_intensity: cannot set intensity (%s)\n", strerror (errno));
136 WORKAROUND: start/stop i/o streaming to block camera application
139 for (i = 0; i < flashlight->n_buffers; ++i) {
140 struct v4l2_buffer buf;
142 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
143 buf.memory = V4L2_MEMORY_MMAP;
145 if (ioctl (flashlight->fd, VIDIOC_QBUF, &buf) == -1) {
146 printf ("flashlight_set_intensity: unable to exchange a buffer %d with driver (%s)\n", i, strerror (errno));
151 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
152 if (ioctl (flashlight->fd, VIDIOC_STREAMON, &type)) {
153 printf ("flashlight_set_intensity: unable to start i/o streaming (%s)\n", strerror (errno));
157 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
158 if (ioctl (flashlight->fd, VIDIOC_STREAMOFF, &type) == -1) {
159 printf ("flashlight_set_intensity: unable to stop i/o streaming (%s)\n", strerror (errno));
167 int flashlight_get_intensity (FlashlightContext_t *flashlight, int *intensity)
169 struct v4l2_control ctrl;
171 printf ("flashlight_get_intensity()\n");
173 if (flashlight == NULL) {
174 printf ("flashlight_get_intensity: flashlight context is not valid\n");
178 if (flashlight->fd == -1) {
179 printf ("flashlight_get_intensity: device not openned\n");
183 ctrl.id = V4L2_CID_TORCH_INTENSITY;
185 if (ioctl (flashlight->fd, VIDIOC_G_CTRL, &ctrl) == -1) {
186 printf ("flashlight_get_intensity: cannot get intensity (%s)\n", strerror (errno));
190 *intensity = ctrl.value;
194 int flashlight_open (FlashlightContext_t *flashlight, const char *device_name)
196 struct v4l2_queryctrl ctrl;
197 struct v4l2_cropcap cropcap;
198 struct v4l2_crop crop;
199 struct v4l2_format fmt;
200 struct v4l2_requestbuffers req;
203 printf ("flashlight_open(%s)\n", device_name);
205 if (flashlight == NULL) {
206 printf ("flashlight_open: flashlight context is not valid\n");
210 if (device_name == NULL) {
211 printf ("flashlight_open: device name not specified\n");
215 memcpy (flashlight->device_name, device_name, sizeof(flashlight->device_name));
217 if (stat (flashlight->device_name, &st) == -1) {
218 printf ("flashlight_open: cannot identify '%s' (%s)\n", flashlight->device_name, strerror (errno));
222 /* check it device_name is real device */
223 if (!S_ISCHR (st.st_mode)) {
224 printf ("flashlight_open: %s is no device\n", flashlight->device_name);
228 flashlight->fd = open (flashlight->device_name, O_RDWR /* required */ | O_NONBLOCK, 0);
230 if (flashlight->fd == -1) {
231 printf ("flashlight_open: cannot open '%s' (%s)\n", flashlight->device_name, strerror (errno));
235 /* query from driver minimal and maximal flashlight intensity */
236 ctrl.id = V4L2_CID_TORCH_INTENSITY;
237 if (ioctl (flashlight->fd, VIDIOC_QUERYCTRL, &ctrl) == -1) {
238 printf ("flashlight_open: cannot get minimal and maximal flashlight intensity (%s)\n", strerror (errno));
242 flashlight->min_intensity = ctrl.minimum;
243 flashlight->max_intensity = ctrl.maximum;
246 WORKAROUND: Initialization of camera extracted from v4l2_example.
247 http://v4l2spec.bytesex.org/spec/capture-example.html
249 We need to initialize camera in other to block camera application.
250 (bug 4949: Applet breaks the camera application)
252 /* get crop capabilities */
253 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
254 if (ioctl (flashlight->fd, VIDIOC_CROPCAP, &cropcap) == -1) {
255 printf ("flashlight_open: unable to get crop capabilities (%s)\n", strerror (errno));
259 /* set crop capabilities */
260 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261 crop.c = cropcap.defrect; /* reset to default */
262 if (ioctl (flashlight->fd, VIDIOC_S_CROP, &crop) == -1) {
263 printf ("flashlight_open: unable to set cropping rectangle (%s)\n", strerror (errno));
267 /* set data format */
268 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
269 fmt.fmt.pix.width = 640;
270 fmt.fmt.pix.height = 480;
271 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
272 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
273 if (ioctl (flashlight->fd, VIDIOC_S_FMT, &fmt) == -1) {
274 printf ("flashlight_open: unable to set data format (%s)\n", strerror (errno));
279 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
280 req.memory = V4L2_MEMORY_MMAP;
281 if (ioctl (flashlight->fd, VIDIOC_REQBUFS, &req) == -1) {
282 printf ("flashlight_open: unable to initiate memory mapping (%s)\n", strerror (errno));
287 printf ("flashlight_open: insufficient buffer memory on %s\n", device_name);
291 flashlight->buffers = calloc (req.count, sizeof (*flashlight->buffers));
292 if (!flashlight->buffers) {
293 printf ("flashlight_open: unable to allocate memory\n");
297 for (flashlight->n_buffers = 0; flashlight->n_buffers < req.count; ++flashlight->n_buffers) {
298 struct v4l2_buffer buf;
300 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
301 buf.memory = V4L2_MEMORY_MMAP;
302 buf.index = flashlight->n_buffers;
304 if (ioctl (flashlight->fd, VIDIOC_QUERYBUF, &buf) == -1) {
305 printf ("flashlight_open: unable to query the status of a buffer %d (%s)\n",
306 flashlight->n_buffers, strerror (errno));
310 flashlight->buffers[flashlight->n_buffers].length = buf.length;
311 flashlight->buffers[flashlight->n_buffers].start = mmap (NULL /* start anywhere */,
313 PROT_READ | PROT_WRITE /* required */,
314 MAP_SHARED /* recommended */,
318 if (flashlight->buffers[flashlight->n_buffers].start == MAP_FAILED) {
319 printf ("flashlight_open: unable to map memory (%s)\n", strerror (errno));
327 int flashlight_close (FlashlightContext_t *flashlight)
331 printf ("flashlight_close()\n");
333 if (flashlight == NULL) {
334 printf ("flashlight_close: flashlight context is not valid\n");
338 /* unmap memory mapped buffers */
339 for (i = 0; i < flashlight->n_buffers; ++i) {
340 if (flashlight->buffers[flashlight->n_buffers].start != MAP_FAILED) {
341 if (munmap (flashlight->buffers[i].start, flashlight->buffers[i].length) == -1) {
342 printf ("flashlight_close: unable to unmap memory (%s)\n", strerror (errno));
347 flashlight->n_buffers = 0;
350 if (flashlight->buffers)
351 free (flashlight->buffers);
352 flashlight->buffers = NULL;
354 /* close camera device */
355 if (flashlight->fd != -1) {
356 if (close (flashlight->fd) == -1) {
357 printf ("flashlight_close: cannot close device '%s' (%s)\n", flashlight->device_name, strerror (errno));
366 int flashlight_init (FlashlightContext_t **pRefContext)
368 FlashlightContext_t *flashlight = NULL;
370 printf ("flashlight_init()\n");
372 if (*pRefContext != NULL) {
373 printf("flashlight_init: expecting zero pointer context '*pRefContext'\n");
377 /* allocate memory for context structure */
378 flashlight = malloc (sizeof (FlashlightContext_t));
379 if (flashlight == NULL) {
380 printf ("flashlight_init: unable to allocate memory for context\n");
384 *pRefContext = flashlight;
386 /* initialize default values */
387 memset (flashlight, 0x00, sizeof (FlashlightContext_t));
390 flashlight->n_buffers = 0;
391 flashlight->buffers = NULL;
394 flashlight->min_intensity = 0;
395 flashlight->max_intensity = 11;
400 int flashlight_deinit (FlashlightContext_t *flashlight)
404 printf ("flashlight_deinit()\n");
406 if (flashlight == NULL) {
407 printf ("flashlight_deinit: flashlight context is not valid\n");
411 if (flashlight->fd != -1) {
412 /* check if flashlight isn't enabled before closing device */
413 if (flashlight_get_intensity (flashlight, &intensity) == -1)
417 if (flashlight_set_intensity (flashlight, 0) == -1)
421 if (flashlight_close(flashlight))
425 /* free allocated memory */