g_sensor好像很简单,就是注册i2c设备,然后通过一个任务队列,每隔delay时间向上报x,y,z数据.
在drivers/input/sensors/accel/bma2x2.c中
module_init(BMA2X2_init);
-
static int __init BMA2X2_init(void)
-
{
-
//注册了一个i2c设备驱动
-
return i2c_add_driver(&bma2x2_driver);
-
}
在probe函数中
-
static int bma2x2_probe(struct i2c_client *client, const struct i2c_device_id *id)
-
{
-
int err = 0;
-
int tempvalue;
-
unsigned char tmp_chip_id;
-
struct input_dev *dev;
-
-
struct bma2x2_data *data = kzalloc(sizeof(struct bma2x2_data), GFP_KERNEL);
-
//获取设备的具体型号
-
tempvalue = i2c_smbus_read_word_data(client, BMA2X2_CHIP_ID_REG);
-
tmp_chip_id = tempvalue&0x00ff;
-
switch (tmp_chip_id) {
-
case BMA255_CHIP_ID:
-
data->sensor_type = BMA255_TYPE;
-
break;
-
case BMA250E_CHIP_ID:
-
data->sensor_type = BMA250E_TYPE;
-
break;
-
case BMA222E_CHIP_ID:
-
data->sensor_type = BMA222E_TYPE;
-
break;
-
case BMA280_CHIP_ID:
-
data->sensor_type = BMA280_TYPE;
-
break;
-
default:
-
data->sensor_type = -1;
-
}
-
-
if (data->sensor_type != -1) {
-
data->chip_id = tmp_chip_id;
-
} else{
-
err = -ENODEV;
-
goto kfree_exit;
-
}
-
i2c_set_clientdata(client, data);
-
data->bma2x2_client = client;
-
mutex_init(&data->value_mutex);
-
mutex_init(&data->mode_mutex);
-
mutex_init(&data->enable_mutex);
-
bma2x2_set_bandwidth(client, BMA2X2_BW_SET);
-
bma2x2_set_range(client, BMA2X2_RANGE_SET);
-
bma2x2_set_Int_Enable(client, 8, 1);
-
bma2x2_set_Int_Enable(client, 10, 1);
-
bma2x2_set_Int_Enable(client, 11, 1);
-
-
INIT_DELAYED_WORK(&data->work, bma2x2_work_func);
-
atomic_set(&data->delay, BMA2X2_MAX_DELAY); //将delay设为8ms
-
atomic_set(&data->enable, 0);
-
-
dev = input_allocate_device();
-
dev->name = SENSOR_NAME;
-
dev->id.bustype = BUS_I2C;
-
-
input_set_capability(dev, EV_REL, LOW_G_INTERRUPT);
-
input_set_capability(dev, EV_REL, HIGH_G_INTERRUPT);
-
input_set_capability(dev, EV_REL, SLOP_INTERRUPT);
-
input_set_capability(dev, EV_REL, DOUBLE_TAP_INTERRUPT);
-
input_set_capability(dev, EV_REL, SINGLE_TAP_INTERRUPT);
-
input_set_capability(dev, EV_ABS, ORIENT_INTERRUPT);
-
input_set_capability(dev, EV_ABS, FLAT_INTERRUPT);
-
input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0);
-
input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0);
-
input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0);
-
-
input_set_drvdata(dev, data);
-
-
input_register_device(dev);
-
-
data->input = dev;
-
-
schedule_work(&data->work);
-
-
return 0;
-
}
-
static int bma2x2_read_accel_xyz(struct i2c_client *client, signed char sensor_type, struct bma2x2acc *acc)
-
{
-
int comres = 0;
-
unsigned char data[6];
-
comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_X12_LSB__REG, data, 6);
-
acc->x = (data[1]<<8)|data[0];
-
acc->y = (data[3]<<8)|data[2];
-
acc->z = (data[5]<<8)|data[4];
-
-
return comres;
-
}
-
-
static void bma2x2_work_func(struct work_struct *work)
-
{
-
struct bma2x2_data *bma2x2 = container_of((struct delayed_work *)work, struct bma2x2_data, work);
-
static struct bma2x2acc acc;
-
unsigned long delay = msecs_to_jiffies(atomic_read(&bma2x2->delay));
-
bma2x2_read_accel_xyz(bma2x2->bma2x2_client, bma2x2->sensor_type, &acc);
-
input_report_abs(bma2x2->input, ABS_X, -acc.y);
-
input_report_abs(bma2x2->input, ABS_Y, acc.x);
-
input_report_abs(bma2x2->input, ABS_Z, acc.z);
-
input_sync(bma2x2->input);
-
schedule_delayed_work(&bma2x2->work, delay); //每隔8ms上报一次
-
}
阅读(3778) | 评论(0) | 转发(0) |