RK3568平台 驱动实现IIC设备读取十六位寄存器状态

一.项目需求

要求读取GVS2715这个IIC设置寄存器的值来获取版本号,GVS2715这个芯片是十六位寄存器。

当使用i2ctool工具读取十六位寄存器的时候,发现无法读取出来,读取的都是XXXX。

二.从零开始写IIC设备驱动读取十六位寄存器的状态

#include <linux/miscdevice.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <linux/printk.h>
#include <linux/kobject.h>
#include <linux/version.h>#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
#define DRIVER_NAME "gsv2715"/*define logging*/
#define gsv2715_DEBUG	1
#if gsv2715_DEBUG
#define DBG(format, args...)					\printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ##args)
#define ERR(format, args...)					\printk(KERN_ERR "%s: " format, DRIVER_NAME, ##args)
#define WARNING(format, args...)				\printk(KERN_WARN "%s: " format, DRIVER_NAME, ##args)
#define INFO(format, args...)					\printk(KERN_INFO "%s: " format, DRIVER_NAME, ##args)
#else
#define DBG(format, args...)
#define ERR(format, args...)
#define WARNING(format, args...)
#define INFO(format, args...)
#endifstruct gsv2715_dev {struct device *dev;struct miscdevice miscdev;struct i2c_client *client;struct mutex confctl_mutex;u32 hdmi_rx_sel;
};struct gsv2715_dev *g_gsv2715;
//struct gsv2715_dev *gsv2715;
static int  i2c_write(struct gsv2715_dev *gsv2715, u16 reg, u8 *val, u32 n)
{struct i2c_msg msg;struct i2c_client *client = gsv2715->client;int err;u8 data[128];data[0] = (reg >> 8) & 0xFF;data[1] = reg & 0xFF;data[2] = *val;msg.addr = client->addr;msg.flags = !I2C_M_RD;msg.buf = &data[0];msg.len = 3;INFO("I2C ready write 0x%04x = (data[0])0x%02x (data[1])0x%02x  (data[2])0x%02x\n", reg , data[0], data[1], data[2]);err = i2c_transfer(client->adapter, &msg, 1);if (err != 1) {ERR("%s: writing register 0x%x from 0x%x failed\n", __func__,reg, client->addr);return -1;} else {switch (n) {case 1:INFO("I2C write 0x%02X%02X = 0x%02X\n",  data[0], data[1], data[2]);break;case 2:INFO("I2C write 0x%02x = 0x%02x%02x\n", reg, data[2],data[1]);break;case 4:INFO("I2C write 0x%02x = 0x%02x%02x%02x%02x\n", reg,data[4], data[3], data[2], data[1]);break;default:INFO("I2C write %d bytes from address 0x%02x\n", n,reg);}}return 0;
}static void i2c_read(struct gsv2715_dev *gsv2715, u16 reg, u8 *val, u32 n)
{struct i2c_msg msg[2];struct i2c_client *client = gsv2715->client;int err;u8 buf[2] = { 0x00 };buf[0] = (reg >> 8) & 0xFF;buf[1] = reg & 0xFF;INFO("gsv2715-i2c_read - reg = 0x%04X ;buf = 0x%02X 0x%02X\n", reg, buf[0],buf[1]);/*msg[0] addr to read*/msg[0].addr = client->addr;msg[0].flags = !I2C_M_RD;msg[0].buf = &buf[0];msg[0].len = 2;/*msg[1] read data*/msg[1].addr = client->addr;msg[1].flags = I2C_M_RD;msg[1].buf = val;msg[1].len = n;err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));if (err != ARRAY_SIZE(msg)) {ERR("%s: reading register 0x%x from 0x%x failed , ARRAY_SIZE(msg) = %d , err =%d\n", __func__,reg, client->addr,ARRAY_SIZE(msg),err);}INFO("gsv2715-i2c_read end - reg = 0x%04X ;val = 0x%02X\n", reg, *val);
}/*** 从16位地址寄存器中读取8位数据,并将结果存储到指定的变量中。** @param gsv2715 指向gsv2715设备结构体的指针* @param reg 要读取的寄存器地址* @param val 指向用于存储读取结果的变量的指针*/
static void i2c_read_16bit(struct gsv2715_dev *gsv2715, u16 reg, u8 *val)
{i2c_read(gsv2715, reg, val, sizeof(*val));
}static void i2c_write_16bit(struct gsv2715_dev *gsv2715, u16 reg, u8 buf)
{i2c_write(gsv2715, reg, &buf, 1);
}static long gsv2715_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
{return 0;
}static ssize_t gsv2715_write(struct file *file, const char __user *buf,size_t size, loff_t *ppos)
{return 1;
}static ssize_t gsv2715_read(struct file *file, char __user *buf, size_t size,loff_t *ppos)
{return 1;
}int gsv2715_read_version(struct device *dev, u8 *version)
{int ret = 0 ;struct gsv2715_dev *gsv2715 = g_gsv2715;u8 buffer[8];i2c_read_16bit(gsv2715, 0xFF3C, buffer);sprintf(version, "20%02d%02d%02d%02d",buffer[1],buffer[2],buffer[3],buffer[0]);dev_info(dev, "get verison: %s \n",version);return ret;
}static ssize_t gsv2715version_read(struct device *dev,struct device_attribute *attr, char *buf)
{u8 version[12];memset(version, 0 ,sizeof(version));gsv2715_read_version(dev, version);sprintf(buf, "%s\n", version);return strlen(buf);
}static ssize_t gsv2715version_write(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct gsv2715_dev *gsv2715 = g_gsv2715;u32 hdmirxstate = 0;int ret;ret = kstrtouint(buf, 10, &hdmirxstate);if (!ret) {dev_dbg(gsv2715->dev, "gsv2715sw1_hdmirxsel_store: %d\n",hdmirxstate);} else {dev_err(gsv2715->dev, "write hdmi_rx_sel failed!!!\n");}i2c_write_16bit(gsv2715, 0xFF3C, hdmirxstate);DBG("%s: hdmi rx select state: %d,ret = %d,hdmirxstate = %d\n", __func__, gsv2715->hdmi_rx_sel,ret,hdmirxstate);return count;
}static DEVICE_ATTR(gsv2715version, 0644,gsv2715version_read, gsv2715version_write);static int gsv2715_init(struct gsv2715_dev *gsv2715)
{int ret  = 0;gsv2715->hdmi_rx_sel = 0;DBG("%s \n", __func__, gsv2715->hdmi_rx_sel,ret);return ret;
}static const struct file_operations gsv2715_fops = {.owner = THIS_MODULE,.read = gsv2715_read,.write = gsv2715_write,.unlocked_ioctl = gsv2715_ioctl,
};struct miscdevice gsv2715_miscdev = {.minor = MISC_DYNAMIC_MINOR,.name = "gsv2715_dev",.fops = &gsv2715_fops,
};static int gsv2715_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct gsv2715_dev *gsv2715;struct device *dev = &client->dev;int ret;dev_info(dev, "driver version: %02x.%02x.%02x",DRIVER_VERSION >> 16,(DRIVER_VERSION & 0xff00) >> 8,DRIVER_VERSION & 0x00ff);if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)){ERR("FILE:%s Func:%s @Line:%d \n",__FILE__,__func__,__LINE__);return -EIO;}DBG("chip found @ 0x%x (%s)\n", client->addr << 1,client->adapter->name);gsv2715 = devm_kzalloc(dev, sizeof(struct gsv2715_dev), GFP_KERNEL);if (!gsv2715)return -ENOMEM;DBG("FILE:%s Func:%s @Line:%d \n",__FILE__,__func__,__LINE__);gsv2715->client = client;ret = misc_register(&gsv2715_miscdev);if (ret) {ERR("gsv2715 ERROR: could not register gsv2715 device\n");return ret;}mutex_init(&gsv2715->confctl_mutex);ret = device_create_file(gsv2715_miscdev.this_device,&dev_attr_gsv2715version);if (ret) {dev_err(gsv2715->dev, "failed to create attr hdmirxsel!\n");return ret;}	gsv2715_init(gsv2715);g_gsv2715 = gsv2715;INFO("%s found @ 0x%x (%s)\n", client->name, client->addr << 1,client->adapter->name);return 0;
}static int gsv2715_remove(struct i2c_client *client)
{mutex_destroy(&g_gsv2715->confctl_mutex);misc_deregister(&gsv2715_miscdev);kfree(g_gsv2715);return 0;
}static void gsv2715_shutdown(struct i2c_client *client)
{struct gsv2715_dev *gsv2715 = g_gsv2715;u32 data = 0xA1;i2c_write_16bit(gsv2715, 0XFF09, data);
}static const struct of_device_id gsv2715_of_match[] = {{ .compatible = "gscoolink,gsv2715" },{}
};
MODULE_DEVICE_TABLE(of, gsv2715_of_match);static struct i2c_driver gsv2715_driver = {.probe = gsv2715_probe,.remove = gsv2715_remove,.shutdown = gsv2715_shutdown,.driver = {.owner = THIS_MODULE,.name = DRIVER_NAME,.of_match_table = of_match_ptr(gsv2715_of_match),},
};static int __init gsv2715_driver_init(void)
{return i2c_add_driver(&gsv2715_driver);
}static void __exit gsv2715_driver_exit(void)
{i2c_del_driver(&gsv2715_driver);
}device_initcall_sync(gsv2715_driver_init);
module_exit(gsv2715_driver_exit);MODULE_DESCRIPTION("gsv2715 4 HDMI in switch driver");
MODULE_LICENSE("GPL v2");

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/309300.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS 7安装Zookeeper

