• Home
  • Raw
  • Download

Lines Matching +full:cam +full:- +full:if

1 // SPDX-License-Identifier: GPL-2.0-only
18 #include <media/v4l2-device.h>
19 #include <media/v4l2-ioctl.h>
20 #include <media/v4l2-ctrls.h>
21 #include <media/v4l2-event.h>
22 #include <media/v4l2-image-sizes.h>
24 #include <media/videobuf2-dma-sg.h>
26 #include <linux/dma-mapping.h>
28 #include <linux/via-core.h>
29 #include <linux/via-gpio.h>
38 #include "via-camera.h"
40 MODULE_ALIAS("platform:viafb-camera");
42 MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
48 "If set, the sensor will be instructed to flip the image vertically.");
53 … camera driver will normally refuse to load if the XO 1.5 serial port is enabled. Set this option…
88 u8 __iomem *cb_addrs[3]; /* Kernel-space addresses */
97 * downscale things if need be. So we keep the "real*
107 /* common v4l buffer stuff -- must be first */
128 #define sensor_call(cam, optype, func, args...) \ argument
129 v4l2_subdev_call(cam->sensor, optype, func, ##args)
134 #define cam_err(cam, fmt, arg...) \ argument
135 dev_err(&(cam)->platdev->dev, fmt, ##arg);
136 #define cam_warn(cam, fmt, arg...) \ argument
137 dev_warn(&(cam)->platdev->dev, fmt, ##arg);
138 #define cam_dbg(cam, fmt, arg...) \ argument
139 dev_dbg(&(cam)->platdev->dev, fmt, ##arg);
169 if (via_formats[i].pixelformat == pixelformat) in via_find_format()
176 /*--------------------------------------------------------------------------*/
178 * Sensor power/reset management. This piece is OLPC-specific for
181 static int via_sensor_power_setup(struct via_camera *cam) in via_sensor_power_setup() argument
185 cam->power_gpio = viafb_gpio_lookup("VGPIO3"); in via_sensor_power_setup()
186 cam->reset_gpio = viafb_gpio_lookup("VGPIO2"); in via_sensor_power_setup()
187 if (!gpio_is_valid(cam->power_gpio) || !gpio_is_valid(cam->reset_gpio)) { in via_sensor_power_setup()
188 dev_err(&cam->platdev->dev, "Unable to find GPIO lines\n"); in via_sensor_power_setup()
189 return -EINVAL; in via_sensor_power_setup()
191 ret = gpio_request(cam->power_gpio, "viafb-camera"); in via_sensor_power_setup()
192 if (ret) { in via_sensor_power_setup()
193 dev_err(&cam->platdev->dev, "Unable to request power GPIO\n"); in via_sensor_power_setup()
196 ret = gpio_request(cam->reset_gpio, "viafb-camera"); in via_sensor_power_setup()
197 if (ret) { in via_sensor_power_setup()
198 dev_err(&cam->platdev->dev, "Unable to request reset GPIO\n"); in via_sensor_power_setup()
199 gpio_free(cam->power_gpio); in via_sensor_power_setup()
202 gpio_direction_output(cam->power_gpio, 0); in via_sensor_power_setup()
203 gpio_direction_output(cam->reset_gpio, 0); in via_sensor_power_setup()
210 static void via_sensor_power_up(struct via_camera *cam) in via_sensor_power_up() argument
212 gpio_set_value(cam->power_gpio, 1); in via_sensor_power_up()
213 gpio_set_value(cam->reset_gpio, 0); in via_sensor_power_up()
215 gpio_set_value(cam->reset_gpio, 1); in via_sensor_power_up()
219 static void via_sensor_power_down(struct via_camera *cam) in via_sensor_power_down() argument
221 gpio_set_value(cam->power_gpio, 0); in via_sensor_power_down()
222 gpio_set_value(cam->reset_gpio, 0); in via_sensor_power_down()
226 static void via_sensor_power_release(struct via_camera *cam) in via_sensor_power_release() argument
228 via_sensor_power_down(cam); in via_sensor_power_release()
229 gpio_free(cam->power_gpio); in via_sensor_power_release()
230 gpio_free(cam->reset_gpio); in via_sensor_power_release()
233 /* --------------------------------------------------------------------------*/
239 static int viacam_set_flip(struct via_camera *cam) in viacam_set_flip() argument
246 return v4l2_s_ctrl(NULL, cam->sensor->ctrl_handler, &ctrl); in viacam_set_flip()
253 static int viacam_configure_sensor(struct via_camera *cam) in viacam_configure_sensor() argument
260 v4l2_fill_mbus_format(&format.format, &cam->sensor_format, cam->mbus_code); in viacam_configure_sensor()
261 ret = sensor_call(cam, core, init, 0); in viacam_configure_sensor()
262 if (ret == 0) in viacam_configure_sensor()
263 ret = sensor_call(cam, pad, set_fmt, NULL, &format); in viacam_configure_sensor()
265 * OV7670 does weird things if flip is set *before* format... in viacam_configure_sensor()
267 if (ret == 0) in viacam_configure_sensor()
268 ret = viacam_set_flip(cam); in viacam_configure_sensor()
274 /* --------------------------------------------------------------------------*/
280 * 0x300-350 range.
282 static inline void viacam_write_reg(struct via_camera *cam, in viacam_write_reg() argument
285 iowrite32(value, cam->mmio + reg); in viacam_write_reg()
288 static inline int viacam_read_reg(struct via_camera *cam, int reg) in viacam_read_reg() argument
290 return ioread32(cam->mmio + reg); in viacam_read_reg()
293 static inline void viacam_write_reg_mask(struct via_camera *cam, in viacam_write_reg_mask() argument
296 int tmp = viacam_read_reg(cam, reg); in viacam_write_reg_mask()
299 viacam_write_reg(cam, reg, tmp); in viacam_write_reg_mask()
303 /* --------------------------------------------------------------------------*/
308 struct via_camera *cam = data; in viacam_quick_irq() local
316 spin_lock(&cam->viadev->reg_lock); in viacam_quick_irq()
317 icv = viacam_read_reg(cam, VCR_INTCTRL); in viacam_quick_irq()
318 if (icv & VCR_IC_EAV) { in viacam_quick_irq()
320 viacam_write_reg(cam, VCR_INTCTRL, icv); in viacam_quick_irq()
323 spin_unlock(&cam->viadev->reg_lock); in viacam_quick_irq()
330 static struct via_buffer *viacam_next_buffer(struct via_camera *cam) in viacam_next_buffer() argument
332 if (cam->opstate != S_RUNNING) in viacam_next_buffer()
334 if (list_empty(&cam->buffer_queue)) in viacam_next_buffer()
336 return list_entry(cam->buffer_queue.next, struct via_buffer, queue); in viacam_next_buffer()
344 struct via_camera *cam = data; in viacam_irq() local
349 mutex_lock(&cam->lock); in viacam_irq()
351 * If there is no place to put the data frame, don't bother in viacam_irq()
354 vb = viacam_next_buffer(cam); in viacam_irq()
355 if (vb == NULL) in viacam_irq()
360 bufn = (viacam_read_reg(cam, VCR_INTCTRL) & VCR_IC_ACTBUF) >> 3; in viacam_irq()
361 bufn -= 1; in viacam_irq()
362 if (bufn < 0) in viacam_irq()
363 bufn = cam->n_cap_bufs - 1; in viacam_irq()
367 sgt = vb2_dma_sg_plane_desc(&vb->vbuf.vb2_buf, 0); in viacam_irq()
368 vb->vbuf.vb2_buf.timestamp = ktime_get_ns(); in viacam_irq()
369 viafb_dma_copy_out_sg(cam->cb_offsets[bufn], sgt->sgl, sgt->nents); in viacam_irq()
370 vb->vbuf.sequence = cam->sequence++; in viacam_irq()
371 vb->vbuf.field = V4L2_FIELD_NONE; in viacam_irq()
372 list_del(&vb->queue); in viacam_irq()
373 vb2_buffer_done(&vb->vbuf.vb2_buf, VB2_BUF_STATE_DONE); in viacam_irq()
375 mutex_unlock(&cam->lock); in viacam_irq()
385 * the via-core level.
387 static void viacam_int_enable(struct via_camera *cam) in viacam_int_enable() argument
389 viacam_write_reg(cam, VCR_INTCTRL, in viacam_int_enable()
394 static void viacam_int_disable(struct via_camera *cam) in viacam_int_disable() argument
397 viacam_write_reg(cam, VCR_INTCTRL, 0); in viacam_int_disable()
402 /* --------------------------------------------------------------------------*/
408 static int viacam_ctlr_cbufs(struct via_camera *cam) in viacam_ctlr_cbufs() argument
410 int nbuf = cam->viadev->camera_fbmem_size/cam->sensor_format.sizeimage; in viacam_ctlr_cbufs()
417 if (nbuf >= 3) { in viacam_ctlr_cbufs()
418 cam->n_cap_bufs = 3; in viacam_ctlr_cbufs()
419 viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_3BUFS, in viacam_ctlr_cbufs()
421 } else if (nbuf == 2) { in viacam_ctlr_cbufs()
422 cam->n_cap_bufs = 2; in viacam_ctlr_cbufs()
423 viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_3BUFS); in viacam_ctlr_cbufs()
425 cam_warn(cam, "Insufficient frame buffer memory\n"); in viacam_ctlr_cbufs()
426 return -ENOMEM; in viacam_ctlr_cbufs()
431 offset = cam->fb_offset; in viacam_ctlr_cbufs()
432 for (i = 0; i < cam->n_cap_bufs; i++) { in viacam_ctlr_cbufs()
433 cam->cb_offsets[i] = offset; in viacam_ctlr_cbufs()
434 cam->cb_addrs[i] = cam->fbmem + offset; in viacam_ctlr_cbufs()
435 viacam_write_reg(cam, VCR_VBUF1 + i*4, offset & VCR_VBUF_MASK); in viacam_ctlr_cbufs()
436 offset += cam->sensor_format.sizeimage; in viacam_ctlr_cbufs()
445 * by bit 26; if that bit is set, downscaling is controlled by the
454 * This function is naive in that, if the user departs from
456 * could work around that if it really seemed important.
458 static void viacam_set_scale(struct via_camera *cam) in viacam_set_scale() argument
463 if (cam->user_format.width == VGA_WIDTH) in viacam_set_scale()
466 sf = (cam->user_format.width*2048)/VGA_WIDTH; in viacam_set_scale()
469 if (cam->user_format.height < VGA_HEIGHT) { in viacam_set_scale()
470 sf = (1024*cam->user_format.height)/VGA_HEIGHT; in viacam_set_scale()
473 viacam_write_reg(cam, VCR_AVSCALE, avscale); in viacam_set_scale()
478 * Configure image-related information into the capture engine.
480 static void viacam_ctlr_image(struct via_camera *cam) in viacam_ctlr_image() argument
485 * Disable clock before messing with stuff - from the via in viacam_ctlr_image()
488 viacam_write_reg(cam, VCR_CAPINTC, ~(VCR_CI_ENABLE|VCR_CI_CLKEN)); in viacam_ctlr_image()
493 viacam_write_reg(cam, VCR_HORRANGE, 0x06200120); in viacam_ctlr_image()
494 viacam_write_reg(cam, VCR_VERTRANGE, 0x01de0000); in viacam_ctlr_image()
495 viacam_set_scale(cam); in viacam_ctlr_image()
499 viacam_write_reg(cam, VCR_MAXDATA, in viacam_ctlr_image()
500 (cam->sensor_format.height << 16) | in viacam_ctlr_image()
501 (cam->sensor_format.bytesperline >> 3)); in viacam_ctlr_image()
502 viacam_write_reg(cam, VCR_MAXVBI, 0); in viacam_ctlr_image()
503 viacam_write_reg(cam, VCR_VSTRIDE, in viacam_ctlr_image()
504 cam->user_format.bytesperline & VCR_VS_STRIDE); in viacam_ctlr_image()
514 VCR_CI_FLDINV | /* OLPC-specific? */ in viacam_ctlr_image()
515 VCR_CI_VREFINV | /* OLPC-specific? */ in viacam_ctlr_image()
518 if (cam->n_cap_bufs == 3) in viacam_ctlr_image()
523 if (cam->user_format.pixelformat == V4L2_PIX_FMT_YUYV) in viacam_ctlr_image()
527 viacam_write_reg(cam, VCR_CAPINTC, cicreg); in viacam_ctlr_image()
531 static int viacam_config_controller(struct via_camera *cam) in viacam_config_controller() argument
536 spin_lock_irqsave(&cam->viadev->reg_lock, flags); in viacam_config_controller()
537 ret = viacam_ctlr_cbufs(cam); in viacam_config_controller()
538 if (!ret) in viacam_config_controller()
539 viacam_ctlr_image(cam); in viacam_config_controller()
540 spin_unlock_irqrestore(&cam->viadev->reg_lock, flags); in viacam_config_controller()
541 clear_bit(CF_CONFIG_NEEDED, &cam->flags); in viacam_config_controller()
548 static void viacam_start_engine(struct via_camera *cam) in viacam_start_engine() argument
550 spin_lock_irq(&cam->viadev->reg_lock); in viacam_start_engine()
551 viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE); in viacam_start_engine()
552 viacam_int_enable(cam); in viacam_start_engine()
553 (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */ in viacam_start_engine()
554 cam->opstate = S_RUNNING; in viacam_start_engine()
555 spin_unlock_irq(&cam->viadev->reg_lock); in viacam_start_engine()
559 static void viacam_stop_engine(struct via_camera *cam) in viacam_stop_engine() argument
561 spin_lock_irq(&cam->viadev->reg_lock); in viacam_stop_engine()
562 viacam_int_disable(cam); in viacam_stop_engine()
563 viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_ENABLE); in viacam_stop_engine()
564 (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */ in viacam_stop_engine()
565 cam->opstate = S_IDLE; in viacam_stop_engine()
566 spin_unlock_irq(&cam->viadev->reg_lock); in viacam_stop_engine()
570 /* --------------------------------------------------------------------------*/
582 struct via_camera *cam = vb2_get_drv_priv(vb->vb2_queue); in viacam_vb2_queue() local
585 list_add_tail(&via->queue, &cam->buffer_queue); in viacam_vb2_queue()
590 struct via_camera *cam = vb2_get_drv_priv(vb->vb2_queue); in viacam_vb2_prepare() local
592 if (vb2_plane_size(vb, 0) < cam->user_format.sizeimage) { in viacam_vb2_prepare()
593 cam_dbg(cam, in viacam_vb2_prepare()
596 cam->user_format.sizeimage); in viacam_vb2_prepare()
597 return -EINVAL; in viacam_vb2_prepare()
600 vb2_set_plane_payload(vb, 0, cam->user_format.sizeimage); in viacam_vb2_prepare()
610 struct via_camera *cam = vb2_get_drv_priv(vq); in viacam_vb2_queue_setup() local
611 int size = cam->user_format.sizeimage; in viacam_vb2_queue_setup()
613 if (*num_planes) in viacam_vb2_queue_setup()
614 return sizes[0] < size ? -EINVAL : 0; in viacam_vb2_queue_setup()
623 struct via_camera *cam = vb2_get_drv_priv(vq); in viacam_vb2_start_streaming() local
627 if (cam->opstate != S_IDLE) { in viacam_vb2_start_streaming()
628 ret = -EBUSY; in viacam_vb2_start_streaming()
632 * Configure things if need be. in viacam_vb2_start_streaming()
634 if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) { in viacam_vb2_start_streaming()
635 ret = viacam_configure_sensor(cam); in viacam_vb2_start_streaming()
636 if (ret) in viacam_vb2_start_streaming()
638 ret = viacam_config_controller(cam); in viacam_vb2_start_streaming()
639 if (ret) in viacam_vb2_start_streaming()
642 cam->sequence = 0; in viacam_vb2_start_streaming()
644 * If the CPU goes into C3, the DMA transfer gets corrupted and in viacam_vb2_start_streaming()
649 cpu_latency_qos_add_request(&cam->qos_request, 50); in viacam_vb2_start_streaming()
650 viacam_start_engine(cam); in viacam_vb2_start_streaming()
653 list_for_each_entry_safe(buf, tmp, &cam->buffer_queue, queue) { in viacam_vb2_start_streaming()
654 list_del(&buf->queue); in viacam_vb2_start_streaming()
655 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); in viacam_vb2_start_streaming()
662 struct via_camera *cam = vb2_get_drv_priv(vq); in viacam_vb2_stop_streaming() local
665 cpu_latency_qos_remove_request(&cam->qos_request); in viacam_vb2_stop_streaming()
666 viacam_stop_engine(cam); in viacam_vb2_stop_streaming()
668 list_for_each_entry_safe(buf, tmp, &cam->buffer_queue, queue) { in viacam_vb2_stop_streaming()
669 list_del(&buf->queue); in viacam_vb2_stop_streaming()
670 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in viacam_vb2_stop_streaming()
684 /* --------------------------------------------------------------------------*/
689 struct via_camera *cam = video_drvdata(filp); in viacam_open() local
693 * Note the new user. If this is the first one, we'll also in viacam_open()
696 mutex_lock(&cam->lock); in viacam_open()
698 if (ret) in viacam_open()
700 if (v4l2_fh_is_singular_file(filp)) { in viacam_open()
703 if (ret) { in viacam_open()
707 via_sensor_power_up(cam); in viacam_open()
708 set_bit(CF_CONFIG_NEEDED, &cam->flags); in viacam_open()
711 mutex_unlock(&cam->lock); in viacam_open()
717 struct via_camera *cam = video_drvdata(filp); in viacam_release() local
720 mutex_lock(&cam->lock); in viacam_release()
726 if (last_open) { in viacam_release()
727 via_sensor_power_down(cam); in viacam_release()
730 mutex_unlock(&cam->lock); in viacam_release()
744 /*----------------------------------------------------------------------------*/
755 if (input->index != 0) in viacam_enum_input()
756 return -EINVAL; in viacam_enum_input()
758 input->type = V4L2_INPUT_TYPE_CAMERA; in viacam_enum_input()
759 strscpy(input->name, "Camera", sizeof(input->name)); in viacam_enum_input()
771 if (i != 0) in viacam_s_input()
772 return -EINVAL; in viacam_s_input()
795 if (fmt->index >= N_VIA_FMTS) in viacam_enum_fmt_vid_cap()
796 return -EINVAL; in viacam_enum_fmt_vid_cap()
797 fmt->pixelformat = via_formats[fmt->index].pixelformat; in viacam_enum_fmt_vid_cap()
809 if (userfmt->width < QCIF_WIDTH || userfmt->height < QCIF_HEIGHT) { in viacam_fmt_pre()
810 userfmt->width = QCIF_WIDTH; in viacam_fmt_pre()
811 userfmt->height = QCIF_HEIGHT; in viacam_fmt_pre()
813 if (userfmt->width > VGA_WIDTH || userfmt->height > VGA_HEIGHT) { in viacam_fmt_pre()
814 userfmt->width = VGA_WIDTH; in viacam_fmt_pre()
815 userfmt->height = VGA_HEIGHT; in viacam_fmt_pre()
817 sensorfmt->width = VGA_WIDTH; in viacam_fmt_pre()
818 sensorfmt->height = VGA_HEIGHT; in viacam_fmt_pre()
824 struct via_format *f = via_find_format(userfmt->pixelformat); in viacam_fmt_post()
826 sensorfmt->bytesperline = sensorfmt->width * f->bpp; in viacam_fmt_post()
827 sensorfmt->sizeimage = sensorfmt->height * sensorfmt->bytesperline; in viacam_fmt_post()
828 userfmt->pixelformat = sensorfmt->pixelformat; in viacam_fmt_post()
829 userfmt->field = sensorfmt->field; in viacam_fmt_post()
830 userfmt->bytesperline = 2 * userfmt->width; in viacam_fmt_post()
831 userfmt->sizeimage = userfmt->bytesperline * userfmt->height; in viacam_fmt_post()
832 userfmt->colorspace = sensorfmt->colorspace; in viacam_fmt_post()
833 userfmt->ycbcr_enc = sensorfmt->ycbcr_enc; in viacam_fmt_post()
834 userfmt->quantization = sensorfmt->quantization; in viacam_fmt_post()
835 userfmt->xfer_func = sensorfmt->xfer_func; in viacam_fmt_post()
842 static int viacam_do_try_fmt(struct via_camera *cam, in viacam_do_try_fmt() argument
850 struct via_format *f = via_find_format(upix->pixelformat); in viacam_do_try_fmt()
852 upix->pixelformat = f->pixelformat; in viacam_do_try_fmt()
854 v4l2_fill_mbus_format(&format.format, spix, f->mbus_code); in viacam_do_try_fmt()
855 ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format); in viacam_do_try_fmt()
866 struct via_camera *cam = video_drvdata(filp); in viacam_try_fmt_vid_cap() local
869 return viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); in viacam_try_fmt_vid_cap()
876 struct via_camera *cam = video_drvdata(filp); in viacam_g_fmt_vid_cap() local
878 fmt->fmt.pix = cam->user_format; in viacam_g_fmt_vid_cap()
885 struct via_camera *cam = video_drvdata(filp); in viacam_s_fmt_vid_cap() local
888 struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat); in viacam_s_fmt_vid_cap()
894 if (cam->opstate != S_IDLE) in viacam_s_fmt_vid_cap()
895 return -EBUSY; in viacam_s_fmt_vid_cap()
900 ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); in viacam_s_fmt_vid_cap()
901 if (ret) in viacam_s_fmt_vid_cap()
906 cam->user_format = fmt->fmt.pix; in viacam_s_fmt_vid_cap()
907 cam->sensor_format = sfmt.fmt.pix; in viacam_s_fmt_vid_cap()
908 cam->mbus_code = f->mbus_code; in viacam_s_fmt_vid_cap()
909 ret = viacam_configure_sensor(cam); in viacam_s_fmt_vid_cap()
910 if (!ret) in viacam_s_fmt_vid_cap()
911 ret = viacam_config_controller(cam); in viacam_s_fmt_vid_cap()
918 strscpy(cap->driver, "via-camera", sizeof(cap->driver)); in viacam_querycap()
919 strscpy(cap->card, "via-camera", sizeof(cap->card)); in viacam_querycap()
920 strscpy(cap->bus_info, "platform:via-camera", sizeof(cap->bus_info)); in viacam_querycap()
929 struct via_camera *cam = video_drvdata(filp); in viacam_g_parm() local
931 return v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm); in viacam_g_parm()
937 struct via_camera *cam = video_drvdata(filp); in viacam_s_parm() local
939 return v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm); in viacam_s_parm()
947 if (sizes->index != 0) in viacam_enum_framesizes()
948 return -EINVAL; in viacam_enum_framesizes()
950 if (sizes->pixel_format == via_formats[i].pixelformat) in viacam_enum_framesizes()
952 if (i >= N_VIA_FMTS) in viacam_enum_framesizes()
953 return -EINVAL; in viacam_enum_framesizes()
954 sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; in viacam_enum_framesizes()
955 sizes->stepwise.min_width = QCIF_WIDTH; in viacam_enum_framesizes()
956 sizes->stepwise.min_height = QCIF_HEIGHT; in viacam_enum_framesizes()
957 sizes->stepwise.max_width = VGA_WIDTH; in viacam_enum_framesizes()
958 sizes->stepwise.max_height = VGA_HEIGHT; in viacam_enum_framesizes()
959 sizes->stepwise.step_width = sizes->stepwise.step_height = 1; in viacam_enum_framesizes()
966 struct via_camera *cam = video_drvdata(filp); in viacam_enum_frameintervals() local
968 .index = interval->index, in viacam_enum_frameintervals()
969 .code = cam->mbus_code, in viacam_enum_frameintervals()
970 .width = cam->sensor_format.width, in viacam_enum_frameintervals()
971 .height = cam->sensor_format.height, in viacam_enum_frameintervals()
978 if (interval->pixel_format == via_formats[i].pixelformat) in viacam_enum_frameintervals()
980 if (i >= N_VIA_FMTS) in viacam_enum_frameintervals()
981 return -EINVAL; in viacam_enum_frameintervals()
982 if (interval->width < QCIF_WIDTH || interval->width > VGA_WIDTH || in viacam_enum_frameintervals()
983 interval->height < QCIF_HEIGHT || interval->height > VGA_HEIGHT) in viacam_enum_frameintervals()
984 return -EINVAL; in viacam_enum_frameintervals()
985 ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); in viacam_enum_frameintervals()
986 if (ret) in viacam_enum_frameintervals()
988 interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; in viacam_enum_frameintervals()
989 interval->discrete = fie.interval; in viacam_enum_frameintervals()
1019 /*----------------------------------------------------------------------------*/
1028 struct via_camera *cam = priv; in viacam_suspend() local
1029 enum viacam_opstate state = cam->opstate; in viacam_suspend()
1031 if (cam->opstate != S_IDLE) { in viacam_suspend()
1032 viacam_stop_engine(cam); in viacam_suspend()
1033 cam->opstate = state; /* So resume restarts */ in viacam_suspend()
1041 struct via_camera *cam = priv; in viacam_resume() local
1049 viacam_int_disable(cam); in viacam_resume()
1050 set_bit(CF_CONFIG_NEEDED, &cam->flags); in viacam_resume()
1054 if (!list_empty(&cam->vdev.fh_list)) in viacam_resume()
1055 via_sensor_power_up(cam); in viacam_resume()
1057 via_sensor_power_down(cam); in viacam_resume()
1059 * If it was operating, try to restart it. in viacam_resume()
1061 if (cam->opstate != S_IDLE) { in viacam_resume()
1062 mutex_lock(&cam->lock); in viacam_resume()
1063 ret = viacam_configure_sensor(cam); in viacam_resume()
1064 if (!ret) in viacam_resume()
1065 ret = viacam_config_controller(cam); in viacam_resume()
1066 mutex_unlock(&cam->lock); in viacam_resume()
1067 if (!ret) in viacam_resume()
1068 viacam_start_engine(cam); in viacam_resume()
1086 .name = "via-camera",
1087 .minor = -1,
1097 * the camera. They also get grumpy if we break the
1110 if (!pbus) in viacam_serial_is_enabled()
1114 if ((cbyte & VIACAM_SERIAL_BIT) == 0) in viacam_serial_is_enabled()
1116 if (!override_serial) { in viacam_serial_is_enabled()
1130 /* The XO-1.5 (only known user) clocks the camera at 90MHz. */
1138 struct viafb_dev *viadev = pdev->dev.platform_data; in viacam_probe()
1152 struct via_camera *cam; in viacam_probe() local
1157 * with less than two frames of VGA 16-bit data. in viacam_probe()
1159 * If we ever support the second port, we'll need to set in viacam_probe()
1162 if (viadev->camera_fbmem_size < (VGA_HEIGHT*VGA_WIDTH*4)) { in viacam_probe()
1164 return -ENOMEM; in viacam_probe()
1166 if (viadev->engine_mmio == NULL) { in viacam_probe()
1168 return -ENOMEM; in viacam_probe()
1171 if (machine_is_olpc() && viacam_serial_is_enabled()) in viacam_probe()
1172 return -EBUSY; in viacam_probe()
1177 cam = kzalloc (sizeof(struct via_camera), GFP_KERNEL); in viacam_probe()
1178 if (cam == NULL) in viacam_probe()
1179 return -ENOMEM; in viacam_probe()
1180 via_cam_info = cam; in viacam_probe()
1181 cam->platdev = pdev; in viacam_probe()
1182 cam->viadev = viadev; in viacam_probe()
1183 cam->opstate = S_IDLE; in viacam_probe()
1184 cam->user_format = cam->sensor_format = viacam_def_pix_format; in viacam_probe()
1185 mutex_init(&cam->lock); in viacam_probe()
1186 INIT_LIST_HEAD(&cam->buffer_queue); in viacam_probe()
1187 cam->mmio = viadev->engine_mmio; in viacam_probe()
1188 cam->fbmem = viadev->fbmem; in viacam_probe()
1189 cam->fb_offset = viadev->camera_fbmem_offset; in viacam_probe()
1190 cam->flags = 1 << CF_CONFIG_NEEDED; in viacam_probe()
1191 cam->mbus_code = via_def_mbus_code; in viacam_probe()
1195 ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev); in viacam_probe()
1196 if (ret) { in viacam_probe()
1197 dev_err(&pdev->dev, "Unable to register v4l2 device\n"); in viacam_probe()
1200 ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10); in viacam_probe()
1201 if (ret) in viacam_probe()
1203 cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler; in viacam_probe()
1207 pdev->dev.dma_mask = &viadev->pdev->dma_mask; in viacam_probe()
1208 dma_set_mask(&pdev->dev, 0xffffffff); in viacam_probe()
1218 ret = via_sensor_power_setup(cam); in viacam_probe()
1219 if (ret) in viacam_probe()
1221 via_sensor_power_up(cam); in viacam_probe()
1224 * See if we can't find it on the bus. The VIA_PORT_31 assumption in viacam_probe()
1225 * is OLPC-specific. 0x42 assumption is ov7670-specific. in viacam_probe()
1228 cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, sensor_adapter, in viacam_probe()
1230 if (cam->sensor == NULL) { in viacam_probe()
1231 dev_err(&pdev->dev, "Unable to find the sensor!\n"); in viacam_probe()
1232 ret = -ENODEV; in viacam_probe()
1238 viacam_int_disable(cam); in viacam_probe()
1239 ret = request_threaded_irq(viadev->pdev->irq, viacam_quick_irq, in viacam_probe()
1240 viacam_irq, IRQF_SHARED, "via-camera", cam); in viacam_probe()
1241 if (ret) in viacam_probe()
1244 vq = &cam->vq; in viacam_probe()
1245 vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in viacam_probe()
1246 vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; in viacam_probe()
1247 vq->drv_priv = cam; in viacam_probe()
1248 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in viacam_probe()
1249 vq->buf_struct_size = sizeof(struct via_buffer); in viacam_probe()
1250 vq->dev = cam->v4l2_dev.dev; in viacam_probe()
1252 vq->ops = &viacam_vb2_ops; in viacam_probe()
1253 vq->mem_ops = &vb2_dma_sg_memops; in viacam_probe()
1254 vq->lock = &cam->lock; in viacam_probe()
1260 cam->vdev = viacam_v4l_template; in viacam_probe()
1261 cam->vdev.v4l2_dev = &cam->v4l2_dev; in viacam_probe()
1262 cam->vdev.lock = &cam->lock; in viacam_probe()
1263 cam->vdev.queue = vq; in viacam_probe()
1264 video_set_drvdata(&cam->vdev, cam); in viacam_probe()
1265 ret = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1); in viacam_probe()
1266 if (ret) in viacam_probe()
1273 viacam_pm_hooks.private = cam; in viacam_probe()
1278 via_sensor_power_down(cam); in viacam_probe()
1282 free_irq(viadev->pdev->irq, cam); in viacam_probe()
1284 via_sensor_power_release(cam); in viacam_probe()
1286 v4l2_ctrl_handler_free(&cam->ctrl_handler); in viacam_probe()
1288 v4l2_device_unregister(&cam->v4l2_dev); in viacam_probe()
1290 kfree(cam); in viacam_probe()
1296 struct via_camera *cam = via_cam_info; in viacam_remove() local
1297 struct viafb_dev *viadev = pdev->dev.platform_data; in viacam_remove()
1299 video_unregister_device(&cam->vdev); in viacam_remove()
1300 v4l2_device_unregister(&cam->v4l2_dev); in viacam_remove()
1304 free_irq(viadev->pdev->irq, cam); in viacam_remove()
1305 via_sensor_power_release(cam); in viacam_remove()
1306 v4l2_ctrl_handler_free(&cam->ctrl_handler); in viacam_remove()
1307 kfree(cam); in viacam_remove()
1314 .name = "viafb-camera",