内核版本 3.9.11 编译器版本4.51
由于内核中已经有比较完善的HDMI驱动了,所以稍微修改配置一下就能使用HDMI驱动。
S5PV210的HDMI驱动文件在\drivers\media\platform\s5p-tv文件夹中
其中 hdmi_drv.c 是作为HDMI平台设备驱动。(主要驱动)
hdmiphy_drv.c是通过上面的驱动匹配成功后会自动匹配此设备驱动,该设备驱动实质就是一个i2c驱动,用于硬件之间指令数据的发送(貌似这个I2C只有发送功能)。
还有一个就是mixer文件,它是一个混合器,负责合成图像和声音,之前的驱动最后都会交由该驱动管理。会在/dev目录下生成几个video的设备。
基本分析完了,接下来开始修改内核文件。
首先在arch\arm\mach-s5pv210\mach-smdkv210.c中添加如下i2c子设备信息
/*HDMI*/
static struct i2c_board_info hdmiphy_info = {
I2C_BOARD_INFO("hdmiphy-s5pv210", (0x70>>1)),
};
其中 0x70是芯片手册中给的HDMI设备的I2c地址。(右移1位是因为读写位的关系,i2c发送时地址会自动左移一位在最低位添加0(写)或者1(读))”hdmiphy-s5pv210”对应着 hdmiphy_drv.c中的id。对于成功匹配至关重要。
在平台设备数组中,注释掉默认的i2c1设备,并添加HDMI相关的设备。
这些设备定义都在arch\arm\plat-samsung\devs.c文件中。
由于 HDMI使用i2c1作为指令发送器,并且是HDMI专用的i2c,所以不能当做普通的i2c控制器驱动,否则驱动能正确加载,但是会提示0x70地址没ack信号。(i2c_hdmi设备在devs.c中有定义,和普通i2c1设备对比后,明显有区别)
继续在smdkv210_machine_init中添加2个函数,设置I2C从设备信息,在HDMI设备匹配成功后会自动进行注册。
对上述两个函数进行修改,修改默认的bus_num,因为HDMI接口使用I2c1控制的,所以将bus_num改为1.(上面两个函数都要改),不然会注册失败。因为跟踪hdmi_drv.c的prob函数不难发现,他会通过此bus_num获取一个adapt,在i2c子系统中1个adapt相当于一个i2c控制器驱动,bus_num则是区分这些I2C控制器的。然后在将i2c从设备信息添加到对应的i2c控制器下。修改后如下图:
还要注意CONFIG_S5P_DEV_I2C_HDMIPHY这个宏,它在3.9.11中属于隐藏选项,没有配置选项,只能通过手动修改Kconfig文件实现。若不修改则无法使用上述2个函数。
在arch\arm\mach-s5pv210\Kconfig的SMDK210中添加
内核配置则通过查Kconfig和menuconfig 的 / 号的查找功能来配置。
大致配置如下:
Device Drivers -->
Multimedia support -->
V4L platform device -->
samsung TV driver -->
HDMI Driver
在device driver选中I2c support,其中要注意 I2c Hardware Bus support选项,里面要选择 S3c2410 I2c driver 否则I2c控制器设备不会被加载。
Power management options 中的 Run-time PM core 必选
成功后会输出如下
这样编译完成后第一次运行可以,第二次运行就会死机,这是因为HDMI时钟关了,第二次运行会重新打开导致系统时钟出问题,解决办法:
一、修改mixer_drv.c中的mxr_runtime_suspend函数中注释掉clk_disable(res->sclk_mixer);。
二、修改hdmi_drv.c中的hdmi_resource_poweroff函数,注释掉clk_disable(res->sclk_hdmi)。
这样就不会死机了!!!!!!!!!!!!!!!!!!
附上效果图: