从另一个模块获取私有数据

来源:互联网 发布:最优化方法 张薇答案 编辑:程序博客网 时间:2024/06/05 18:47

kernel/drivers/media/video/v4l2-common.c

void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops)
{
v4l2_subdev_init(sd, ops);
sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
/* the owner is the same as the i2c_client's driver owner */
sd->owner = client->driver->driver.owner;
/* i2c_client and v4l2_subdev point to one another */
v4l2_set_subdevdata(sd, client);
i2c_set_clientdata(client, sd);
/* initialize name */
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
client->driver->driver.name, i2c_adapter_id(client->adapter),
client->addr);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);

static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
{
dev_set_drvdata(&dev->dev, data);
}

int dev_set_drvdata(struct device *dev, void *data)
{
int error;
if (!dev->p) {
error = device_private_init(dev);
if (error)
return error;
}
dev->p->driver_data = data;
return 0;
}
EXPORT_SYMBOL(dev_set_drvdata);

void *dev_get_drvdata(const struct device *dev)
{
if (dev && dev->p)
return dev->p->driver_data;
return NULL;
}
EXPORT_SYMBOL(dev_get_drvdata);


模块A:

static struct i2c_board_info i2c_devs_eisp[] = {
{
I2C_BOARD_INFO("ms2r", 0x1f),
.platform_data = &ms2r_plat,
.irq = MEIZU_ISP_IRQ,/*Should be configured as INT somewhere*/
},
};

static int __init m6x_init_camera(void)
{

       i2c_register_board_info(I2C_CAMERA_BUS_ID, i2c_devs_eisp, ARRAY_SIZE(i2c_devs_eisp));

return 0;
}

arch_initcall(m6x_init_camera);


static const struct v4l2_subdev_core_ops ms2r_core_ops = {
.init = ms2r_init,
.load_fw = ms2r_load_firmware,
.reset = ms2r_reset,
.s_power = ms2r_sensor_isp_s_power,
.g_ctrl = ms2r_g_ctrl,
.s_ctrl = ms2r_s_ctrl,
.g_ext_ctrls = ms2r_g_ext_ctrls,
};
static const struct v4l2_subdev_video_ops ms2r_video_ops = {
.enum_framesizes = ms2r_enum_framesizes,
.s_mbus_fmt = ms2r_s_fmt,
.s_stream = ms2r_s_stream,
.s_parm = ms2r_s_parm,
};
static const struct v4l2_subdev_ops ms2r_subdev_ops = {
.core = &ms2r_core_ops,
.video = &ms2r_video_ops,
};

static int ms2r_probe(struct i2c_client *client, const struct i2c_device_id *id)
{

struct v4l2_subdev *sd = NULL;

.........................

v4l2_i2c_subdev_init(sd, client, &ms2r_subdev_ops);

........................

}

static const struct i2c_device_id ms2r_id[] = {
{"ms2r", 0},
{},
};
static struct i2c_driver ms2r_i2c_driver = {
.driver = {
.name = "ms2r",
}, 
.probe = ms2r_probe,
.remove = ms2r_remove,
.id_table = ms2r_id,
};
static int __init ms2r_module_init(void)
{
return i2c_add_driver(&ms2r_i2c_driver);
}

module_init(ms2r_module_init);

在这个模块probe()完成后,struct v4l2_subdev 信息被保存到了 i2c_client->dev->p->driver_data 中,而 client->dev 被挂接到了 i2c_bus_type->p->klist_devices 链表中,所以可以通过 client->name 到链表中查询到 device 后,取得  struct v4l2_subdev 。

其他模块可以通过这个方法来取得  struct v4l2_subdev 。

模块B:

struct device *driver_find_device(struct device_driver *drv,
 struct device *start, void *data,
 int (*match)(struct device *dev, void *data))
{
struct klist_iter i;
struct device *dev;
if (!drv)
return NULL;
klist_iter_init_node(&drv->p->klist_devices, &i,         // i2c_driver/i2c_client 是挂接到 i2c_bus_type->p->klist_drivers/devices 上。
    (start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
klist_iter_exit(&i);
return dev;
}
EXPORT_SYMBOL_GPL(driver_find_device);

static int get_cam_subdev_callback(struct device *dev, void *data)
{
int ret;
struct i2c_client *client = list_entry(dev, struct i2c_client, dev);
if (!strncmp(client->name, (const char *)data, sizeof(client->name)))
ret = 1;
else
ret = 0;
return ret;
}

struct v4l2_subdev *get_cam_subdev(const char *module_name)
{
struct device_driver *drv;
struct device *dev = NULL;
struct v4l2_subdev *sd = NULL;
drv = driver_find(module_name, &i2c_bus_type);
if (!drv)  {
request_module(module_name);
drv = driver_find(module_name, &i2c_bus_type);
}
if (!drv)
return ERR_PTR(-ENODEV);
dev = driver_find_device(drv, NULL, (void *)module_name, 
get_cam_subdev_callback);
if (dev) 
sd = dev_get_drvdata(dev);
else 
sd = NULL;
put_device(dev);
return sd;
}

static int CAMERA_HW_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{

  struct v4l2_subdev *sd = NULL;

   sd = get_cam_subdev("ms2r");

   return 0

}


0 0
原创粉丝点击