Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * FireDTV driver (formerly known as FireSAT)
0004  *
0005  * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
0006  * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
0007  */
0008 
0009 #include <linux/bitops.h>
0010 #include <linux/device.h>
0011 #include <linux/errno.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/mutex.h>
0015 #include <linux/types.h>
0016 
0017 #include <media/dmxdev.h>
0018 #include <media/dvb_demux.h>
0019 #include <media/dvbdev.h>
0020 #include <media/dvb_frontend.h>
0021 
0022 #include "firedtv.h"
0023 
0024 static int alloc_channel(struct firedtv *fdtv)
0025 {
0026     int i;
0027 
0028     for (i = 0; i < 16; i++)
0029         if (!__test_and_set_bit(i, &fdtv->channel_active))
0030             break;
0031     return i;
0032 }
0033 
0034 static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
0035 {
0036     int i, n;
0037 
0038     for (i = 0, n = 0; i < 16; i++)
0039         if (test_bit(i, &fdtv->channel_active))
0040             pid[n++] = fdtv->channel_pid[i];
0041     *pidc = n;
0042 }
0043 
0044 static inline void dealloc_channel(struct firedtv *fdtv, int i)
0045 {
0046     __clear_bit(i, &fdtv->channel_active);
0047 }
0048 
0049 int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
0050 {
0051     struct firedtv *fdtv = dvbdmxfeed->demux->priv;
0052     int pidc, c, ret;
0053     u16 pids[16];
0054 
0055     switch (dvbdmxfeed->type) {
0056     case DMX_TYPE_TS:
0057     case DMX_TYPE_SEC:
0058         break;
0059     default:
0060         dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
0061             dvbdmxfeed->type);
0062         return -EINVAL;
0063     }
0064 
0065     if (mutex_lock_interruptible(&fdtv->demux_mutex))
0066         return -EINTR;
0067 
0068     if (dvbdmxfeed->type == DMX_TYPE_TS) {
0069         switch (dvbdmxfeed->pes_type) {
0070         case DMX_PES_VIDEO:
0071         case DMX_PES_AUDIO:
0072         case DMX_PES_TELETEXT:
0073         case DMX_PES_PCR:
0074         case DMX_PES_OTHER:
0075             c = alloc_channel(fdtv);
0076             break;
0077         default:
0078             dev_err(fdtv->device,
0079                 "can't start dmx feed: invalid pes type %u\n",
0080                 dvbdmxfeed->pes_type);
0081             ret = -EINVAL;
0082             goto out;
0083         }
0084     } else {
0085         c = alloc_channel(fdtv);
0086     }
0087 
0088     if (c > 15) {
0089         dev_err(fdtv->device, "can't start dmx feed: busy\n");
0090         ret = -EBUSY;
0091         goto out;
0092     }
0093 
0094     dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
0095     fdtv->channel_pid[c] = dvbdmxfeed->pid;
0096     collect_channels(fdtv, &pidc, pids);
0097 
0098     if (dvbdmxfeed->pid == 8192) {
0099         ret = avc_tuner_get_ts(fdtv);
0100         if (ret) {
0101             dealloc_channel(fdtv, c);
0102             dev_err(fdtv->device, "can't get TS\n");
0103             goto out;
0104         }
0105     } else {
0106         ret = avc_tuner_set_pids(fdtv, pidc, pids);
0107         if (ret) {
0108             dealloc_channel(fdtv, c);
0109             dev_err(fdtv->device, "can't set PIDs\n");
0110             goto out;
0111         }
0112     }
0113 out:
0114     mutex_unlock(&fdtv->demux_mutex);
0115 
0116     return ret;
0117 }
0118 
0119 int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
0120 {
0121     struct dvb_demux *demux = dvbdmxfeed->demux;
0122     struct firedtv *fdtv = demux->priv;
0123     int pidc, c, ret;
0124     u16 pids[16];
0125 
0126     if (dvbdmxfeed->type == DMX_TYPE_TS &&
0127         !((dvbdmxfeed->ts_type & TS_PACKET) &&
0128           (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
0129 
0130         if (dvbdmxfeed->ts_type & TS_DECODER) {
0131             if (dvbdmxfeed->pes_type >= DMX_PES_OTHER ||
0132                 !demux->pesfilter[dvbdmxfeed->pes_type])
0133                 return -EINVAL;
0134 
0135             demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
0136             demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
0137         }
0138 
0139         if (!(dvbdmxfeed->ts_type & TS_DECODER &&
0140               dvbdmxfeed->pes_type < DMX_PES_OTHER))
0141             return 0;
0142     }
0143 
0144     if (mutex_lock_interruptible(&fdtv->demux_mutex))
0145         return -EINTR;
0146 
0147     c = (unsigned long)dvbdmxfeed->priv;
0148     dealloc_channel(fdtv, c);
0149     collect_channels(fdtv, &pidc, pids);
0150 
0151     ret = avc_tuner_set_pids(fdtv, pidc, pids);
0152 
0153     mutex_unlock(&fdtv->demux_mutex);
0154 
0155     return ret;
0156 }
0157 
0158 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
0159 
0160 int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
0161 {
0162     int err;
0163 
0164     err = dvb_register_adapter(&fdtv->adapter, name,
0165                    THIS_MODULE, fdtv->device, adapter_nr);
0166     if (err < 0)
0167         goto fail_log;
0168 
0169     /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
0170     fdtv->demux.dmx.capabilities = 0;
0171 
0172     fdtv->demux.priv    = fdtv;
0173     fdtv->demux.filternum   = 16;
0174     fdtv->demux.feednum = 16;
0175     fdtv->demux.start_feed  = fdtv_start_feed;
0176     fdtv->demux.stop_feed   = fdtv_stop_feed;
0177     fdtv->demux.write_to_decoder = NULL;
0178 
0179     err = dvb_dmx_init(&fdtv->demux);
0180     if (err)
0181         goto fail_unreg_adapter;
0182 
0183     fdtv->dmxdev.filternum    = 16;
0184     fdtv->dmxdev.demux        = &fdtv->demux.dmx;
0185     fdtv->dmxdev.capabilities = 0;
0186 
0187     err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
0188     if (err)
0189         goto fail_dmx_release;
0190 
0191     fdtv->frontend.source = DMX_FRONTEND_0;
0192 
0193     err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
0194     if (err)
0195         goto fail_dmxdev_release;
0196 
0197     err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
0198                            &fdtv->frontend);
0199     if (err)
0200         goto fail_rem_frontend;
0201 
0202     err = dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
0203     if (err)
0204         goto fail_disconnect_frontend;
0205 
0206     fdtv_frontend_init(fdtv, name);
0207     err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
0208     if (err)
0209         goto fail_net_release;
0210 
0211     err = fdtv_ca_register(fdtv);
0212     if (err)
0213         dev_info(fdtv->device,
0214              "Conditional Access Module not enabled\n");
0215     return 0;
0216 
0217 fail_net_release:
0218     dvb_net_release(&fdtv->dvbnet);
0219 fail_disconnect_frontend:
0220     fdtv->demux.dmx.close(&fdtv->demux.dmx);
0221 fail_rem_frontend:
0222     fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
0223 fail_dmxdev_release:
0224     dvb_dmxdev_release(&fdtv->dmxdev);
0225 fail_dmx_release:
0226     dvb_dmx_release(&fdtv->demux);
0227 fail_unreg_adapter:
0228     dvb_unregister_adapter(&fdtv->adapter);
0229 fail_log:
0230     dev_err(fdtv->device, "DVB initialization failed\n");
0231     return err;
0232 }
0233 
0234 void fdtv_dvb_unregister(struct firedtv *fdtv)
0235 {
0236     fdtv_ca_release(fdtv);
0237     dvb_unregister_frontend(&fdtv->fe);
0238     dvb_net_release(&fdtv->dvbnet);
0239     fdtv->demux.dmx.close(&fdtv->demux.dmx);
0240     fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
0241     dvb_dmxdev_release(&fdtv->dmxdev);
0242     dvb_dmx_release(&fdtv->demux);
0243     dvb_unregister_adapter(&fdtv->adapter);
0244 }