何时通过 I2C 使用 platform_driver?
我正在寻找一个代码 xxx 设备,它是一个使用 I2C 进行通信的 IC。不知何故,它是使用平台设备编写的。为了与IC通信,它使用“microp_i2c_write()”(请参考以下函数write_xxx_register())。我认为这段代码很难在不同的平台上维护。这是一个导航产品。
问题: 1.我相信我的问题是如何包含 struct i2c_client *client?进入这种情况?那么这样可以更容易地移植到不同的linux/andriod内核吗? 2. 为什么&何时首选 platform_driver?有什么特别的原因吗?
static struct platform_driver xxx_device_driver = {
.probe = xxx_probe,
.remove = __devexit_p(xxx_remove),
.driver = {
.name = XXX_NAME,
.owner = THIS_MODULE,
}
};
static void write_xxx_register(uint8_t reg, uint8_t val)
{
uint8_t data[BURST_DATA_SIZE];
data[0] = reg;
data[1] = val;
microp_i2c_write(OJ_REGISTER_WRITE, data, 2);
}
static int __devinit XXX_probe(struct platform_device *pdev)
{
struct XXX_platform_data *oj = pdev->dev.platform_data;
int err;
int i;
err = -ENOMEM;
my_oj = oj;
INIT_WORK(&oj->work, XXX_work_func);
XXX__wq = create_singlethread_workqueue("XXX__wq");
if (!XXX__wq) {
err = -ENOMEM;
goto fail;
}
oj->input_dev = input_allocate_device();
if (!oj->input_dev) {
printk(KERN_ERR "Unable to allocate device for OJ\n");
err = -ENOMEM;
goto fail;
}
oj->input_dev->name = "XXX_-oj";
oj->input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS)| BIT_MASK(EV_SYN )|BIT_MASK(EV_REL) ;
input_set_capability(oj->input_dev, EV_KEY, BTN_MOUSE);
input_set_capability(oj->input_dev, EV_KEY, BTN_TOUCH);
oj->input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
oj->input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
input_set_abs_params(oj->input_dev, ABS_X, 8, 4024-8 , 0, 0);
input_set_abs_params(oj->input_dev, ABS_Y, 41, 6604-41, 0, 0);
input_set_abs_params(oj->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
input_set_abs_params(oj->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
input_set_abs_params(oj->input_dev, ABS_HAT0X, 8, 4024-8, 0, 0);
input_set_abs_params(oj->input_dev, ABS_HAT0Y, 41, 6604-41, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_POSITION_X, 8, 4024-8, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_POSITION_Y, 41, 6604-41, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
set_bit(EV_SYN, oj->input_dev->evbit);
set_bit(EV_KEY, oj->input_dev->evbit);
set_bit(BTN_TOUCH, oj->input_dev->keybit);
set_bit(EV_ABS, oj->input_dev->evbit);
for(i = 0; i < ARRAY_SIZE(keymap); i++)
set_bit(keymap[i], oj->input_dev->keybit);
err = input_register_device(oj->input_dev);
if (err) {
printk(KERN_ERR "Unable to register %s input device\n", oj->input_dev->name);
goto fail;
}
err = request_irq(my_oj->irq, XXX_irq_handler,
IRQF_TRIGGER_NONE, XXX_NAME, oj);
if (err < 0) {
err = -ENOMEM;
printk(KERN_ERR "request_irq failed\n");
goto fail;
}
normal_th = my_oj->normal_th;
xy_ratio = my_oj->xy_ratio;
interval = my_oj->interval;
polling_delay = my_oj->mdelay_time;
debugflag = my_oj->debugflag;
ap_code = my_oj->ap_code;
printk(KERN_INFO "driver loaded\n");
return 0;
}
I am looking a code xxx device is an IC using I2C to communicate. Somehow it is written using platform device. To communicate with the IC it is using "microp_i2c_write()"(pls refer to the following function write_xxx_register()). I think this code is hard to maintain in different platform. this is a navigation product.
Question:
1. I believe my question is how can I include the struct i2c_client *client? into this scenario? So this way it is easier to port to different linux/ andriod kernel?
2. Why & when platform_driver preferred? any particular reason?
static struct platform_driver xxx_device_driver = {
.probe = xxx_probe,
.remove = __devexit_p(xxx_remove),
.driver = {
.name = XXX_NAME,
.owner = THIS_MODULE,
}
};
static void write_xxx_register(uint8_t reg, uint8_t val)
{
uint8_t data[BURST_DATA_SIZE];
data[0] = reg;
data[1] = val;
microp_i2c_write(OJ_REGISTER_WRITE, data, 2);
}
static int __devinit XXX_probe(struct platform_device *pdev)
{
struct XXX_platform_data *oj = pdev->dev.platform_data;
int err;
int i;
err = -ENOMEM;
my_oj = oj;
INIT_WORK(&oj->work, XXX_work_func);
XXX__wq = create_singlethread_workqueue("XXX__wq");
if (!XXX__wq) {
err = -ENOMEM;
goto fail;
}
oj->input_dev = input_allocate_device();
if (!oj->input_dev) {
printk(KERN_ERR "Unable to allocate device for OJ\n");
err = -ENOMEM;
goto fail;
}
oj->input_dev->name = "XXX_-oj";
oj->input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS)| BIT_MASK(EV_SYN )|BIT_MASK(EV_REL) ;
input_set_capability(oj->input_dev, EV_KEY, BTN_MOUSE);
input_set_capability(oj->input_dev, EV_KEY, BTN_TOUCH);
oj->input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
oj->input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
input_set_abs_params(oj->input_dev, ABS_X, 8, 4024-8 , 0, 0);
input_set_abs_params(oj->input_dev, ABS_Y, 41, 6604-41, 0, 0);
input_set_abs_params(oj->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
input_set_abs_params(oj->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
input_set_abs_params(oj->input_dev, ABS_HAT0X, 8, 4024-8, 0, 0);
input_set_abs_params(oj->input_dev, ABS_HAT0Y, 41, 6604-41, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_POSITION_X, 8, 4024-8, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_POSITION_Y, 41, 6604-41, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(oj->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
set_bit(EV_SYN, oj->input_dev->evbit);
set_bit(EV_KEY, oj->input_dev->evbit);
set_bit(BTN_TOUCH, oj->input_dev->keybit);
set_bit(EV_ABS, oj->input_dev->evbit);
for(i = 0; i < ARRAY_SIZE(keymap); i++)
set_bit(keymap[i], oj->input_dev->keybit);
err = input_register_device(oj->input_dev);
if (err) {
printk(KERN_ERR "Unable to register %s input device\n", oj->input_dev->name);
goto fail;
}
err = request_irq(my_oj->irq, XXX_irq_handler,
IRQF_TRIGGER_NONE, XXX_NAME, oj);
if (err < 0) {
err = -ENOMEM;
printk(KERN_ERR "request_irq failed\n");
goto fail;
}
normal_th = my_oj->normal_th;
xy_ratio = my_oj->xy_ratio;
interval = my_oj->interval;
polling_delay = my_oj->mdelay_time;
debugflag = my_oj->debugflag;
ap_code = my_oj->ap_code;
printk(KERN_INFO "driver loaded\n");
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的设备连接到 I2C 总线,那么您应该注册 i2c_driver 结构而不是 platform_driver 结构。例如,在 drivers/input/touchscreen/ 中查找 i2C_driver 的 grep 。
If your device is connected to the I2C bus, then you should register a i2c_driver structure and not a platform_driver structure. grep for i2C_driver in drivers/input/touchscreen/ for example.