DM6467视频输出芯片驱动分析

输出的芯片驱动跟采集芯片的驱动类似,TI也提供了输出芯片驱动的接口,它提供了和采集芯片类似的头文件,要编写主要是根据include/media/davinci/vid_encoder_if.h 这个头文件进行编写。

主要是定义了视频编码设备的结构体,结构体如下:

/**

 * struct vid_encoder_device

 * @name: Name of the encoder device

 * @channel_id:  Id of the channel to which encoder is connected

 * @capabilities: encoder capabilities. This is only for VBI capabilities

 * @initialize: Pointer to initialize function to initialize encoder

 * @mode_ops: Set of functions pointers for standard related functions

 * @ctrl_ops: Set of functions pointers for control related functions

 * @output_ops: Set of functions pointers for output related functions

 * @fmt_ops: Set of functions pointers for format related functions

 * @params_ops: Set of functions pointers for params related functions

 * @misc_ops: Set of functions pointers for miscellaneous functions functions

 * @deinitialize: functions pointer to de-initialize functio

 * @start_display: function to start display.

 * @stop_display: function to stop display.

 * @write_vbi_data: function to write sliced vbi data.

 * @enable_vbi: Function to enable support for RAW VBI.

 * @enable_hbi: Function to enable support for RAW HBI.

 * @set_vbi_services: function to enable sliced vbi services

 *

 * Description:

 * output ops structure

 *   Channel_id is used when encoder support multiple channels. In this case

 *   encoder module will use the channel id to select the channel for

 *   which the operation applies.

 *   initialize() called by encoder manager to initialize the encoder. Usually

 *   called before invoking any operations on the encoder.flag may be used by

 *   the encoder module to do different level of initialization. Encoder

 *   module must set a default output and mode in this code.

 *   deinitialize() called to deinitialize the current encoder that is active

 *   before initializing the new encoder.

 */

struct vid_encoder_device {

u8 name[VID_ENC_NAME_MAX_CHARS];  

int channel_id;

u32 capabilities;

int (*initialize) (struct vid_encoder_device * enc, int flag);

struct vid_enc_mode_ops *mode_ops;

struct vid_enc_control_ops *ctrl_ops;

struct vid_enc_output_ops *output_ops;

struct vid_enc_param_ops *params_ops;

struct vid_enc_misc_ops *misc_ops;

int (*write_vbi_data) (struct vid_enc_sliced_vbi_data * data,

       struct vid_encoder_device * enc);

int (*enable_vbi) (int flag, struct vid_encoder_device * enc);

int (*enable_hbi) (int flag, struct vid_encoder_device * enc);

int (*set_vbi_services) (struct vid_enc_sliced_vbi_service * services,

 struct vid_encoder_device * enc);

int (*get_sliced_cap) (struct vid_enc_sliced_vbi_service *,

       struct vid_encoder_device * enc);

int (*deinitialize) (struct vid_encoder_device * enc);

int (*start_display) (struct vid_encoder_device * enc);

int (*stop_display) (struct vid_encoder_device * enc);

};

同时也包含了在drivers/media/video/davinci/davinci_enc_mngr.c定义的注册和反注册的两个接口,供其他模块使用。

261 /**

262  * vid_enc_register_encoder

263  * @encoder: pointer to the encoder device structure

264  * Returns: Zero if successful, or non-zero otherwise

265  *

266  * Description:

267  * Register the encoder module with the encoder manager

268  * This is implemented by the encoder Manager

269  */

270 int vid_enc_register_encoder(struct vid_encoder_device

271                              *encoder);

272 

273 /**

274  * vid_enc_unregister_encoder

275  * @encoder: pointer to the encoder device structure

276  * Returns: Zero if successful, or non-zero otherwise

277  *

278  * Description:

279  * Unregister the encoder module with the encoder manager

280  * This is implemented by the encoder Manager

281  */

282 int vid_enc_unregister_encoder(struct vid_encoder_device

283                                *encoder);

视频输出设备结构体在9034中定义如下:

 538 static struct vid_encoder_device sii9034_dev[SII9034_NUM_CHANNELS] = {

 539         {               

 540          .name = "SII9034",     

 541          .channel_id = 0,

 542          .capabilities = 0,

 543          .initialize = sii9034_initialize,

 544          .mode_ops = &standards_ops,

 545          .ctrl_ops = &controls_ops,

 546          .output_ops = &outputs_ops,

 547          .params_ops = ¶ms_ops,

 548          .deinitialize = sii9034_deinitialize,

 549          .misc_ops = NULL,

 550          .write_vbi_data = NULL,

 551          .enable_vbi = NULL,

 552          .enable_hbi = NULL,

 553          .set_vbi_services = NULL,

 554          .get_sliced_cap = NULL,

 555          .start_display = sii9034_start_display,

 556          .stop_display = sii9034_stop_display}

 557 };

编写9034的驱动主要完成以上的一些操作,

 515 /* Global structures variables */用户空间和内核空间的操作

 516 static struct vid_enc_param_ops params_ops = {

 517         .setparams = sii9034_set_params,

 518         .getparams = sii9034_get_params

 519 };

 520 //一些控制信息

 521 static struct vid_enc_control_ops controls_ops = {

 522         .setcontrol = sii9034_setcontrol,

 523         .getcontrol = sii9034_getcontrol

 524 };

 525 //输出的一些操作

 526 static struct vid_enc_output_ops outputs_ops = {

 527         .count = SII9034_MAX_NO_OUTPUTS,

 528         .enumoutput = sii9034_enumoutput,

 529         .setoutput = sii9034_setoutput, //通过index设置输出的索引

 530         .getoutput = sii9034_getoutput

 531 };

 532 

 533 static struct vid_enc_mode_ops standards_ops = {

 534         .setmode = sii9034_setstd,

 535         .getmode = sii9034_getstd,

 536 };

 537 

