1
2
3
4
5
6
7
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/list.h>
13#include <linux/pci.h>
14#include <linux/gpio.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/videodev2.h>
18#include <media/v4l2-device.h>
19#include <media/v4l2-ioctl.h>
20#include <media/v4l2-ctrls.h>
21#include <media/v4l2-image-sizes.h>
22#include <media/i2c/ov7670.h>
23#include <media/videobuf-dma-sg.h>
24#include <linux/delay.h>
25#include <linux/dma-mapping.h>
26#include <linux/pm_qos.h>
27#include <linux/via-core.h>
28#include <linux/via-gpio.h>
29#include <linux/via_i2c.h>
30
31#ifdef CONFIG_X86
32#include <asm/olpc.h>
33#else
34#define machine_is_olpc(x) 0
35#endif
36
37#include "via-camera.h"
38
39MODULE_ALIAS("platform:viafb-camera");
40MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
41MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
42MODULE_LICENSE("GPL");
43
44static bool flip_image;
45module_param(flip_image, bool, 0444);
46MODULE_PARM_DESC(flip_image,
47 "If set, the sensor will be instructed to flip the image vertically.");
48
49static bool override_serial;
50module_param(override_serial, bool, 0444);
51MODULE_PARM_DESC(override_serial,
52 "The camera driver will normally refuse to load if the XO 1.5 serial port is enabled. Set this option to force-enable the camera.");
53
54
55
56
57enum viacam_opstate { S_IDLE = 0, S_RUNNING = 1 };
58
59struct via_camera {
60 struct v4l2_device v4l2_dev;
61 struct v4l2_ctrl_handler ctrl_handler;
62 struct video_device vdev;
63 struct v4l2_subdev *sensor;
64 struct platform_device *platdev;
65 struct viafb_dev *viadev;
66 struct mutex lock;
67 enum viacam_opstate opstate;
68 unsigned long flags;
69 struct pm_qos_request qos_request;
70
71
72
73 int power_gpio;
74 int reset_gpio;
75
76
77
78 void __iomem *mmio;
79 void __iomem *fbmem;
80 u32 fb_offset;
81
82
83
84
85
86 unsigned int cb_offsets[3];
87 u8 __iomem *cb_addrs[3];
88 int n_cap_bufs;
89 int next_buf;
90 struct videobuf_queue vb_queue;
91 struct list_head buffer_queue;
92
93
94
95 int users;
96 struct file *owner;
97
98
99
100
101
102
103
104 struct v4l2_pix_format sensor_format;
105 struct v4l2_pix_format user_format;
106 u32 mbus_code;
107};
108
109
110
111
112
113static struct via_camera *via_cam_info;
114
115
116
117
118#define CF_DMA_ACTIVE 0
119#define CF_CONFIG_NEEDED 1
120
121
122
123
124
125#define sensor_call(cam, optype, func, args...) \
126 v4l2_subdev_call(cam->sensor, optype, func, ##args)
127
128
129
130
131#define cam_err(cam, fmt, arg...) \
132 dev_err(&(cam)->platdev->dev, fmt, ##arg);
133#define cam_warn(cam, fmt, arg...) \
134 dev_warn(&(cam)->platdev->dev, fmt, ##arg);
135#define cam_dbg(cam, fmt, arg...) \
136 dev_dbg(&(cam)->platdev->dev, fmt, ##arg);
137
138
139
140
141
142
143
144static struct via_format {
145 __u8 *desc;
146 __u32 pixelformat;
147 int bpp;
148 u32 mbus_code;
149} via_formats[] = {
150 {
151 .desc = "YUYV 4:2:2",
152 .pixelformat = V4L2_PIX_FMT_YUYV,
153 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
154 .bpp = 2,
155 },
156
157
158
159
160};
161#define N_VIA_FMTS ARRAY_SIZE(via_formats)
162
163static struct via_format *via_find_format(u32 pixelformat)
164{
165 unsigned i;
166
167 for (i = 0; i < N_VIA_FMTS; i++)
168 if (via_formats[i].pixelformat == pixelformat)
169 return via_formats + i;
170
171 return via_formats;
172}
173
174
175
176
177
178
179
180static int via_sensor_power_setup(struct via_camera *cam)
181{
182 int ret;
183
184 cam->power_gpio = viafb_gpio_lookup("VGPIO3");
185 cam->reset_gpio = viafb_gpio_lookup("VGPIO2");
186 if (!gpio_is_valid(cam->power_gpio) || !gpio_is_valid(cam->reset_gpio)) {
187 dev_err(&cam->platdev->dev, "Unable to find GPIO lines\n");
188 return -EINVAL;
189 }
190 ret = gpio_request(cam->power_gpio, "viafb-camera");
191 if (ret) {
192 dev_err(&cam->platdev->dev, "Unable to request power GPIO\n");
193 return ret;
194 }
195 ret = gpio_request(cam->reset_gpio, "viafb-camera");
196 if (ret) {
197 dev_err(&cam->platdev->dev, "Unable to request reset GPIO\n");
198 gpio_free(cam->power_gpio);
199 return ret;
200 }
201 gpio_direction_output(cam->power_gpio, 0);
202 gpio_direction_output(cam->reset_gpio, 0);
203 return 0;
204}
205
206
207
208
209static void via_sensor_power_up(struct via_camera *cam)
210{
211 gpio_set_value(cam->power_gpio, 1);
212 gpio_set_value(cam->reset_gpio, 0);
213 msleep(20);
214 gpio_set_value(cam->reset_gpio, 1);
215 msleep(20);
216}
217
218static void via_sensor_power_down(struct via_camera *cam)
219{
220 gpio_set_value(cam->power_gpio, 0);
221 gpio_set_value(cam->reset_gpio, 0);
222}
223
224
225static void via_sensor_power_release(struct via_camera *cam)
226{
227 via_sensor_power_down(cam);
228 gpio_free(cam->power_gpio);
229 gpio_free(cam->reset_gpio);
230}
231
232
233
234
235
236
237
238static int viacam_set_flip(struct via_camera *cam)
239{
240 struct v4l2_control ctrl;
241
242 memset(&ctrl, 0, sizeof(ctrl));
243 ctrl.id = V4L2_CID_VFLIP;
244 ctrl.value = flip_image;
245 return v4l2_s_ctrl(NULL, cam->sensor->ctrl_handler, &ctrl);
246}
247
248
249
250
251
252static int viacam_configure_sensor(struct via_camera *cam)
253{
254 struct v4l2_subdev_format format = {
255 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
256 };
257 int ret;
258
259 v4l2_fill_mbus_format(&format.format, &cam->sensor_format, cam->mbus_code);
260 ret = sensor_call(cam, core, init, 0);
261 if (ret == 0)
262 ret = sensor_call(cam, pad, set_fmt, NULL, &format);
263
264
265
266 if (ret == 0)
267 ret = viacam_set_flip(cam);
268 return ret;
269}
270
271
272
273
274
275
276
277
278
279
280
281static inline void viacam_write_reg(struct via_camera *cam,
282 int reg, int value)
283{
284 iowrite32(value, cam->mmio + reg);
285}
286
287static inline int viacam_read_reg(struct via_camera *cam, int reg)
288{
289 return ioread32(cam->mmio + reg);
290}
291
292static inline void viacam_write_reg_mask(struct via_camera *cam,
293 int reg, int value, int mask)
294{
295 int tmp = viacam_read_reg(cam, reg);
296
297 tmp = (tmp & ~mask) | (value & mask);
298 viacam_write_reg(cam, reg, tmp);
299}
300
301
302
303
304
305static irqreturn_t viacam_quick_irq(int irq, void *data)
306{
307 struct via_camera *cam = data;
308 irqreturn_t ret = IRQ_NONE;
309 int icv;
310
311
312
313
314
315 spin_lock(&cam->viadev->reg_lock);
316 icv = viacam_read_reg(cam, VCR_INTCTRL);
317 if (icv & VCR_IC_EAV) {
318 icv |= VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL;
319 viacam_write_reg(cam, VCR_INTCTRL, icv);
320 ret = IRQ_WAKE_THREAD;
321 }
322 spin_unlock(&cam->viadev->reg_lock);
323 return ret;
324}
325
326
327
328
329static struct videobuf_buffer *viacam_next_buffer(struct via_camera *cam)
330{
331 unsigned long flags;
332 struct videobuf_buffer *buf = NULL;
333
334 spin_lock_irqsave(&cam->viadev->reg_lock, flags);
335 if (cam->opstate != S_RUNNING)
336 goto out;
337 if (list_empty(&cam->buffer_queue))
338 goto out;
339 buf = list_entry(cam->buffer_queue.next, struct videobuf_buffer, queue);
340 if (!waitqueue_active(&buf->done)) {
341 buf = NULL;
342 goto out;
343 }
344 list_del(&buf->queue);
345 buf->state = VIDEOBUF_ACTIVE;
346out:
347 spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
348 return buf;
349}
350
351
352
353
354static irqreturn_t viacam_irq(int irq, void *data)
355{
356 int bufn;
357 struct videobuf_buffer *vb;
358 struct via_camera *cam = data;
359 struct videobuf_dmabuf *vdma;
360
361
362
363
364
365 vb = viacam_next_buffer(cam);
366 if (vb == NULL)
367 goto done;
368
369
370
371 bufn = (viacam_read_reg(cam, VCR_INTCTRL) & VCR_IC_ACTBUF) >> 3;
372 bufn -= 1;
373 if (bufn < 0)
374 bufn = cam->n_cap_bufs - 1;
375
376
377
378 vdma = videobuf_to_dma(vb);
379 viafb_dma_copy_out_sg(cam->cb_offsets[bufn], vdma->sglist, vdma->sglen);
380 vb->state = VIDEOBUF_DONE;
381 vb->size = cam->user_format.sizeimage;
382 wake_up(&vb->done);
383done:
384 return IRQ_HANDLED;
385}
386
387
388
389
390
391
392
393
394
395static void viacam_int_enable(struct via_camera *cam)
396{
397 viacam_write_reg(cam, VCR_INTCTRL,
398 VCR_IC_INTEN|VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL);
399 viafb_irq_enable(VDE_I_C0AVEN);
400}
401
402static void viacam_int_disable(struct via_camera *cam)
403{
404 viafb_irq_disable(VDE_I_C0AVEN);
405 viacam_write_reg(cam, VCR_INTCTRL, 0);
406}
407
408
409
410
411
412
413
414
415
416static int viacam_ctlr_cbufs(struct via_camera *cam)
417{
418 int nbuf = cam->viadev->camera_fbmem_size/cam->sensor_format.sizeimage;
419 int i;
420 unsigned int offset;
421
422
423
424
425 if (nbuf >= 3) {
426 cam->n_cap_bufs = 3;
427 viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_3BUFS,
428 VCR_CI_3BUFS);
429 } else if (nbuf == 2) {
430 cam->n_cap_bufs = 2;
431 viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_3BUFS);
432 } else {
433 cam_warn(cam, "Insufficient frame buffer memory\n");
434 return -ENOMEM;
435 }
436
437
438
439 offset = cam->fb_offset;
440 for (i = 0; i < cam->n_cap_bufs; i++) {
441 cam->cb_offsets[i] = offset;
442 cam->cb_addrs[i] = cam->fbmem + offset;
443 viacam_write_reg(cam, VCR_VBUF1 + i*4, offset & VCR_VBUF_MASK);
444 offset += cam->sensor_format.sizeimage;
445 }
446 return 0;
447}
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466static void viacam_set_scale(struct via_camera *cam)
467{
468 unsigned int avscale;
469 int sf;
470
471 if (cam->user_format.width == VGA_WIDTH)
472 avscale = 0;
473 else {
474 sf = (cam->user_format.width*2048)/VGA_WIDTH;
475 avscale = VCR_AVS_HEN | sf;
476 }
477 if (cam->user_format.height < VGA_HEIGHT) {
478 sf = (1024*cam->user_format.height)/VGA_HEIGHT;
479 avscale |= VCR_AVS_VEN | (sf << 16);
480 }
481 viacam_write_reg(cam, VCR_AVSCALE, avscale);
482}
483
484
485
486
487
488static void viacam_ctlr_image(struct via_camera *cam)
489{
490 int cicreg;
491
492
493
494
495
496 viacam_write_reg(cam, VCR_CAPINTC, ~(VCR_CI_ENABLE|VCR_CI_CLKEN));
497
498
499
500
501 viacam_write_reg(cam, VCR_HORRANGE, 0x06200120);
502 viacam_write_reg(cam, VCR_VERTRANGE, 0x01de0000);
503 viacam_set_scale(cam);
504
505
506
507 viacam_write_reg(cam, VCR_MAXDATA,
508 (cam->sensor_format.height << 16) |
509 (cam->sensor_format.bytesperline >> 3));
510 viacam_write_reg(cam, VCR_MAXVBI, 0);
511 viacam_write_reg(cam, VCR_VSTRIDE,
512 cam->user_format.bytesperline & VCR_VS_STRIDE);
513
514
515
516
517
518
519
520 cicreg = VCR_CI_CLKEN |
521 0x08000000 |
522 VCR_CI_FLDINV |
523 VCR_CI_VREFINV |
524 VCR_CI_DIBOTH |
525 VCR_CI_CCIR601_8;
526 if (cam->n_cap_bufs == 3)
527 cicreg |= VCR_CI_3BUFS;
528
529
530
531 if (cam->user_format.pixelformat == V4L2_PIX_FMT_YUYV)
532 cicreg |= VCR_CI_YUYV;
533 else
534 cicreg |= VCR_CI_UYVY;
535 viacam_write_reg(cam, VCR_CAPINTC, cicreg);
536}
537
538
539static int viacam_config_controller(struct via_camera *cam)
540{
541 int ret;
542 unsigned long flags;
543
544 spin_lock_irqsave(&cam->viadev->reg_lock, flags);
545 ret = viacam_ctlr_cbufs(cam);
546 if (!ret)
547 viacam_ctlr_image(cam);
548 spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
549 clear_bit(CF_CONFIG_NEEDED, &cam->flags);
550 return ret;
551}
552
553
554
555
556static void viacam_start_engine(struct via_camera *cam)
557{
558 spin_lock_irq(&cam->viadev->reg_lock);
559 cam->next_buf = 0;
560 viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE);
561 viacam_int_enable(cam);
562 (void) viacam_read_reg(cam, VCR_CAPINTC);
563 cam->opstate = S_RUNNING;
564 spin_unlock_irq(&cam->viadev->reg_lock);
565}
566
567
568static void viacam_stop_engine(struct via_camera *cam)
569{
570 spin_lock_irq(&cam->viadev->reg_lock);
571 viacam_int_disable(cam);
572 viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_ENABLE);
573 (void) viacam_read_reg(cam, VCR_CAPINTC);
574 cam->opstate = S_IDLE;
575 spin_unlock_irq(&cam->viadev->reg_lock);
576}
577
578
579
580
581
582
583
584
585
586
587static int viacam_vb_buf_setup(struct videobuf_queue *q,
588 unsigned int *count, unsigned int *size)
589{
590 struct via_camera *cam = q->priv_data;
591
592 *size = cam->user_format.sizeimage;
593 if (*count == 0 || *count > 6)
594 *count = 6;
595 return 0;
596}
597
598
599
600
601static int viacam_vb_buf_prepare(struct videobuf_queue *q,
602 struct videobuf_buffer *vb, enum v4l2_field field)
603{
604 struct via_camera *cam = q->priv_data;
605
606 vb->size = cam->user_format.sizeimage;
607 vb->width = cam->user_format.width;
608 vb->height = cam->user_format.height;
609 vb->field = field;
610 if (vb->state == VIDEOBUF_NEEDS_INIT) {
611 int ret = videobuf_iolock(q, vb, NULL);
612 if (ret)
613 return ret;
614 }
615 vb->state = VIDEOBUF_PREPARED;
616 return 0;
617}
618
619
620
621
622
623
624static void viacam_vb_buf_queue(struct videobuf_queue *q,
625 struct videobuf_buffer *vb)
626{
627 struct via_camera *cam = q->priv_data;
628
629
630
631
632
633 vb->state = VIDEOBUF_QUEUED;
634 list_add_tail(&vb->queue, &cam->buffer_queue);
635}
636
637
638
639
640static void viacam_vb_buf_release(struct videobuf_queue *q,
641 struct videobuf_buffer *vb)
642{
643 struct via_camera *cam = q->priv_data;
644
645 videobuf_dma_unmap(&cam->platdev->dev, videobuf_to_dma(vb));
646 videobuf_dma_free(videobuf_to_dma(vb));
647 vb->state = VIDEOBUF_NEEDS_INIT;
648}
649
650static const struct videobuf_queue_ops viacam_vb_ops = {
651 .buf_setup = viacam_vb_buf_setup,
652 .buf_prepare = viacam_vb_buf_prepare,
653 .buf_queue = viacam_vb_buf_queue,
654 .buf_release = viacam_vb_buf_release,
655};
656
657
658
659
660static int viacam_open(struct file *filp)
661{
662 struct via_camera *cam = video_drvdata(filp);
663
664 filp->private_data = cam;
665
666
667
668
669 mutex_lock(&cam->lock);
670 if (cam->users == 0) {
671 int ret = viafb_request_dma();
672
673 if (ret) {
674 mutex_unlock(&cam->lock);
675 return ret;
676 }
677 via_sensor_power_up(cam);
678 set_bit(CF_CONFIG_NEEDED, &cam->flags);
679
680
681
682 videobuf_queue_sg_init(&cam->vb_queue, &viacam_vb_ops,
683 &cam->platdev->dev, &cam->viadev->reg_lock,
684 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
685 sizeof(struct videobuf_buffer), cam, NULL);
686 }
687 (cam->users)++;
688 mutex_unlock(&cam->lock);
689 return 0;
690}
691
692static int viacam_release(struct file *filp)
693{
694 struct via_camera *cam = video_drvdata(filp);
695
696 mutex_lock(&cam->lock);
697 (cam->users)--;
698
699
700
701
702 if (filp == cam->owner) {
703 videobuf_stop(&cam->vb_queue);
704
705
706
707
708
709
710 if (cam->opstate != S_IDLE)
711 viacam_stop_engine(cam);
712 cam->owner = NULL;
713 }
714
715
716
717 if (cam->users == 0) {
718 videobuf_mmap_free(&cam->vb_queue);
719 via_sensor_power_down(cam);
720 viafb_release_dma();
721 }
722 mutex_unlock(&cam->lock);
723 return 0;
724}
725
726
727
728
729static ssize_t viacam_read(struct file *filp, char __user *buffer,
730 size_t len, loff_t *pos)
731{
732 struct via_camera *cam = video_drvdata(filp);
733 int ret;
734
735 mutex_lock(&cam->lock);
736
737
738
739 if (cam->owner && cam->owner != filp) {
740 ret = -EBUSY;
741 goto out_unlock;
742 }
743 cam->owner = filp;
744
745
746
747 if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
748 ret = viacam_configure_sensor(cam);
749 if (!ret)
750 ret = viacam_config_controller(cam);
751 if (ret)
752 goto out_unlock;
753 }
754
755
756
757
758
759 INIT_LIST_HEAD(&cam->buffer_queue);
760 viacam_start_engine(cam);
761 ret = videobuf_read_stream(&cam->vb_queue, buffer, len, pos, 0,
762 filp->f_flags & O_NONBLOCK);
763 viacam_stop_engine(cam);
764
765
766out_unlock:
767 mutex_unlock(&cam->lock);
768 return ret;
769}
770
771
772static __poll_t viacam_poll(struct file *filp, struct poll_table_struct *pt)
773{
774 struct via_camera *cam = video_drvdata(filp);
775
776 return videobuf_poll_stream(filp, &cam->vb_queue, pt);
777}
778
779
780static int viacam_mmap(struct file *filp, struct vm_area_struct *vma)
781{
782 struct via_camera *cam = video_drvdata(filp);
783
784 return videobuf_mmap_mapper(&cam->vb_queue, vma);
785}
786
787
788
789static const struct v4l2_file_operations viacam_fops = {
790 .owner = THIS_MODULE,
791 .open = viacam_open,
792 .release = viacam_release,
793 .read = viacam_read,
794 .poll = viacam_poll,
795 .mmap = viacam_mmap,
796 .unlocked_ioctl = video_ioctl2,
797};
798
799
800
801
802
803
804
805
806
807static int viacam_enum_input(struct file *filp, void *priv,
808 struct v4l2_input *input)
809{
810 if (input->index != 0)
811 return -EINVAL;
812
813 input->type = V4L2_INPUT_TYPE_CAMERA;
814 input->std = V4L2_STD_ALL;
815 strcpy(input->name, "Camera");
816 return 0;
817}
818
819static int viacam_g_input(struct file *filp, void *priv, unsigned int *i)
820{
821 *i = 0;
822 return 0;
823}
824
825static int viacam_s_input(struct file *filp, void *priv, unsigned int i)
826{
827 if (i != 0)
828 return -EINVAL;
829 return 0;
830}
831
832static int viacam_s_std(struct file *filp, void *priv, v4l2_std_id std)
833{
834 return 0;
835}
836
837static int viacam_g_std(struct file *filp, void *priv, v4l2_std_id *std)
838{
839 *std = V4L2_STD_NTSC_M;
840 return 0;
841}
842
843
844
845
846
847static const struct v4l2_pix_format viacam_def_pix_format = {
848 .width = VGA_WIDTH,
849 .height = VGA_HEIGHT,
850 .pixelformat = V4L2_PIX_FMT_YUYV,
851 .field = V4L2_FIELD_NONE,
852 .bytesperline = VGA_WIDTH * 2,
853 .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2,
854};
855
856static const u32 via_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8;
857
858static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv,
859 struct v4l2_fmtdesc *fmt)
860{
861 if (fmt->index >= N_VIA_FMTS)
862 return -EINVAL;
863 strlcpy(fmt->description, via_formats[fmt->index].desc,
864 sizeof(fmt->description));
865 fmt->pixelformat = via_formats[fmt->index].pixelformat;
866 return 0;
867}
868
869
870
871
872
873static void viacam_fmt_pre(struct v4l2_pix_format *userfmt,
874 struct v4l2_pix_format *sensorfmt)
875{
876 *sensorfmt = *userfmt;
877 if (userfmt->width < QCIF_WIDTH || userfmt->height < QCIF_HEIGHT) {
878 userfmt->width = QCIF_WIDTH;
879 userfmt->height = QCIF_HEIGHT;
880 }
881 if (userfmt->width > VGA_WIDTH || userfmt->height > VGA_HEIGHT) {
882 userfmt->width = VGA_WIDTH;
883 userfmt->height = VGA_HEIGHT;
884 }
885 sensorfmt->width = VGA_WIDTH;
886 sensorfmt->height = VGA_HEIGHT;
887}
888
889static void viacam_fmt_post(struct v4l2_pix_format *userfmt,
890 struct v4l2_pix_format *sensorfmt)
891{
892 struct via_format *f = via_find_format(userfmt->pixelformat);
893
894 sensorfmt->bytesperline = sensorfmt->width * f->bpp;
895 sensorfmt->sizeimage = sensorfmt->height * sensorfmt->bytesperline;
896 userfmt->pixelformat = sensorfmt->pixelformat;
897 userfmt->field = sensorfmt->field;
898 userfmt->bytesperline = 2 * userfmt->width;
899 userfmt->sizeimage = userfmt->bytesperline * userfmt->height;
900}
901
902
903
904
905
906static int viacam_do_try_fmt(struct via_camera *cam,
907 struct v4l2_pix_format *upix, struct v4l2_pix_format *spix)
908{
909 int ret;
910 struct v4l2_subdev_pad_config pad_cfg;
911 struct v4l2_subdev_format format = {
912 .which = V4L2_SUBDEV_FORMAT_TRY,
913 };
914 struct via_format *f = via_find_format(upix->pixelformat);
915
916 upix->pixelformat = f->pixelformat;
917 viacam_fmt_pre(upix, spix);
918 v4l2_fill_mbus_format(&format.format, spix, f->mbus_code);
919 ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format);
920 v4l2_fill_pix_format(spix, &format.format);
921 viacam_fmt_post(upix, spix);
922 return ret;
923}
924
925
926
927static int viacam_try_fmt_vid_cap(struct file *filp, void *priv,
928 struct v4l2_format *fmt)
929{
930 struct via_camera *cam = priv;
931 struct v4l2_format sfmt;
932 int ret;
933
934 mutex_lock(&cam->lock);
935 ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
936 mutex_unlock(&cam->lock);
937 return ret;
938}
939
940
941static int viacam_g_fmt_vid_cap(struct file *filp, void *priv,
942 struct v4l2_format *fmt)
943{
944 struct via_camera *cam = priv;
945
946 mutex_lock(&cam->lock);
947 fmt->fmt.pix = cam->user_format;
948 mutex_unlock(&cam->lock);
949 return 0;
950}
951
952static int viacam_s_fmt_vid_cap(struct file *filp, void *priv,
953 struct v4l2_format *fmt)
954{
955 struct via_camera *cam = priv;
956 int ret;
957 struct v4l2_format sfmt;
958 struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat);
959
960
961
962
963
964 mutex_lock(&cam->lock);
965 if (cam->opstate != S_IDLE) {
966 ret = -EBUSY;
967 goto out;
968 }
969
970
971
972
973 ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
974 if (ret)
975 goto out;
976
977
978
979 cam->user_format = fmt->fmt.pix;
980 cam->sensor_format = sfmt.fmt.pix;
981 cam->mbus_code = f->mbus_code;
982 ret = viacam_configure_sensor(cam);
983 if (!ret)
984 ret = viacam_config_controller(cam);
985out:
986 mutex_unlock(&cam->lock);
987 return ret;
988}
989
990static int viacam_querycap(struct file *filp, void *priv,
991 struct v4l2_capability *cap)
992{
993 strcpy(cap->driver, "via-camera");
994 strcpy(cap->card, "via-camera");
995 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
996 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
997 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
998 return 0;
999}
1000
1001
1002
1003
1004static int viacam_reqbufs(struct file *filp, void *priv,
1005 struct v4l2_requestbuffers *rb)
1006{
1007 struct via_camera *cam = priv;
1008
1009 return videobuf_reqbufs(&cam->vb_queue, rb);
1010}
1011
1012static int viacam_querybuf(struct file *filp, void *priv,
1013 struct v4l2_buffer *buf)
1014{
1015 struct via_camera *cam = priv;
1016
1017 return videobuf_querybuf(&cam->vb_queue, buf);
1018}
1019
1020static int viacam_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
1021{
1022 struct via_camera *cam = priv;
1023
1024 return videobuf_qbuf(&cam->vb_queue, buf);
1025}
1026
1027static int viacam_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
1028{
1029 struct via_camera *cam = priv;
1030
1031 return videobuf_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
1032}
1033
1034static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
1035{
1036 struct via_camera *cam = priv;
1037 int ret = 0;
1038
1039 if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1040 return -EINVAL;
1041
1042 mutex_lock(&cam->lock);
1043 if (cam->opstate != S_IDLE) {
1044 ret = -EBUSY;
1045 goto out;
1046 }
1047
1048
1049
1050 if (cam->owner && cam->owner != filp) {
1051 ret = -EBUSY;
1052 goto out;
1053 }
1054 cam->owner = filp;
1055
1056
1057
1058 if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
1059 ret = viacam_configure_sensor(cam);
1060 if (ret)
1061 goto out;
1062 ret = viacam_config_controller(cam);
1063 if (ret)
1064 goto out;
1065 }
1066
1067
1068
1069
1070
1071
1072 pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
1073
1074
1075
1076 INIT_LIST_HEAD(&cam->buffer_queue);
1077 ret = videobuf_streamon(&cam->vb_queue);
1078 if (!ret)
1079 viacam_start_engine(cam);
1080out:
1081 mutex_unlock(&cam->lock);
1082 return ret;
1083}
1084
1085static int viacam_streamoff(struct file *filp, void *priv, enum v4l2_buf_type t)
1086{
1087 struct via_camera *cam = priv;
1088 int ret;
1089
1090 if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1091 return -EINVAL;
1092 mutex_lock(&cam->lock);
1093 if (cam->opstate != S_RUNNING) {
1094 ret = -EINVAL;
1095 goto out;
1096 }
1097 pm_qos_remove_request(&cam->qos_request);
1098 viacam_stop_engine(cam);
1099
1100
1101
1102
1103
1104 ret = videobuf_streamoff(&cam->vb_queue);
1105 INIT_LIST_HEAD(&cam->buffer_queue);
1106out:
1107 mutex_unlock(&cam->lock);
1108 return ret;
1109}
1110
1111
1112
1113static int viacam_g_parm(struct file *filp, void *priv,
1114 struct v4l2_streamparm *parm)
1115{
1116 struct via_camera *cam = priv;
1117 int ret;
1118
1119 mutex_lock(&cam->lock);
1120 ret = v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm);
1121 mutex_unlock(&cam->lock);
1122 parm->parm.capture.readbuffers = cam->n_cap_bufs;
1123 return ret;
1124}
1125
1126static int viacam_s_parm(struct file *filp, void *priv,
1127 struct v4l2_streamparm *parm)
1128{
1129 struct via_camera *cam = priv;
1130 int ret;
1131
1132 mutex_lock(&cam->lock);
1133 ret = v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm);
1134 mutex_unlock(&cam->lock);
1135 parm->parm.capture.readbuffers = cam->n_cap_bufs;
1136 return ret;
1137}
1138
1139static int viacam_enum_framesizes(struct file *filp, void *priv,
1140 struct v4l2_frmsizeenum *sizes)
1141{
1142 if (sizes->index != 0)
1143 return -EINVAL;
1144 sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
1145 sizes->stepwise.min_width = QCIF_WIDTH;
1146 sizes->stepwise.min_height = QCIF_HEIGHT;
1147 sizes->stepwise.max_width = VGA_WIDTH;
1148 sizes->stepwise.max_height = VGA_HEIGHT;
1149 sizes->stepwise.step_width = sizes->stepwise.step_height = 1;
1150 return 0;
1151}
1152
1153static int viacam_enum_frameintervals(struct file *filp, void *priv,
1154 struct v4l2_frmivalenum *interval)
1155{
1156 struct via_camera *cam = priv;
1157 struct v4l2_subdev_frame_interval_enum fie = {
1158 .index = interval->index,
1159 .code = cam->mbus_code,
1160 .width = cam->sensor_format.width,
1161 .height = cam->sensor_format.height,
1162 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1163 };
1164 int ret;
1165
1166 mutex_lock(&cam->lock);
1167 ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie);
1168 mutex_unlock(&cam->lock);
1169 if (ret)
1170 return ret;
1171 interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1172 interval->discrete = fie.interval;
1173 return 0;
1174}
1175
1176
1177
1178static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
1179 .vidioc_enum_input = viacam_enum_input,
1180 .vidioc_g_input = viacam_g_input,
1181 .vidioc_s_input = viacam_s_input,
1182 .vidioc_s_std = viacam_s_std,
1183 .vidioc_g_std = viacam_g_std,
1184 .vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap,
1185 .vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap,
1186 .vidioc_g_fmt_vid_cap = viacam_g_fmt_vid_cap,
1187 .vidioc_s_fmt_vid_cap = viacam_s_fmt_vid_cap,
1188 .vidioc_querycap = viacam_querycap,
1189 .vidioc_reqbufs = viacam_reqbufs,
1190 .vidioc_querybuf = viacam_querybuf,
1191 .vidioc_qbuf = viacam_qbuf,
1192 .vidioc_dqbuf = viacam_dqbuf,
1193 .vidioc_streamon = viacam_streamon,
1194 .vidioc_streamoff = viacam_streamoff,
1195 .vidioc_g_parm = viacam_g_parm,
1196 .vidioc_s_parm = viacam_s_parm,
1197 .vidioc_enum_framesizes = viacam_enum_framesizes,
1198 .vidioc_enum_frameintervals = viacam_enum_frameintervals,
1199};
1200
1201
1202
1203
1204
1205
1206#ifdef CONFIG_PM
1207
1208static int viacam_suspend(void *priv)
1209{
1210 struct via_camera *cam = priv;
1211 enum viacam_opstate state = cam->opstate;
1212
1213 if (cam->opstate != S_IDLE) {
1214 viacam_stop_engine(cam);
1215 cam->opstate = state;
1216 }
1217
1218 return 0;
1219}
1220
1221static int viacam_resume(void *priv)
1222{
1223 struct via_camera *cam = priv;
1224 int ret = 0;
1225
1226
1227
1228
1229 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1230 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1231 viacam_int_disable(cam);
1232 set_bit(CF_CONFIG_NEEDED, &cam->flags);
1233
1234
1235
1236 if (cam->users > 0)
1237 via_sensor_power_up(cam);
1238 else
1239 via_sensor_power_down(cam);
1240
1241
1242
1243 if (cam->opstate != S_IDLE) {
1244 mutex_lock(&cam->lock);
1245 ret = viacam_configure_sensor(cam);
1246 if (!ret)
1247 ret = viacam_config_controller(cam);
1248 mutex_unlock(&cam->lock);
1249 if (!ret)
1250 viacam_start_engine(cam);
1251 }
1252
1253 return ret;
1254}
1255
1256static struct viafb_pm_hooks viacam_pm_hooks = {
1257 .suspend = viacam_suspend,
1258 .resume = viacam_resume
1259};
1260
1261#endif
1262
1263
1264
1265
1266
1267static const struct video_device viacam_v4l_template = {
1268 .name = "via-camera",
1269 .minor = -1,
1270 .tvnorms = V4L2_STD_NTSC_M,
1271 .fops = &viacam_fops,
1272 .ioctl_ops = &viacam_ioctl_ops,
1273 .release = video_device_release_empty,
1274};
1275
1276
1277
1278
1279
1280
1281
1282#define VIACAM_SERIAL_DEVFN 0x88
1283#define VIACAM_SERIAL_CREG 0x46
1284#define VIACAM_SERIAL_BIT 0x40
1285
1286static bool viacam_serial_is_enabled(void)
1287{
1288 struct pci_bus *pbus = pci_find_bus(0, 0);
1289 u8 cbyte;
1290
1291 if (!pbus)
1292 return false;
1293 pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1294 VIACAM_SERIAL_CREG, &cbyte);
1295 if ((cbyte & VIACAM_SERIAL_BIT) == 0)
1296 return false;
1297 if (!override_serial) {
1298 printk(KERN_NOTICE "Via camera: serial port is enabled, " \
1299 "refusing to load.\n");
1300 printk(KERN_NOTICE "Specify override_serial=1 to force " \
1301 "module loading.\n");
1302 return true;
1303 }
1304 printk(KERN_NOTICE "Via camera: overriding serial port\n");
1305 pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1306 VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
1307 return false;
1308}
1309
1310static struct ov7670_config sensor_cfg = {
1311
1312 .clock_speed = 90,
1313};
1314
1315static int viacam_probe(struct platform_device *pdev)
1316{
1317 int ret;
1318 struct i2c_adapter *sensor_adapter;
1319 struct viafb_dev *viadev = pdev->dev.platform_data;
1320 struct i2c_board_info ov7670_info = {
1321 .type = "ov7670",
1322 .addr = 0x42 >> 1,
1323 .platform_data = &sensor_cfg,
1324 };
1325
1326
1327
1328
1329
1330
1331
1332 struct via_camera *cam;
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342 if (viadev->camera_fbmem_size < (VGA_HEIGHT*VGA_WIDTH*4)) {
1343 printk(KERN_ERR "viacam: insufficient FB memory reserved\n");
1344 return -ENOMEM;
1345 }
1346 if (viadev->engine_mmio == NULL) {
1347 printk(KERN_ERR "viacam: No I/O memory, so no pictures\n");
1348 return -ENOMEM;
1349 }
1350
1351 if (machine_is_olpc() && viacam_serial_is_enabled())
1352 return -EBUSY;
1353
1354
1355
1356
1357 cam = kzalloc (sizeof(struct via_camera), GFP_KERNEL);
1358 if (cam == NULL)
1359 return -ENOMEM;
1360 via_cam_info = cam;
1361 cam->platdev = pdev;
1362 cam->viadev = viadev;
1363 cam->users = 0;
1364 cam->owner = NULL;
1365 cam->opstate = S_IDLE;
1366 cam->user_format = cam->sensor_format = viacam_def_pix_format;
1367 mutex_init(&cam->lock);
1368 INIT_LIST_HEAD(&cam->buffer_queue);
1369 cam->mmio = viadev->engine_mmio;
1370 cam->fbmem = viadev->fbmem;
1371 cam->fb_offset = viadev->camera_fbmem_offset;
1372 cam->flags = 1 << CF_CONFIG_NEEDED;
1373 cam->mbus_code = via_def_mbus_code;
1374
1375
1376
1377 ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev);
1378 if (ret) {
1379 dev_err(&pdev->dev, "Unable to register v4l2 device\n");
1380 goto out_free;
1381 }
1382 ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10);
1383 if (ret)
1384 goto out_unregister;
1385 cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler;
1386
1387
1388
1389 pdev->dev.dma_mask = &viadev->pdev->dma_mask;
1390 dma_set_mask(&pdev->dev, 0xffffffff);
1391
1392
1393
1394
1395 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1396 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1397
1398
1399
1400 ret = via_sensor_power_setup(cam);
1401 if (ret)
1402 goto out_ctrl_hdl_free;
1403 via_sensor_power_up(cam);
1404
1405
1406
1407
1408
1409 sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
1410 cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, sensor_adapter,
1411 &ov7670_info, NULL);
1412 if (cam->sensor == NULL) {
1413 dev_err(&pdev->dev, "Unable to find the sensor!\n");
1414 ret = -ENODEV;
1415 goto out_power_down;
1416 }
1417
1418
1419
1420 viacam_int_disable(cam);
1421 ret = request_threaded_irq(viadev->pdev->irq, viacam_quick_irq,
1422 viacam_irq, IRQF_SHARED, "via-camera", cam);
1423 if (ret)
1424 goto out_power_down;
1425
1426
1427
1428 cam->vdev = viacam_v4l_template;
1429 cam->vdev.v4l2_dev = &cam->v4l2_dev;
1430 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
1431 if (ret)
1432 goto out_irq;
1433 video_set_drvdata(&cam->vdev, cam);
1434
1435#ifdef CONFIG_PM
1436
1437
1438
1439 viacam_pm_hooks.private = cam;
1440 viafb_pm_register(&viacam_pm_hooks);
1441#endif
1442
1443
1444 via_sensor_power_down(cam);
1445 return 0;
1446
1447out_irq:
1448 free_irq(viadev->pdev->irq, cam);
1449out_power_down:
1450 via_sensor_power_release(cam);
1451out_ctrl_hdl_free:
1452 v4l2_ctrl_handler_free(&cam->ctrl_handler);
1453out_unregister:
1454 v4l2_device_unregister(&cam->v4l2_dev);
1455out_free:
1456 kfree(cam);
1457 return ret;
1458}
1459
1460static int viacam_remove(struct platform_device *pdev)
1461{
1462 struct via_camera *cam = via_cam_info;
1463 struct viafb_dev *viadev = pdev->dev.platform_data;
1464
1465 video_unregister_device(&cam->vdev);
1466 v4l2_device_unregister(&cam->v4l2_dev);
1467 free_irq(viadev->pdev->irq, cam);
1468 via_sensor_power_release(cam);
1469 v4l2_ctrl_handler_free(&cam->ctrl_handler);
1470 kfree(cam);
1471 via_cam_info = NULL;
1472 return 0;
1473}
1474
1475static struct platform_driver viacam_driver = {
1476 .driver = {
1477 .name = "viafb-camera",
1478 },
1479 .probe = viacam_probe,
1480 .remove = viacam_remove,
1481};
1482
1483module_platform_driver(viacam_driver);
1484