📄 meteor.c
字号:
return(EIO); /* already capturing */ count = mtr->rows * mtr->cols * mtr->depth; if (uio->uio_iov->iov_len < count) return(EINVAL); /* Start capture */ start_capture(mtr, METEOR_SINGLE); status=tsleep((caddr_t)mtr, METPRI, "capturing", 0); if (!status) /* successful capture */ status = uiomove((caddr_t)mtr->bigbuf, count, uio); else printf ("meteor%d: read: tsleep error %d\n", unit, status); mtr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK); return(status);}intmeteor_write(dev_t dev, struct uio *uio, int ioflag){ return(0);}intmeteor_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *pr){ int error; int unit; unsigned int temp; meteor_reg_t *mtr; struct meteor_counts *cnt; struct meteor_geomet *geo; struct meteor_mem *mem; struct meteor_capframe *frame;#ifdef METEOR_TEST_VIDEO struct meteor_video *video;#endif vm_offset_t buf; struct saa7116_regs *base; error = 0; if (!arg) return(EINVAL); unit = UNIT(minor(dev)); if (unit >= NMETEOR) /* unit out of range */ return(ENXIO); mtr = &(meteor[unit]); base = mtr->base; switch (cmd) { case METEORSTS: if(*arg) mtr->flags |= METEOR_WANT_TS; else mtr->flags &= ~METEOR_WANT_TS; break; case METEORGTS: if(mtr->flags & METEOR_WANT_TS) *arg = 1; else *arg = 0; break;#ifdef METEOR_TEST_VIDEO case METEORGVIDEO: video = (struct meteor_video *)arg; video->addr = mtr->video.addr; video->width = mtr->video.width; video->banksize = mtr->video.banksize; video->ramsize = mtr->video.ramsize; break; case METEORSVIDEO: video = (struct meteor_video *)arg; mtr->video.addr = video->addr; mtr->video.width = video->width; mtr->video.banksize = video->banksize; mtr->video.ramsize = video->ramsize; break;#endif case METEORSFPS: set_fps(mtr, *(u_short *)arg); break; case METEORGFPS: *(u_short *)arg = mtr->fps; break; case METEORSSIGNAL: mtr->signal = *(int *) arg; mtr->proc = pr; break; case METEORGSIGNAL: *(int *)arg = mtr->signal; break; case METEORSTATUS: /* get 7196 status */ temp = 0; SAA7196_WRITE(mtr, SAA7196_STDC, SAA7196_REG(mtr, SAA7196_STDC) | 0x02); SAA7196_READ(mtr); temp |= (base->i2c_read & 0xff000000L) >> 24; SAA7196_WRITE(mtr, SAA7196_STDC, SAA7196_REG(mtr, SAA7196_STDC) & ~0x02); SAA7196_READ(mtr); temp |= (base->i2c_read & 0xff000000L) >> 16; *(u_short *)arg = temp; break; case METEORSHUE: /* set hue */ SAA7196_WRITE(mtr, SAA7196_HUEC, *(char *)arg); break; case METEORGHUE: /* get hue */ *(char *)arg = SAA7196_REG(mtr, SAA7196_HUEC); break; case METEORSCHCV: /* set chrominance gain */ SAA7196_WRITE(mtr, SAA7196_CGAINR, *(char *)arg); break; case METEORGCHCV: /* get chrominance gain */ *(char *)arg = SAA7196_REG(mtr, SAA7196_CGAINR); break; case METEORSBRIG: /* set brightness */ SAA7196_WRITE(mtr, SAA7196_BRIG, *(char *)arg); break; case METEORGBRIG: /* get brightness */ *(char *)arg = SAA7196_REG(mtr, SAA7196_BRIG); break; case METEORSCSAT: /* set chroma saturation */ SAA7196_WRITE(mtr, SAA7196_CSAT, *(char *)arg); break; case METEORGCSAT: /* get chroma saturation */ *(char *)arg = SAA7196_REG(mtr, SAA7196_CSAT); break; case METEORSCONT: /* set contrast */ SAA7196_WRITE(mtr, SAA7196_CONT, *(char *)arg); break; case METEORGCONT: /* get contrast */ *(char *)arg = SAA7196_REG(mtr, SAA7196_CONT); break; case METEORSBT254: if((mtr->flags & METEOR_RGB) == 0) return EINVAL; temp = *(unsigned short *)arg; bt254_write(mtr, temp & 0xf, (temp & 0x0ff0) >> 4); break; case METEORGBT254: if((mtr->flags & METEOR_RGB) == 0) return EINVAL; temp = *(unsigned short *)arg & 0x7; *(unsigned short *)arg = mtr->bt254_reg[temp] << 4 | temp; break; case METEORSHWS: /* set horizontal window start */ SAA7196_WRITE(mtr, SAA7196_HWS, *(char *)arg); break; case METEORGHWS: /* get horizontal window start */ *(char *)arg = SAA7196_REG(mtr, SAA7196_HWS); break; case METEORSVWS: /* set vertical window start */ SAA7196_WRITE(mtr, SAA7196_VWS, *(char *)arg); break; case METEORGVWS: /* get vertical window start */ *(char *)arg = SAA7196_REG(mtr, SAA7196_VWS); break; case METEORSINPUT: /* set input device */ switch(*(unsigned long *)arg & METEOR_DEV_MASK) { case 0: /* default */ case METEOR_INPUT_DEV0: if(mtr->flags & METEOR_RGB) select_saa7196(mtr); mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0; SAA7196_WRITE(mtr, 0x0e, (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x0); SAA7196_WRITE(mtr, 0x06, (SAA7196_REG(mtr, 0x06) & ~0x80)); break; case METEOR_INPUT_DEV1: if(mtr->flags & METEOR_RGB) select_saa7196(mtr); mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) | METEOR_DEV1; SAA7196_WRITE(mtr, 0x0e, (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x1); SAA7196_WRITE(mtr, 0x06, (SAA7196_REG(mtr, 0x06) & ~0x80)); break; case METEOR_INPUT_DEV2: if(mtr->flags & METEOR_RGB) select_saa7196(mtr); mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) | METEOR_DEV2; SAA7196_WRITE(mtr, 0x0e, (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2); SAA7196_WRITE(mtr, 0x06, (SAA7196_REG(mtr, 0x06) & ~0x80)); break; case METEOR_INPUT_DEV3: if(mtr->flags & METEOR_RGB) select_saa7196(mtr); mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) | METEOR_DEV3; SAA7196_WRITE(mtr, 0x0e, (SAA7196_REG(mtr, 0x0e) | 0x3)); SAA7196_WRITE(mtr, 0x06, (SAA7196_REG(mtr, 0x06) & ~0x80) ); break; case METEOR_INPUT_DEV_SVIDEO: if(mtr->flags & METEOR_RGB) select_saa7196(mtr); mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) | METEOR_DEV_SVIDEO; SAA7196_WRITE(mtr, 0x0e, (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2); SAA7196_WRITE(mtr, 0x06, (SAA7196_REG(mtr, 0x06) & ~0x80) | 0x80); break; case METEOR_INPUT_DEV_RGB: if((mtr->flags & METEOR_RGB) == 0) return EINVAL; mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) | METEOR_DEV_RGB; SAA7196_WRITE(mtr, 0x0e, (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x3); SAA7196_WRITE(mtr, 0x06, (SAA7196_REG(mtr, 0x06) & ~0x80)); select_bt254(mtr); SAA7196_WRITE(mtr, 0x0e, /* chn 3 for synch */ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x3); break; default: return EINVAL; } break; case METEORGINPUT: /* get input device */ *(u_long *)arg = mtr->flags & METEOR_DEV_MASK; break; case METEORSFMT: /* set input format */ switch(*(unsigned long *)arg & METEOR_FORM_MASK ) { case 0: /* default */ case METEOR_FMT_NTSC: mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | METEOR_NTSC; SAA7196_WRITE(mtr, SAA7196_STDC, (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01)); SAA7196_WRITE(mtr, 0x0f, (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x40); SAA7196_WRITE(mtr, 0x22, 0x80); SAA7196_WRITE(mtr, 0x24, (SAA7196_REG(mtr, 0x24) & ~0x0c) | 0x08); SAA7196_WRITE(mtr, 0x26, 0xf0); SAA7196_WRITE(mtr, 0x28, (SAA7196_REG(mtr, 0x28) & ~0x0c)) ; if(mtr->flags & METEOR_RGB){ bt254_ntsc(mtr, 1); } break; case METEOR_FMT_PAL: mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | METEOR_PAL; SAA7196_WRITE(mtr, SAA7196_STDC, (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01)); SAA7196_WRITE(mtr, 0x0f, (SAA7196_REG(mtr, 0x0f) & ~0xe0)); SAA7196_WRITE(mtr, 0x22, 0x00); SAA7196_WRITE(mtr, 0x24, (SAA7196_REG(mtr, 0x24) | 0x0c)); SAA7196_WRITE(mtr, 0x26, 0x20); SAA7196_WRITE(mtr, 0x28, (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x04) ; if(mtr->flags & METEOR_RGB){ bt254_ntsc(mtr, 0); } break; case METEOR_FMT_SECAM: mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | METEOR_SECAM; SAA7196_WRITE(mtr, SAA7196_STDC, (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01) | 0x1); SAA7196_WRITE(mtr, 0x0f, (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x20); SAA7196_WRITE(mtr, 0x22, 0x00); SAA7196_WRITE(mtr, 0x24, (SAA7196_REG(mtr, 0x24) | 0x0c)); SAA7196_WRITE(mtr, 0x26, 0x20); SAA7196_WRITE(mtr, 0x28, (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x04) ; if(mtr->flags & METEOR_RGB){ bt254_ntsc(mtr, 0); } break; case METEOR_FMT_AUTOMODE: mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | METEOR_AUTOMODE; SAA7196_WRITE(mtr, SAA7196_STDC, (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01)); SAA7196_WRITE(mtr, 0x0f, (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x80); break; default: return EINVAL; } break; case METEORGFMT: /* get input format */ *(u_long *)arg = mtr->flags & METEOR_FORM_MASK; break; case METEORCAPTUR: temp = mtr->flags; switch (*(int *) arg) { case METEOR_CAP_SINGLE: if (mtr->bigbuf==0) /* no frame buffer allocated */ return(ENOMEM); if (temp & METEOR_CAP_MASK) return(EIO); /* already capturing */ start_capture(mtr, METEOR_SINGLE); /* wait for capture to complete */ error=tsleep((caddr_t)mtr, METPRI, "capturing", 0); if(error) printf("meteor%d: ioctl: tsleep error %d\n", unit, error); mtr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK); break; case METEOR_CAP_CONTINOUS: if (mtr->bigbuf==0) /* no frame buffer allocated */ return(ENOMEM); if (temp & METEOR_CAP_MASK) return(EIO); /* already capturing */ start_capture(mtr, METEOR_CONTIN); break; case METEOR_CAP_STOP_CONT: if (mtr->flags & METEOR_CONTIN) { /* turn off capture */ base->cap_cntl = 0x8ff0; mtr->flags &= ~(METEOR_CONTIN|METEOR_WANT_MASK); } break; default: error = EINVAL; break; } break; case METEORCAPFRM: frame = (struct meteor_capframe *) arg; if (!frame) return(EINVAL); switch (frame->command) { case METEOR_CAP_N_FRAMES: if (mtr->flags & METEOR_CAP_MASK) return(EIO); if (mtr->flags & (METEOR_YUV_PLANAR | METEOR_YUV_422)) /* XXX */ return(EINVAL); /* should fix intr so we allow these */ if (mtr->bigbuf == 0) return(ENOMEM); if ((mtr->frames < 2) || (frame->lowat < 1 || frame->lowat >= mtr->frames) || (frame->hiwat < 1 || frame->hiwat >= mtr->frames) || (frame->lowat > frame->hiwat)) return(EINVAL); /* meteor_mem structure is on the page after the data */ mem = mtr->mem = (struct meteor_mem *) (mtr->bigbuf + (round_page(mtr->frame_size * mtr->frames))); mtr->current = 1; mtr->synch_wait = 0; mem->num_bufs = mtr->frames; mem->frame_size= mtr->frame_size; /* user and kernel change these */ mem->lowat = frame->lowat; mem->hiwat = frame->hiwat; mem->active = 0; mem->num_active_bufs = 0; /* Start capture */ start_capture(mtr, METEOR_SYNCAP); break; case METEOR_CAP_STOP_FRAMES: if (mtr->flags & METEOR_SYNCAP) { /* turn off capture */ base->cap_cntl = 0x8ff0; mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK); } break; case METEOR_HALT_N_FRAMES: if(mtr->flags & METEOR_SYNCAP) { base->cap_cntl = 0x8ff0; mtr->flags &= ~(METEOR_WANT_MASK); } break; case METEOR_CONT_N_FRAMES: if(!(mtr->flags & METEOR_SYNCAP)) { error = EINVAL; break; } start_capture(mtr, METEOR_SYNCAP); break; default: error = EINVAL; break; } break; case METEORSETGEO: geo = (struct meteor_geomet *) arg; /* Either even or odd, if even & odd, then these a zero */ if((geo->oformat & METEOR_GEO_ODD_ONLY) && (geo->oformat & METEOR_GEO_EVEN_ONLY)) { printf("meteor%d: ioctl: Geometry odd or even only.\n", unit); return EINVAL; } /* set/clear even/odd flags */ if(geo->oformat & METEOR_GEO_ODD_ONLY) mtr->flags |= METEOR_ONLY_ODD_FIELDS; else mtr->flags &= ~METEOR_ONLY_ODD_FIELDS; if(geo->oformat & METEOR_GEO_EVEN_ONLY) mtr->flags |= METEOR_ONLY_EVEN_FIELDS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -