#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dvb/dmx.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <media/dmxdev.h>
#include <media/dvbdev.h>
#include <media/dvb_demux.h>
#include <media/dvb_frontend.h>
#include <media/dvb_net.h>
#include "c8sectpfe-common.h"
#include "c8sectpfe-core.h"
#include "c8sectpfe-dvb.h"
static int register_dvb(struct stdemux *demux, struct dvb_adapter *adap,
void *start_feed, void *stop_feed,
struct c8sectpfei *fei)
{ … }
static void unregister_dvb(struct stdemux *demux)
{ … }
static struct c8sectpfe *c8sectpfe_create(struct c8sectpfei *fei,
void *start_feed,
void *stop_feed)
{
struct c8sectpfe *c8sectpfe;
int result;
int i, j;
short int ids[] = { -1 };
c8sectpfe = kzalloc(sizeof(struct c8sectpfe), GFP_KERNEL);
if (!c8sectpfe)
goto err1;
mutex_init(&c8sectpfe->lock);
c8sectpfe->device = fei->dev;
result = dvb_register_adapter(&c8sectpfe->adapter, "STi c8sectpfe",
THIS_MODULE, fei->dev, ids);
if (result < 0) {
dev_err(fei->dev, "dvb_register_adapter failed (errno = %d)\n",
result);
goto err2;
}
c8sectpfe->adapter.priv = fei;
for (i = 0; i < fei->tsin_count; i++) {
c8sectpfe->demux[i].tsin_index = i;
c8sectpfe->demux[i].c8sectpfei = fei;
result = register_dvb(&c8sectpfe->demux[i], &c8sectpfe->adapter,
start_feed, stop_feed, fei);
if (result < 0) {
dev_err(fei->dev,
"register_dvb feed=%d failed (errno = %d)\n",
result, i);
for (j = 0; j < i; j++)
unregister_dvb(&c8sectpfe->demux[j]);
goto err3;
}
}
c8sectpfe->num_feeds = fei->tsin_count;
return c8sectpfe;
err3:
dvb_unregister_adapter(&c8sectpfe->adapter);
err2:
kfree(c8sectpfe);
err1:
return NULL;
};
static void c8sectpfe_delete(struct c8sectpfe *c8sectpfe)
{
int i;
if (!c8sectpfe)
return;
for (i = 0; i < c8sectpfe->num_feeds; i++)
unregister_dvb(&c8sectpfe->demux[i]);
dvb_unregister_adapter(&c8sectpfe->adapter);
kfree(c8sectpfe);
};
void c8sectpfe_tuner_unregister_frontend(struct c8sectpfe *c8sectpfe,
struct c8sectpfei *fei)
{
int n;
struct channel_info *tsin;
for (n = 0; n < fei->tsin_count; n++) {
tsin = fei->channel_data[n];
if (tsin) {
if (tsin->frontend) {
dvb_unregister_frontend(tsin->frontend);
dvb_frontend_detach(tsin->frontend);
}
i2c_put_adapter(tsin->i2c_adapter);
if (tsin->i2c_client) {
module_put(tsin->i2c_client->dev.driver->owner);
i2c_unregister_device(tsin->i2c_client);
}
}
}
c8sectpfe_delete(c8sectpfe);
};
int c8sectpfe_tuner_register_frontend(struct c8sectpfe **c8sectpfe,
struct c8sectpfei *fei,
void *start_feed,
void *stop_feed)
{ … }