说明&#xff1a;本文介绍如何在CentOS 7操作系统下使用Zookeeper 下载安装 首先&#xff0c;去官网下载所需要安装的版本&#xff0c;我这里下载3.4.9版本&#xff1b; 上传到云服务器上&#xff0c;解压 tar -xvf zookeeper-3.4.9.tar.gz修改配置 进入Zookeeper目录下的co…

Spark-机器学习(1)什么是机器学习与MLlib算法库的认识

从这一系列开始&#xff0c;我会带着大家一起了解我们的机器学习&#xff0c;了解我们spark机器学习中的MLIib算法库&#xff0c;知道它大概的模型&#xff0c;熟悉并认识它。同时&#xff0c;本篇文章为个人spark免费专栏的系列文章&#xff0c;有兴趣的可以收藏关注一下&…

前端标记语言HTML

HTML&#xff08;HyperText Markup Language&#xff09;是一种用于创建网页的标准标记语言。它是构建和设计网页及应用的基础&#xff0c;通过定义各种元素和属性&#xff0c;HTML使得开发者能够组织和格式化文本、图像、链接等内容。 HTML的基本结构 文档类型声明&#xff0…

SpringBoot+FreeMaker

目录 1.FreeMarker说明2.SpringBootFreeMarker快速搭建Pom文件application.properties文件Controller文件目录结构 3.FreeMarker数据类型3.1.布尔类型3.2.数值类型3.3.字符串类型3.4.日期类型3.5.空值类型3.6.sequence类型3.7.hash类型 4.FreeMarker指令assign自定义变量指令if…

