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

传感器芯片mpu6500 linux驱动

时间:2024-11-16 11:46:25浏览次数:3  
标签:struct ops 芯片 gyro client linux mpu6500 sensor

/* drivers/input/sensors/access/mpu6880_gyro.c
*

  • Copyright © 2012-2015 ROCKCHIP.
  • 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 <asm/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>
#include <linux/mpu6500.h>

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;
int status = 0;
u8 pwrm1 = 0;

sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
pwrm1 = sensor_read_reg(client, MPU6500_PWR_MGMT_1);

if (!enable) {
	status = BIT_GYRO_STBY;
	sensor->ops->ctrl_data |= status;
	if ((sensor->ops->ctrl_data & BIT_ACCEL_STBY) == BIT_ACCEL_STBY) {
		pwrm1 |= MPU6500_PWRM1_SLEEP;
	}
} else {
	status = ~BIT_GYRO_STBY;
	sensor->ops->ctrl_data &= status;
	pwrm1 &= ~MPU6500_PWRM1_SLEEP;
}

result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
if (result) {
	dev_err(&client->dev, "%s:fail to active sensor\n", __func__);
	return -1;
}
msleep(20);

result = sensor_write_reg(client, MPU6500_PWR_MGMT_1, pwrm1);
if (result) {
	dev_err(&client->dev, "%s:fail to set pwrm1\n", __func__);
	return -1;
}
msleep(50);

return result;

}

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

/* init on mpu6500_acc.c */
ret = sensor->ops->active(client, 0, sensor->pdata->poll_delay_ms);
if (ret) {
	dev_err(&client->dev, "%s:line=%d,error\n", __func__, __LINE__);
	return ret;
}

return ret;

}

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) {
	/* Report gyro sensor information */
	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;
int ret = 0;
short x, y, z;
struct sensor_axis axis;
u8 buffer[6] = {0};
char value = 0;

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

memset(buffer, 0, 6);

do {
	*buffer = sensor->ops->read_reg;
	ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
	if (ret < 0)
		return ret;
} while (0);

x = ((buffer[0] << 8) & 0xFF00) + (buffer[1] & 0xFF);
y = ((buffer[2] << 8) & 0xFF00) + (buffer[3] & 0xFF);
z = ((buffer[4] << 8) & 0xFF00) + (buffer[5] & 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) && (sensor->ops->int_status_reg >= 0))
	value = sensor_read_reg(client, sensor->ops->int_status_reg);

return ret;

}

struct sensor_operate gyro_mpu6500_ops = {
.name = “mpu6500_gyro”,
.type = SENSOR_TYPE_GYROSCOPE,
.id_i2c = GYRO_ID_MPU6500,
.read_reg = MPU6500_GYRO_XOUT_H,
.read_len = 6,
.id_reg = SENSOR_UNKNOW_DATA,
.id_data = SENSOR_UNKNOW_DATA,
.precision = MPU6500_PRECISION,
.ctrl_reg = MPU6500_PWR_MGMT_2,
.int_status_reg = MPU6500_INT_STATUS,
.range = {-32768, 32768},
.trig = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
.active = sensor_active,
.init = sensor_init,
.report = sensor_report_value,
};

/****operate according to sensor chip:end/
static int gyro_mpu6500_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
return sensor_register_device(client, NULL, devid, &gyro_mpu6500_ops);
}

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

static const struct i2c_device_id gyro_mpu6500_id[] = {
{“mpu6500_gyro”, GYRO_ID_MPU6500},
{}
};

static struct i2c_driver gyro_mpu6500_driver = {
.probe = gyro_mpu6500_probe,
.remove = gyro_mpu6500_remove,
.shutdown = sensor_shutdown,
.id_table = gyro_mpu6500_id,
.driver = {
.name = “gyro_mpu6500”,
#ifdef CONFIG_PM
.pm = &sensor_pm_ops,
#endif
},
};

static int __init gyro_mpu6500_init(void)
{
return i2c_add_driver(&gyro_mpu6500_driver);
}

static void __exit gyro_mpu6500_exit(void)
{
i2c_del_driver(&gyro_mpu6500_driver);
}

/* must register after mpu6500_acc */
device_initcall_sync(gyro_mpu6500_init);
module_exit(gyro_mpu6500_exit);

MODULE_AUTHOR(“xxx”);
MODULE_DESCRIPTION(“mpu6500_gyro 3-Axis Gyroscope driver”);
MODULE_LICENSE(“GPL”);

标签:struct,ops,芯片,gyro,client,linux,mpu6500,sensor
From: https://blog.csdn.net/baidu_37552881/article/details/143785897

相关文章

  • 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程序,进行系统初始化根据系统运行级别执行......
  • Linux常用命令之find命令详解
    find命令详解find是Unix和类Unix操作系统(如Linux和macOS)中一个非常强大的命令行工具,用于在文件系统中搜索文件和目录。find命令可以根据多种条件(如文件名、类型、大小、修改时间等)进行搜索,并可以执行复杂的操作。基本语法find命令的基本语法如下:find[路径]......