首页 > 系统相关 >传感器芯片lsm330 linux驱动

传感器芯片lsm330 linux驱动

时间:2024-11-16 11:46:51浏览次数:3  
标签:lsm330 struct 芯片 client result linux sensor reg define

/*

  • kernel/drivers/input/sensors/accel/lsm330_gyro.c
  • Copyright © 2012-2016 Rockchip Co.,Ltd.
  • This software is licensed under the terms of the GNU General Public
  • License version 2, as published by the Free Software Foundation, and
  • may be copied, distributed, and modified under those terms.
  • This program is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • GNU General Public License for more details.

*/

#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <linux/uaccess.h>
#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/sensor-dev.h>

/* Angular rate sensor register */
#define WHO_AM_I_G 0x0F
#define CTRL_REG1_G 0x20
#define CTRL_REG2_G 0x21
#define CTRL_REG3_G 0x22
#define CTRL_REG4_G 0x23
#define CTRL_REG5_G 0x24
#define REFERENCE_G 0x25
#define OUT_TEMP_G 0x26
#define STATUS_REG_G 0x27
#define OUT_X_L_G 0x28
#define OUT_X_H_G 0x29
#define OUT_Y_L_G 0x2A
#define OUT_Y_H_G 0x2B
#define OUT_Z_L_G 0x2C
#define OUT_Z_H_G 0x2D
#define FIFO_CTRL_REG_G 0x2E
#define FIFO_SRC_REG_G 0x2F
#define INT1_CFG_G 0x30
#define INT1_SRC_G 0x31
#define INT1_TSH_XH_G 0x32
#define INT1_TSH_XL_G 0x33
#define INT1_TSH_YH_G 0x34
#define INT1_TSH_YL_G 0x35
#define INT1_TSH_ZH_G 0x36
#define INT1_TSH_ZL_G 0x37
#define INT1_DURATION_G 0x38

#define LSM330_DEVICE_ID_G 0xD4

static int sensor_active(struct i2c_client *client, int enable, int rate)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
int result = 0;

sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
if (enable)
	result = sensor_write_reg(client,
	sensor->ops->ctrl_reg,
	sensor->ops->ctrl_data | 0x0F);
else
	result = sensor_write_reg(client,
	sensor->ops->ctrl_reg,
	0x00);

if (result)
	dev_err(&client->dev, "%s:fail to active sensor\n", __func__);

DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",
	__func__,
	sensor->ops->ctrl_reg,
	sensor->ops->ctrl_data, enable);

return result;

}

static int sensor_init(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
int result = 0;

result = sensor->ops->active(client, 0, 0);
if (result) {
	dev_err(&client->dev,
		"%s:line=%d,error\n",
		__func__,
		__LINE__);
	return result;
}
sensor->status_cur = SENSOR_OFF;

/*ODR: 760Hz, Cut-off: 100Hz*/
result = sensor_write_reg(client, CTRL_REG1_G, 0xF0);
if (result) {
	dev_err(&client->dev,
		"%s:fail to set CTRL_REG1_A.\n",
		__func__);
	return result;
}
result = sensor_write_reg(client, CTRL_REG3_G, 0x80);
if (result) {
	dev_err(&client->dev,
		"%s:fail to set CTRL_REG3_G.\n",
		__func__);
	return result;
}
/*Full-scale selection: 2000dps*/
result = sensor_write_reg(client, CTRL_REG4_G, 0x30);
if (result) {
	dev_err(&client->dev,
		"%s:fail to set CTRL_REG4_G.\n",
		__func__);
	return result;
}
result = sensor_write_reg(client, INT1_CFG_G, 0x7F);
if (result) {
	dev_err(&client->dev, "%s:fail to set INT1_CFG_G.\n", __func__);
	return result;
}

return result;

}

static int gyro_report_value(struct i2c_client *client,
struct sensor_axis *axis)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);

if (sensor->status_cur == SENSOR_ON) {
	input_report_rel(sensor->input_dev, ABS_RX, axis->x);
	input_report_rel(sensor->input_dev, ABS_RY, axis->y);
	input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
	input_sync(sensor->input_dev);
}

return 0;

}

static int sensor_report_value(struct i2c_client *client)
{
struct sensor_private_data *sensor =
(struct sensor_private_data *)i2c_get_clientdata(client);
struct sensor_platform_data *pdata = sensor->pdata;
char buffer[6];
int ret = 0;
char value = 0;
struct sensor_axis axis;
short x, y, z;
unsigned char reg_buf = 0;
unsigned char i = 0;

if (sensor->ops->read_len < 6) {
	dev_err(&client->dev, "%s:Read len is error,len=%d\n",
		__func__,
		sensor->ops->read_len);
	return -1;
}
memset(buffer, 0, 6);

reg_buf = sensor->ops->read_reg;
for (i = 0; i < sensor->ops->read_len; i++) {
	buffer[i] = sensor_read_reg(client, reg_buf);
	reg_buf++;
}

x = ((buffer[1] << 8) & 0xFF00) + (buffer[0] & 0xFF);
y = ((buffer[3] << 8) & 0xFF00) + (buffer[2] & 0xFF);
z = ((buffer[5] << 8) & 0xFF00) + (buffer[4] & 0xFF);

axis.x = (pdata->orientation[0]) * x +
	(pdata->orientation[1]) * y +
	(pdata->orientation[2]) * z;
axis.y = (pdata->orientation[3]) * x +
	(pdata->orientation[4]) * y +
	(pdata->orientation[5]) * z;
axis.z = (pdata->orientation[6]) * x +
	(pdata->orientation[7]) * y +
	(pdata->orientation[8]) * z;

gyro_report_value(client, &axis);
mutex_lock(&sensor->data_mutex);
sensor->axis = axis;
mutex_unlock(&sensor->data_mutex);

if (sensor->pdata->irq_enable) {
	value = sensor_read_reg(client, sensor->ops->int_status_reg);
	DBG("%s:gyro int status :0x%x\n", __func__, value);
}

return ret;

}

