int saa7134_tuner_callback(void *ptr, int command, int arg) { u8 sync_control; struct saa7134_dev *dev = ptr; switch (dev->tuner_type) { case TUNER_PHILIPS_TDA8290: switch (command) { case 0: /* switch LNA gain through GPIO 22*/ saa7134_set_gpio(dev, 22, arg) ; break; case 1: /* vsync output at GPIO22. 50 / 60Hz */ dprintk("setting GPIO22 to vsync %d\n", arg); saa_andorb(SAA7134_VIDEO_PORT_CTRL3, 0x80, 0x80); saa_andorb(SAA7134_VIDEO_PORT_CTRL6, 0x0f, 0x03); if (arg == 1) sync_control = 11; else sync_control = 17; saa_writeb(SAA7134_VGATE_START, sync_control); saa_writeb(SAA7134_VGATE_STOP, sync_control + 1); saa_andorb(SAA7134_MISC_VGATE_MSB, 0x03, 0x00); break; default: return -EINVAL; } break; default: return -ENODEV; } return 0; }
static void ts_reset_encoder(struct saa7134_dev* dev) { if (!dev->empress_started) return; saa_writeb(SAA7134_SPECIAL_MODE, 0x00); msleep(10); saa_writeb(SAA7134_SPECIAL_MODE, 0x01); msleep(100); dev->empress_started = 0; }
static void stop_streaming(struct vb2_queue *vq) { struct saa7134_dmaqueue *dmaq = vq->drv_priv; struct saa7134_dev *dev = dmaq->dev; saa7134_ts_stop_streaming(vq); saa_writeb(SAA7134_SPECIAL_MODE, 0x00); msleep(20); saa_writeb(SAA7134_SPECIAL_MODE, 0x01); msleep(100); /* Mute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); dev->empress_started = 0; }
int saa7134_ts_init_hw(struct saa7134_dev *dev) { /* deactivate TS softreset */ saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* TSSOP high active, TSVAL high active, TSLOCK ignored */ saa_writeb(SAA7134_TS_PARALLEL, 0x6c); saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1)); saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff)); saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff)); /* TSNOPIT=0, TSCOLAP=0 */ saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); return 0; }
static int ts_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct saa7134_dev *dev = video_drvdata(file); int err; dprintk("open dev=%s\n", video_device_node_name(vdev)); err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) return err; if (atomic_read(&dev->empress_users)) goto done; /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); atomic_inc(&dev->empress_users); file->private_data = dev; err = 0; done: mutex_unlock(&dev->empress_tsq.vb_lock); return err; }
static int start_streaming(struct vb2_queue *vq, unsigned int count) { struct saa7134_dmaqueue *dmaq = vq->drv_priv; struct saa7134_dev *dev = dmaq->dev; u32 leading_null_bytes = 0; int err; err = saa7134_ts_start_streaming(vq, count); if (err) return err; /* If more cards start to need this, then this should probably be added to the card definitions. */ switch (dev->board) { case SAA7134_BOARD_BEHOLD_M6: case SAA7134_BOARD_BEHOLD_M63: case SAA7134_BOARD_BEHOLD_M6_EXTRA: leading_null_bytes = 1; break; } saa_call_all(dev, core, init, leading_null_bytes); /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); dev->empress_started = 1; return 0; }
static int ts_open(struct file *file) { int minor = video_devdata(file)->minor; struct saa7134_dev *dev; int err; lock_kernel(); list_for_each_entry(dev, &saa7134_devlist, devlist) if (dev->empress_dev && dev->empress_dev->minor == minor) goto found; unlock_kernel(); return -ENODEV; found: dprintk("open minor=%d\n",minor); err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; if (atomic_read(&dev->empress_users)) goto done_up; /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); atomic_inc(&dev->empress_users); file->private_data = dev; err = 0; done_up: mutex_unlock(&dev->empress_tsq.vb_lock); done: unlock_kernel(); return err; }
static int ts_open(struct inode *inode, struct file *file) { int minor = iminor(inode); struct saa7134_dev *dev; int err; list_for_each_entry(dev, &saa7134_devlist, devlist) if (dev->empress_dev && dev->empress_dev->minor == minor) goto found; return -ENODEV; found: dprintk("open minor=%d\n",minor); err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; if (dev->empress_users) goto done_up; /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); dev->empress_users++; file->private_data = dev; err = 0; done_up: mutex_unlock(&dev->empress_tsq.vb_lock); done: return err; }
/* Function for stop TS */ int saa7134_ts_stop(struct saa7134_dev *dev) { dprintk("TS stop\n"); BUG_ON(!dev->ts_started); /* Stop TS stream */ switch (saa7134_boards[dev->board].ts_type) { case SAA7134_MPEG_TS_PARALLEL: saa_writeb(SAA7134_TS_PARALLEL, 0x6c); dev->ts_started = 0; break; case SAA7134_MPEG_TS_SERIAL: saa_writeb(SAA7134_TS_SERIAL0, 0x40); dev->ts_started = 0; break; } return 0; }
static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; /* stop the encoder */ ts_reset_encoder(dev); /* Mute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); return 0; }
/* Function for start TS */ int saa7134_ts_start(struct saa7134_dev *dev) { dprintk("TS start\n"); BUG_ON(dev->ts_started); saa_writeb(SAA7134_TS_SERIAL1, 0x00); saa_writeb(SAA7134_TS_SERIAL1, 0x03); saa_writeb(SAA7134_TS_SERIAL1, 0x00); saa_writeb(SAA7134_TS_SERIAL1, 0x01); /* TS clock non-inverted */ saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* Start TS stream */ switch (saa7134_boards[dev->board].ts_type) { case SAA7134_MPEG_TS_PARALLEL: saa_writeb(SAA7134_TS_SERIAL0, 0x40); saa_writeb(SAA7134_TS_PARALLEL, 0xec); break; case SAA7134_MPEG_TS_SERIAL: saa_writeb(SAA7134_TS_SERIAL0, 0xd8); saa_writeb(SAA7134_TS_PARALLEL, 0x6c); saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); saa_writeb(SAA7134_TS_SERIAL1, 0x02); break; } dev->ts_started = 1; return 0; }