开源版中文和越南语贷款源码贷款平台下载 小额贷款系统 贷款源码运营版

后台 代理 前端均为vue源码&#xff0c;前端有中文和越南语 前端ui黄色大气&#xff0c;逻辑操作简单&#xff0c;注册可对接国际短信&#xff0c;可不对接 用户注册进去填写资料&#xff0c;后台审批&#xff0c;审批状态可自定义修改文字显示 源码免费下载地址抄笔记 (chaob…

详解构造函数

前言 希望这篇文章是有意义的&#xff0c;能够帮助初学者理清构造函数的概念&#xff0c;关系及误区。首先定义一个日期类&#xff0c;借助日期类讲解构造函数。 class Date {public:void Init(int year, int month, int day) //初始化数据的方法{_year year;_month month…

CDP7 下载安装 Flink Percel 包

下载链接&#xff1a;https://www.cloudera.com/downloads/cdf/csa-trial.html 点击后选择版本&#xff0c; 然后点击download now&#xff0c;会有一个协议&#xff0c;勾选即可&#xff0c;然后就有三个文件列表&#xff0c; 我这里是已经注册登录的状态&#xff0c;如果没…

64B/66B GT Transceiver 配置

一、前言 前一篇文章已经讲述了64B/66B的编码原理&#xff0c;此篇文章来配置一下7系列GT的64B/66B编码。并讲述所对应的例子工程的架构&#xff0c;以及部分代码的含义。 二、IP核配置 1、打开7 Series FPGAs Transceiver Wizards&#xff0c;选择将共享逻辑放置在example …