struct sensor_operate gyro_lsm330_ops = {
.name = “lsm330_gyro”,
.type = SENSOR_TYPE_GYROSCOPE,
.id_i2c = GYRO_ID_LSM330,
.read_reg = OUT_X_L_G,
.read_len = 6,
.id_reg = WHO_AM_I_G,
.id_data = LSM330_DEVICE_ID_G,
.precision = 16,
.ctrl_reg = CTRL_REG1_G,
.int_status_reg = INT1_SRC_G,
.range = {-32768, 32768},
.trig = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
.active = sensor_active,
.init = sensor_init,
.report = sensor_report_value,
};

static int gyro_lsm330_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
return sensor_register_device(client, NULL, devid, &gyro_lsm330_ops);
}

static int gyro_lsm330_remove(struct i2c_client *client)
{
return sensor_unregister_device(client, NULL, &gyro_lsm330_ops);
}

static const struct i2c_device_id gyro_lsm330_id[] = {
{“lsm330_gyro”, GYRO_ID_LSM330},
{}
};

static struct i2c_driver gyro_lsm330_driver = {
.probe = gyro_lsm330_probe,
.remove = gyro_lsm330_remove,
.shutdown = sensor_shutdown,
.id_table = gyro_lsm330_id,
.driver = {
.name = “gyro_lsm330”,
#ifdef CONFIG_PM
.pm = &sensor_pm_ops,
#endif
},
};

module_i2c_driver(gyro_lsm330_driver);

MODULE_AUTHOR(“xxxx”);
MODULE_DESCRIPTION(“lsm330 3-Axis Gyroscope driver”);
MODULE_LICENSE(“GPL”);

标签:lsm330,struct,芯片,client,result,linux,sensor,reg,define
From: https://blog.csdn.net/baidu_37552881/article/details/143785869

相关文章

  • 传感器芯片mpu6500 linux驱动
    /*drivers/input/sensors/access/mpu6880_gyro.c*Copyright©2012-2015ROCKCHIP.ThissoftwareislicensedunderthetermsoftheGNUGeneralPublicLicenseversion2,aspublishedbytheFreeSoftwareFoundation,andmaybecopied,distributed,andmodif......
  • Metasploit Pro 4.22.5-2024111401 (Linux, Windows) - 专业渗透测试框架
    MetasploitPro4.22.5-2024111401(Linux,Windows)-专业渗透测试框架Rapid7Penetrationtesting,releasedNov14,2024请访问原文链接:https://sysin.org/blog/metasploit-pro-4/查看最新版。原创作品,转载请保留出处。作者主页:sysin.org世界上最广泛使用的渗透测试框......
  • 【Linux探索学习】第十三弹——进程状态:深入理解操作系统进程状态与Linux操作系统中的
    Linux笔记:https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482前言:在上篇我们已经讲解了进程的基本内容,也了解了进程在操作系统的重要作用,今天我们正式开始进程的另一个知识点的讲解:进程状态,即一个进程不可能一直处在运行或终止状态中,它......
  • Linux系统-redis集群、nacos、nginx、keepalived、mysql开机自启
    一、Redis集群开机自启:如三主三从交叉式redis集群,有两个方法,自行选择。方法一:第一步:分别在各节点添加以下redis.service文件命令:vim/lib/systemd/system/redis_6379.service添加:[Unit]Description=Redispersistentkey-valuedatabaseAfter=network.targetAfter=......
  • 【Linux】系统编程的初探与遐想
    Linux==LinuxisnotUnix.前言 这是我的第一篇关于Linux系统编程的笔记,后面我将会把后续的笔记开源分享到博客。Linux系统介绍系统的特点 1.开源的,即源代码是公开的,大部分是免费的。2.命令行+图形界面的交互形式。 3.多用户操作系统。开源与闭源 1.......
  • 【深入浅出】之Linux多进程实现shell外壳程序(简易版)
    ......
  • 初识Linux · 信号保存
    目录前言:Blockpendinghandler表信号保存前言:前文我们已经介绍了信号产生,在时间的学习线上,信号的学习分为预备知识,信号产生,信号保存,信号处理,本文我们学习信号保存,在前言部分,我们介绍几个信号保存中的概念。信号递达:实际执行信号的处理动作。信号未决:信号从产生到递达......
  • linux下编译安装memcached
    Memcached在Linux下的编译安装一、安装依赖库Memcached依赖于一些系统库,在大多数Linux发行版中,需要安装libevent库。Debian/Ubuntu系统使用以下命令安装依赖库:sudoapt-yupdatesudoapt-yinstalllibevent-devCentOS/RHEL系统可以通过以下命令安装:sudoyum......
  • Linux cp和mv命令 对于目录复制到目录的情况 的 所有情况示例
    cp和mv命令的行为总结表假设以下路径设置:源路径:/nihao或/nihao//nihao包含文件和子目录:file1,dir1/,file2目标路径:/nima或/nima/表格cp命令行为命令目标路径存在?最终路径结构cp-r/nihao/nima/是/nima/nihao/cp-r/nihao//nima/是/ni......
  • linux运维面试题【基础篇】
    前言本篇主要分享linux运维面试过程中常见的面试题材,当时自己面试的时候就遇到3道原题,最终也是顺利通过面试,下面给大家分享一下:面试题库1、描述Linux系统的启动过程电源BIOS自检读取MBR,运行grub加载内核内核启动/sbin/init程序,进行系统初始化根据系统运行级别执行......