static int tsif_init_one(struct tsif_chrdev *the_dev, int index) { int rc; pr_info("%s[%d]\n", __func__, index); cdev_init(&the_dev->cdev, &tsif_fops); the_dev->cdev.owner = THIS_MODULE; init_waitqueue_head(&the_dev->wq_read); rc = cdev_add(&the_dev->cdev, tsif_dev0++, 1); the_dev->dev = device_create(tsif_class, NULL, the_dev->cdev.dev, the_dev, "tsif%d", index); if (IS_ERR(the_dev->dev)) { rc = PTR_ERR(the_dev->dev); pr_err("device_create failed: %d\n", rc); goto err_create; } the_dev->cookie = tsif_attach(index, tsif_notify, the_dev); #ifdef CONFIG_SKY_TDMB_TSIF_IF tsif_dev_tdmb = the_dev; // cys test #endif if (IS_ERR(the_dev->cookie)) { rc = PTR_ERR(the_dev->cookie); pr_err("tsif_attach failed: %d\n", rc); goto err_attach; } /* now data buffer is not allocated yet */ tsif_get_info(the_dev->cookie, &the_dev->data_buffer, NULL); dev_info(the_dev->dev, "Device %d.%d attached to TSIF, buffer size %d\n", MAJOR(the_dev->cdev.dev), MINOR(the_dev->cdev.dev), the_dev->buf_size_packets); return 0; err_attach: device_destroy(tsif_class, the_dev->cdev.dev); err_create: cdev_del(&the_dev->cdev); return rc; }
/** * Attach to TSIF driver and start TSIF operation. * * @mpq_demux: the mpq_demux we are working on. * * Return error code. */ static int mpq_tsif_dmx_start(struct mpq_demux *mpq_demux) { int ret = 0; int tsif; struct tsif_driver_info *tsif_driver; MPQ_DVB_DBG_PRINT("%s executed\n", __func__); /* determine the TSIF we are reading from */ if (mpq_demux->source == DMX_SOURCE_FRONT0) { tsif = 0; } else if (mpq_demux->source == DMX_SOURCE_FRONT1) { tsif = 1; } else { /* invalid source */ MPQ_DVB_ERR_PRINT( "%s: invalid input source (%d)\n", __func__, mpq_demux->source); return -EINVAL; } if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex)) return -ERESTARTSYS; if (mpq_dmx_tsif_info.tsif[tsif].ref_count == 0) { tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver); /* Attach to TSIF driver */ tsif_driver->tsif_handler = tsif_attach(tsif, mpq_tsif_callback, (void *)tsif); if (IS_ERR_OR_NULL(tsif_driver->tsif_handler)) { tsif_driver->tsif_handler = NULL; mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex); MPQ_DVB_DBG_PRINT("%s: tsif_attach(%d) failed\n", __func__, tsif); return -ENODEV; } ret = tsif_set_clk_inverse(tsif_driver->tsif_handler, clock_inv); if (ret < 0) { MPQ_DVB_ERR_PRINT( "%s: tsif_set_clk_inverse (%d) failed\n", __func__, clock_inv); } /* Set TSIF driver mode */ ret = tsif_set_mode(tsif_driver->tsif_handler, tsif_mode); if (ret < 0) { MPQ_DVB_ERR_PRINT("%s: tsif_set_mode (%d) failed\n", __func__, tsif_mode); } /* Set TSIF buffer configuration */ ret = tsif_set_buf_config(tsif_driver->tsif_handler, threshold, DMX_TSIF_CHUNKS_IN_BUF); if (ret < 0) { MPQ_DVB_ERR_PRINT( "%s: tsif_set_buf_config (%d, %d) failed\n", __func__, threshold, DMX_TSIF_CHUNKS_IN_BUF); MPQ_DVB_ERR_PRINT("Using default TSIF driver values\n"); } /* Start TSIF driver */ ret = tsif_start(tsif_driver->tsif_handler); if (ret < 0) { mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex); MPQ_DVB_ERR_PRINT("%s: tsif_start failed\n", __func__); return ret; } /* * Get data buffer information from TSIF driver * (must be called after tsif_start) */ tsif_get_info(tsif_driver->tsif_handler, &(tsif_driver->data_buffer), &(tsif_driver->buffer_size)); /* save pointer to the mpq_demux we are working on */ mpq_dmx_tsif_info.tsif[tsif].mpq_demux = mpq_demux; } mpq_dmx_tsif_info.tsif[tsif].ref_count++; mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex); return ret; }
static int mpq_tsif_dmx_start(struct mpq_demux *mpq_demux) { int ret = 0; int tsif; struct tsif_driver_info *tsif_driver; MPQ_DVB_DBG_PRINT("%s executed\n", __func__); if (mpq_demux->source == DMX_SOURCE_FRONT0) { tsif = 0; } else if (mpq_demux->source == DMX_SOURCE_FRONT1) { tsif = 1; } else { MPQ_DVB_ERR_PRINT( "%s: invalid input source (%d)\n", __func__, mpq_demux->source); return -EINVAL; } if (mutex_lock_interruptible(&mpq_dmx_tsif_info.tsif[tsif].mutex)) return -ERESTARTSYS; if (mpq_dmx_tsif_info.tsif[tsif].ref_count == 0) { tsif_driver = &(mpq_dmx_tsif_info.tsif[tsif].tsif_driver); tsif_driver->tsif_handler = tsif_attach(tsif, mpq_tsif_callback, (void *)tsif); if (IS_ERR_OR_NULL(tsif_driver->tsif_handler)) { tsif_driver->tsif_handler = NULL; mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex); MPQ_DVB_DBG_PRINT("%s: tsif_attach(%d) failed\n", __func__, tsif); return -ENODEV; } ret = tsif_set_clk_inverse(tsif_driver->tsif_handler, clock_inv); if (ret < 0) { MPQ_DVB_ERR_PRINT( "%s: tsif_set_clk_inverse (%d) failed\n", __func__, clock_inv); } ret = tsif_set_mode(tsif_driver->tsif_handler, tsif_mode); if (ret < 0) { MPQ_DVB_ERR_PRINT("%s: tsif_set_mode (%d) failed\n", __func__, tsif_mode); } ret = tsif_set_buf_config(tsif_driver->tsif_handler, threshold, DMX_TSIF_CHUNKS_IN_BUF); if (ret < 0) { MPQ_DVB_ERR_PRINT( "%s: tsif_set_buf_config (%d, %d) failed\n", __func__, threshold, DMX_TSIF_CHUNKS_IN_BUF); MPQ_DVB_ERR_PRINT("Using default TSIF driver values\n"); } ret = tsif_start(tsif_driver->tsif_handler); if (ret < 0) { mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex); MPQ_DVB_ERR_PRINT("%s: tsif_start failed\n", __func__); return ret; } tsif_get_info(tsif_driver->tsif_handler, &(tsif_driver->data_buffer), &(tsif_driver->buffer_size)); mpq_dmx_tsif_info.tsif[tsif].mpq_demux = mpq_demux; } mpq_dmx_tsif_info.tsif[tsif].ref_count++; mutex_unlock(&mpq_dmx_tsif_info.tsif[tsif].mutex); return ret; }