Linux下v4l2-camera子系统之soc_camera_device(二)

Linux下v4l2-camera子系统之soc_camera_device(二)
平台:君正x1000
linux kernel: 3.10
camera sensor:ov7725
上节认识了camera子系统的大概框架结构及主要相关结构,现在看看系统中是怎么注册camera_device。

struct i2c_board_info jz_v4l2_camera_devs[] __initdata = {
	 {
        I2C_BOARD_INFO("ov7725", 0x21),
	},
};
static struct soc_camera_link iclink_front = {
    .bus_id     = 0,     
    .board_info = &jz_v4l2_camera_devs[FRONT_CAMERA_INDEX],
    .i2c_adapter_id = 0,
    .power = camera_sensor_power,
    .reset = camera_sensor_reset,
};

struct platform_device mensa_front_camera_sensor = {
    .name = "soc-camera-pdrv",
    .id   = -1,
    .dev  = {
        .platform_data = &iclink_front,
    },
};
platform_device_register(&mensa_front_camera_sensor);

soc_camera_device也是做为平台设备注册进内核,其下.dev.platform_data 指向soc_camera_link,而soc_camera_link管理sensor。
plarform驱动设备驱动模型就不说了,下面看驱动怎么做的。

camera_device驱动

/*   \drivers\media\platform\soc_camera\soc_camera.c  */
static struct platform_driver __refdata soc_camera_pdrv = {
	.probe = soc_camera_pdrv_probe,
	.remove  = soc_camera_pdrv_remove,
	.driver  = {
		.name	= "soc-camera-pdrv",
		.owner	= THIS_MODULE,
	},
};
module_platform_driver(soc_camera_pdrv);
/*   \drivers\media\platform\soc_camera\soc_camera.c  */
static int soc_camera_pdrv_probe(struct platform_device *pdev)
{	 
	struct soc_camera_desc *sdesc = pdev->dev.platform_data;1struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
	struct soc_camera_device *icd;
	int ret;
	
	icd = devm_kzalloc(&pdev->dev, sizeof(*icd), GFP_KERNEL);2)
	icd->iface = sdesc->host_desc.bus_id; /* struct soc_camera_link成员bus_id */
	icd->sdesc = sdesc;
	icd->pdev = &pdev->dev;
	platform_set_drvdata(pdev, icd);
	icd->user_width		= DEFAULT_WIDTH;
	icd->user_height	= DEFAULT_HEIGHT;
	return soc_camera_device_register(icd);
/* 将代表着camera sensor的对象soc_camera_device放到了全局链表devices中 */
}

上述代码(1)的soc_camera_desc就是上节说的和soc_camera_link 字节对齐的结构,pdev->dev.platform_data 就是平台设备中soc_camera_link 。(2)就是申请soc_camera_device内存,下面就是对它的初始化,最后注册。

static int soc_camera_device_register(struct soc_camera_device *icd)
{
	struct soc_camera_device *ix;
	int num = -1, i;

	for (i = 0; i < 256 && num < 0; i++) {
		num = i;
		/* Check if this index is available on this interface */
		list_for_each_entry(ix, &devices, list) {
			if (ix->iface == icd->iface && ix->devnum == i) {
				num = -1;
				break;
			}
		}
	}
	if (num < 0)
		return -ENOMEM;

	icd->devnum		= num;
	icd->use_count		= 0;
	icd->host_priv		= NULL;

	list_add_tail(&icd->list, &devices);

	return 0;
}

该函数核心是for循环查找icd->iface的主机是否已添加到全局链表&devices,如果没有,则找出空闲的设备号devnum,并添加到全局链表。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值