9034的初始化函数 sii9034_i2c_init9034模块的初始化主要是初始化I2C设备和注册vid_encoder_device,具体函数如下所示:

1910 /* This function used to initialize the i2c driver */

1911 static int sii9034_i2c_init(void)

1912 {

1913         int err = 0;

1914         int i = 0, j;

1915         /* Take instance of driver */

1916         struct i2c_driver *driver;

1917 

1918         static char strings[SII9034_NUM_CHANNELS][80] = {

1919                 "SII9034"

1920         };

1921     

1922         for (i = 0; i < SII9034_NUM_CHANNELS; i++) {

1923                 driver = &sii9034_channel_info[i].i2c_dev.driver; 

1924                 driver->driver.name = strings[i];

1925                 driver->id = I2C_DRIVERID_MISC;

1926 //              driver->flags = I2C_DF_NOTIFY;

1927                 if (0 == i) {

1928                         driver->attach_adapter = sii9034_i2c_probe_adapter;

1929                 }

1930         

1931                 driver->detach_client = sii9034_i2c_detach_client;

1932                 err |= vid_enc_register_encoder(&sii9034_dev[i]);

1933                 if (err < 0) {

1934                         for (j = i - 1; j > 0; j--) {

1935                                 vid_enc_unregister_encoder(&sii9034_dev[j]);

1936                         }

1937                         return err;

1938                 }

1939         }

1940         return err;

1941 }

9034设备的初始化sii9034_initialize,主要是用i2c_add_driver注册I2C 驱动,以及相关寄存器的设置。

 533 static struct vid_enc_mode_ops standards_ops = {

 534         .setmode = sii9034_setstd,

 535         .getmode = sii9034_getstd,

 536 }; 

sii9034_setstd 通过比较来获取输出的格式,然后根据该格式设置相关的寄存器,最后将得到的输出格式保存到sii9034_channel_info[ch_id].mode_info中。

sii9034_getstd sii9034_channel_info[ch_id].mode_info取出格式信息。

 521 static struct vid_enc_control_ops controls_ops = {

 522         .setcontrol = sii9034_setcontrol,

 523         .getcontrol = sii9034_getcontrol

 524 };

设置和获取一些相关的控制信息,比如亮度等

 515 /* Global structures variables */

 516 static struct vid_enc_param_ops params_ops = {

 517         .setparams = sii9034_set_params,

 518         .getparams = sii9034_get_params

 519 }; 

 params_ops 提供了用户空间和内核空间的接口,如下:

1778 /* This function is used to set parameters depending on the type */

1779 static int sii9034_set_params(void *p, struct vid_encoder_device *enc)

1780 {

1781         int err = 0;

1782         int ch_id;

1783         sii9034_params params;

1784 

1785         if (NULL == enc) {

1786                 printk(KERN_ERR "NULL Pointer.\n");

1787                 return -EINVAL;

1788         }

1789         return 0;

1790 

1791 

1792         ch_id = enc->channel_id;

1793         dev_dbg(sii9034_i2c_dev[ch_id], "<sii9034_set_params>\n");

1794         /* Check for null value */

1795         if (!(sii9034_params *) p) {

1796                 dev_err(sii9034_i2c_dev[ch_id],

1797                         "sii9034_set_hdparams:NULL pointer\n");

1798                 return -EINVAL;

1799         }

1800 

1801         if (copy_from_user(¶ms, (sii9034_params *) p, sizeof(params))) {

1802                 return -EFAULT;

1803         }

1804 

1805         if (SII9034_SDPARAMS == params.type) {

1806                 /* If parameter type is SD parameters, call

1807                  * sii9034_set_sdparams function to set SD parameters */

1808                 //err = sii9034_set_sdparams(&(params.params.sd), enc);

1809         } else if (SII9034_HDPARAMS == params.type) {

1810                 /* If parameter type is HD parameters, call

1811                  * sii9034_set_hdparams function to set HD parameters */

1812                 //err = sii9034_set_hdparams(&(params.params.hd), enc);

1813         } else {

1814                 dev_err(sii9034_i2c_dev[ch_id],

1815                         "sii9034_set_params:invalid type of parameter\n");

1816                 return -EINVAL;

1817         }

1818         sii9034_channel_info[ch_id].params = params;

1819         dev_dbg(sii9034_i2c_dev[ch_id], "</sii9034_set_params>\n");

1820         return err;

1821 }

1823 /* This function is used to get parameters depending on the type */

1824 static int sii9034_get_params(void *p, struct vid_encoder_device *enc)

1825 {

1826         int err = 0;

1827         int ch_id;

1828         sii9034_params *params = (sii9034_params *) p;

1829         if (NULL == enc) {

1830                 printk(KERN_ERR "NULL Pointer.\n");

1831                 return -EINVAL;

1832         }

1833 

1834         ch_id = enc->channel_id;

1835         dev_dbg(sii9034_i2c_dev[ch_id], "<sii9034_get_params>\n");

1836         /* Check for null value */

1837         if (!params) {

1838                 dev_err(sii9034_i2c_dev[ch_id],

1839                         "sii9034_get_params:NULL pointer\n");

1840                 return -EINVAL;

1841         }

1842 

1843         if (copy_to_user(params, &(sii9034_channel_info[ch_id].params),

1844                          sizeof(*params))) {

1845                 return -EFAULT;

1846         }

1847         dev_dbg(sii9034_i2c_dev[ch_id], "</sii9034_get_params>\n");

1848         return err;

1849 }

1850 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值