20 #include <linux/kernel.h>
21 #include <linux/module.h>
30 #define SOLO_HW_BPL 2048
31 #define SOLO_DISP_PIX_FIELD V4L2_FIELD_INTERLACED
34 #define solo_vlines(__solo) (__solo->video_vsize * 2)
35 #define solo_image_size(__solo) (solo_bytesperline(__solo) * \
37 #define solo_bytesperline(__solo) (__solo->video_hsize * 2)
39 #define MIN_VID_BUFFERS 4
55 MODULE_PARM_DESC(video_nr,
"videoX start number, -1 is autodetect (default)");
85 static void solo_win_setup(
struct solo_dev *solo_dev,
u8 ch,
86 int sx,
int sy,
int ex,
int ey,
int scale)
103 static int solo_v4l2_ch_ext_4up(
struct solo_dev *solo_dev,
u8 idx,
int on)
112 for (i = ch; i < ch + 4; i++)
121 solo_win_setup(solo_dev, ch, 0, 0, solo_dev->
video_hsize / 2,
123 solo_win_setup(solo_dev, ch + 1, solo_dev->
video_hsize / 2, 0,
126 solo_win_setup(solo_dev, ch + 2, 0,
solo_vlines(solo_dev) / 2,
128 solo_win_setup(solo_dev, ch + 3, solo_dev->
video_hsize / 2,
135 static int solo_v4l2_ch_ext_16up(
struct solo_dev *solo_dev,
int on)
140 for (i = 0; i < 16; i++)
151 for (sy = 0, i = 0; i < 4; i++, sy += ysize) {
152 solo_win_setup(solo_dev, i * 4, 0, sy, hsize,
154 solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy,
155 hsize * 2, sy + ysize, 5);
156 solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy,
157 hsize * 3, sy + ysize, 5);
158 solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy,
165 static int solo_v4l2_ch(
struct solo_dev *solo_dev,
u8 ch,
int on)
169 if (ch < solo_dev->nr_chans) {
170 solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->
video_hsize,
184 return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on);
187 return solo_v4l2_ch_ext_16up(solo_dev, on);
190 static int solo_v4l2_set_ch(
struct solo_dev *solo_dev,
u8 ch)
198 solo_v4l2_ch(solo_dev, ch, 1);
227 u32 ext_addr,
int size,
int repeat,
int ext_size)
230 int ret = disp_flush_descs(fh);
236 size, repeat, ext_size);
245 struct solo_dev *solo_dev = fh->
solo_dev;
247 unsigned int fdma_addr;
258 if (erase_off(solo_dev)) {
263 void *
p = sg_virt(sg);
266 for (i = 0; i < len; i += 2) {
268 ((
u8 *)p)[i + 1] = 0x00;
297 if (sg_size_left < line_len) {
298 int this_addr = fdma_addr;
300 while (line_len > 0) {
311 this_write =
min(sg_size_left, line_len);
313 if (disp_push_desc(fh, sg_dma, this_addr,
317 line_len -= this_write;
318 sg_size_left -= this_write;
319 sg_dma += this_write;
320 this_addr += this_write;
328 lines =
min(sg_size_left / line_len,
331 if (disp_push_desc(fh, sg_dma, fdma_addr, line_len,
337 sg_dma += lines * line_len;
338 sg_size_left -= lines * line_len;
341 error = disp_flush_descs(fh);
361 unsigned int cur_write;
364 spin_lock(&fh->
slock);
372 if (!waitqueue_active(&vb->
done))
383 spin_unlock(&fh->
slock);
385 solo_fillbuf(fh, vb);
389 spin_unlock(&fh->
slock);
392 static int solo_thread(
void *
data)
395 struct solo_dev *solo_dev = fh->
solo_dev;
436 struct solo_dev *solo_dev = fh->
solo_dev;
450 struct solo_dev *solo_dev = fh->
solo_dev;
481 struct solo_dev *solo_dev = fh->
solo_dev;
499 .buf_setup = solo_buf_setup,
500 .buf_prepare = solo_buf_prepare,
501 .buf_queue = solo_buf_queue,
502 .buf_release = solo_buf_release,
505 static unsigned int solo_v4l2_poll(
struct file *
file,
520 static int solo_v4l2_open(
struct file *
file)
522 struct solo_dev *solo_dev = video_drvdata(file);
535 ret = solo_start_thread(fh);
550 static ssize_t solo_v4l2_read(
struct file *file,
char __user *data,
551 size_t count, loff_t *ppos)
559 static int solo_v4l2_release(
struct file *file)
565 solo_stop_thread(fh);
571 static int solo_querycap(
struct file *file,
void *
priv,
575 struct solo_dev *solo_dev = fh->
solo_dev;
580 pci_name(solo_dev->
pdev));
588 static int solo_enum_ext_input(
struct solo_dev *solo_dev,
591 static const char *dispnames_1[] = {
"4UP" };
592 static const char *dispnames_2[] = {
"4UP-1",
"4UP-2" };
593 static const char *dispnames_5[] = {
594 "4UP-1",
"4UP-2",
"4UP-3",
"4UP-4",
"16UP"
596 const char **dispnames;
601 if (solo_dev->
nr_ext == 5)
602 dispnames = dispnames_5;
603 else if (solo_dev->
nr_ext == 2)
604 dispnames = dispnames_2;
606 dispnames = dispnames_1;
614 static int solo_enum_input(
struct file *file,
void *priv,
618 struct solo_dev *solo_dev = fh->
solo_dev;
621 int ret = solo_enum_ext_input(solo_dev, input);
643 static int solo_set_input(
struct file *file,
void *priv,
unsigned int index)
647 return solo_v4l2_set_ch(fh->
solo_dev, index);
650 static int solo_get_input(
struct file *file,
void *priv,
unsigned int *
index)
659 static int solo_enum_fmt_cap(
struct file *file,
void *priv,
671 static int solo_try_fmt_cap(
struct file *file,
void *priv,
675 struct solo_dev *solo_dev = fh->
solo_dev;
699 static int solo_set_fmt_cap(
struct file *file,
void *priv,
709 return solo_try_fmt_cap(file, priv, f);
712 static int solo_get_fmt_cap(
struct file *file,
void *priv,
716 struct solo_dev *solo_dev = fh->
solo_dev;
730 static int solo_reqbufs(
struct file *file,
void *priv,
738 static int solo_querybuf(
struct file *file,
void *priv,
struct v4l2_buffer *
buf)
745 static int solo_qbuf(
struct file *file,
void *priv,
struct v4l2_buffer *
buf)
752 static int solo_dqbuf(
struct file *file,
void *priv,
struct v4l2_buffer *
buf)
759 static int solo_streamon(
struct file *file,
void *priv,
enum v4l2_buf_type i)
769 static int solo_streamoff(
struct file *file,
void *priv,
enum v4l2_buf_type i)
779 static int solo_s_std(
struct file *file,
void *priv,
v4l2_std_id *i)
784 static const u32 solo_motion_ctrls[] = {
789 static const u32 *solo_ctrl_classes[] = {
794 static int solo_disp_queryctrl(
struct file *file,
void *priv,
818 static int solo_disp_g_ctrl(
struct file *file,
void *priv,
822 struct solo_dev *solo_dev = fh->
solo_dev;
833 static int solo_disp_s_ctrl(
struct file *file,
void *priv,
837 struct solo_dev *solo_dev = fh->
solo_dev;
863 .open = solo_v4l2_open,
864 .release = solo_v4l2_release,
865 .read = solo_v4l2_read,
866 .poll = solo_v4l2_poll,
867 .mmap = solo_v4l2_mmap,
872 .vidioc_querycap = solo_querycap,
873 .vidioc_s_std = solo_s_std,
875 .vidioc_enum_input = solo_enum_input,
876 .vidioc_s_input = solo_set_input,
877 .vidioc_g_input = solo_get_input,
879 .vidioc_enum_fmt_vid_cap = solo_enum_fmt_cap,
880 .vidioc_try_fmt_vid_cap = solo_try_fmt_cap,
881 .vidioc_s_fmt_vid_cap = solo_set_fmt_cap,
882 .vidioc_g_fmt_vid_cap = solo_get_fmt_cap,
884 .vidioc_reqbufs = solo_reqbufs,
885 .vidioc_querybuf = solo_querybuf,
886 .vidioc_qbuf = solo_qbuf,
887 .vidioc_dqbuf = solo_dqbuf,
888 .vidioc_streamon = solo_streamon,
889 .vidioc_streamoff = solo_streamoff,
891 .vidioc_queryctrl = solo_disp_queryctrl,
892 .vidioc_g_ctrl = solo_disp_g_ctrl,
893 .vidioc_s_ctrl = solo_disp_s_ctrl,
898 .fops = &solo_v4l2_fops,
899 .ioctl_ops = &solo_v4l2_ioctl_ops,
918 *solo_dev->
vfd = solo_v4l2_template;
919 solo_dev->
vfd->parent = &solo_dev->
pdev->dev;
928 video_set_drvdata(solo_dev->
vfd, solo_dev);
930 snprintf(solo_dev->
vfd->name,
sizeof(solo_dev->
vfd->name),
"%s (%i)",
936 dev_info(&solo_dev->
pdev->dev,
"Display as /dev/video%d with "
937 "%d inputs (%d extended)\n", solo_dev->
vfd->num,
941 for (i = 0; i < solo_dev->
nr_chans; i++) {
942 solo_v4l2_set_ch(solo_dev, i);
943 while (erase_off(solo_dev))
948 solo_v4l2_set_ch(solo_dev, 0);
949 while (erase_off(solo_dev))