diff options
author | Ralph Metzler <rjkm@metzlerbros.de> | 2011-01-10 06:36:15 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 20:31:45 -0300 |
commit | 0f0b270f905bbb0c8e75988ceaf10ff9a401e712 (patch) | |
tree | 03fd199d1cc923a1182b51f6b737cadbd2f4f5fb /drivers/media/dvb/ngene/ngene-dvb.c | |
parent | 8a484719c790772bc51c87c56323611752361bef (diff) |
[media] ngene: CXD2099AR Common Interface driver
Driver for the Common Interface Controller CXD2099AR.
Supports the CI of the cineS2 DVB-S2.
For now, data is passed through '/dev/dvb/adapterX/sec0':
- Encrypted data must be written to 'sec0'.
- Decrypted data can be read from 'sec0'.
- Setup the CAM using device 'ca0'.
Signed-off-by: Ralph Metzler <rjkm@metzlerbros.de>
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-dvb.c')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-dvb.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 8bb159370c70..0b4943233166 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c @@ -47,6 +47,64 @@ /* COMMAND API interface ****************************************************/ /****************************************************************************/ +static ssize_t ts_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + struct dvb_device *dvbdev = file->private_data; + struct ngene_channel *chan = dvbdev->priv; + struct ngene *dev = chan->dev; + + if (wait_event_interruptible(dev->tsout_rbuf.queue, + dvb_ringbuffer_free + (&dev->tsout_rbuf) >= count) < 0) + return 0; + + dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); + + return count; +} + +static ssize_t ts_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + struct dvb_device *dvbdev = file->private_data; + struct ngene_channel *chan = dvbdev->priv; + struct ngene *dev = chan->dev; + int left, avail; + + left = count; + while (left) { + if (wait_event_interruptible( + dev->tsin_rbuf.queue, + dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0) + return -EAGAIN; + avail = dvb_ringbuffer_avail(&dev->tsin_rbuf); + if (avail > left) + avail = left; + dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail); + left -= avail; + buf += avail; + } + return count; +} + +static const struct file_operations ci_fops = { + .owner = THIS_MODULE, + .read = ts_read, + .write = ts_write, + .open = dvb_generic_open, + .release = dvb_generic_release, +}; + +struct dvb_device ngene_dvbdev_ci = { + .priv = 0, + .readers = -1, + .writers = -1, + .users = -1, + .fops = &ci_fops, +}; + + /****************************************************************************/ /* DVB functions and API interface ******************************************/ /****************************************************************************/ @@ -63,11 +121,19 @@ static void swap_buffer(u32 *p, u32 len) void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; + struct ngene *dev = chan->dev; + if (flags & DF_SWAP32) + swap_buffer(buf, len); + if (dev->ci.en && chan->number == 2) { + if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) { + dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len); + wake_up_interruptible(&dev->tsin_rbuf.queue); + } + return 0; + } if (chan->users > 0) { - if (flags & DF_SWAP32) - swap_buffer(buf, len); dvb_dmx_swfilter(&chan->demux, buf, len); } return NULL; |