【面试题】s += 1 和 s = s + 1的区别

文章目录 1.问题2.发现过程3.解析 1.问题 以下两个程序真的完全等同吗&#xff1f; short s 0; s 1; short s 0; s s 1; 2.发现过程 初看s 1 和 s s 1好像是等价的&#xff0c;没有什么区别。很长一段时间内我也是这么觉得&#xff0c;因为当时学习c语言的时候教科书…

【数据挖掘】实验6:初级绘图

实验6&#xff1a;初级绘图 一&#xff1a;实验目的与要求 1&#xff1a;了解R语言中各种图形元素的添加方法&#xff0c;并能够灵活应用这些元素。 2&#xff1a;了解R语言中的各种图形函数&#xff0c;掌握常见图形的绘制方法。 二&#xff1a;实验内容 【直方图】 Eg.1&…

【linux深入剖析】深入理解软硬链接 | 动静态库的制作以及使用

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.理解软硬链接1.1 操作观…

pyqt和opencv结合01:读取图像、显示

在这里插入图片描述 1 、opencv读取图像用于pyqt显示 # image cv2.imread(file_path)image cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 将图像转换为 Qt 可接受的格式height, width, channel image.shapebytes_per_line 3 * widthq_image QImage(image.data, width, hei…

vue3 uniapp微信登录

根据最新的微信小程序官方的规定&#xff0c;uniapp中的uni.getUserInfo方法不再返回用户头像和昵称、以及手机号 首先&#xff0c;需获取appID&#xff0c;appSecret&#xff0c;如下图 先调用uni.getUserInfo方法获取code&#xff0c;然后调用后台的api&#xff0c;传入code&…

ssm049基于Vue.js的在线购物系统的设计与实现+vue

在线购物系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线购物系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线购物系统&#xff0c;它彻底改…

【氮化镓】GaN HEMTs结温和热阻测试方法

文章《Temperature rise detection in GaN high-electron-mobility transistors via gate-drain Schottky junction forward-conduction voltages》&#xff0c;由Xiujuan Huang, Chunsheng Guo, Qian Wen, Shiwei Feng, 和 Yamin Zhang撰写&#xff0c;发表在《Microelectroni…

Linux调试器之gdb

前言 我们前面介绍了几个基本的环境开发工具。例如通过yum我们可以安装和卸载软件、通过vim我们可以写代码、通过gcc和g我们可以编译代码成可执行程序。但是如何在Linux下调试代码呢&#xff1f;我们并未介绍&#xff0c;本期我们将来介绍最后一个工具 --- 调试器gdb。 本期内…

Tomcat服务器入门介及用postman工具简单接收数据 2024详解

Tomcat服务器 简介 Tomcat是一个开源的Servlet容器&#xff0c;也是一个支持Java Servlet和JSP技术的Web服务器。它由Apache软件基金会开发和维护。Tomcat的主要作用是将Java Servlet和JavaServer Pages&#xff08;JSP&#xff09;等动态网页技术部署到服务器上&#xff0c;…

基于Python豆瓣电影数据可视化分析系统的设计与实现

大数据可视化项目——基于Python豆瓣电影数据可视化分析系统的设计与实现 2024最新项目 项目介绍 本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示&#xff0c;构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据&#xff0c;我们提供了…

13.多通道视频流缓存以及显示架构

1 简介 多通道视频流缓存以及显示架构是一个在数字图像处理中很基础也很重要的一个架构。在图像拼接以及高分辨率图像显示方面应用范围较为广泛。本文将介绍一个四通道的图像显示。可以四个图像信息输入以及拼接到一个显示屏里面。使用的开发板为A7 2 框架图 架构图如下图所示…

4/11 QT_day5

服务器端 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QMessageBox> #include <QTcpSocket> #include <QList> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass …