(RK3566驱动开发 - 2).IIC驱动

embedded/2024/11/24 6:15:32/

一.设备树

(1).流程图

(2).设备树代码

二.驱动代码部分

(1).流程图

(2).驱动代码

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/i2c.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include "oledfont.h"#include <linux/clk.h>
#include <linux/gpio/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/version.h>#define OLED_CNT    1
#define OLED_NAME   "oled"#define OLED_CMD    0X00    //OLED 写命令
#define OLED_DATA   0X40    //OLED 写数据#define Max_Column  128     //OLED 的 x方向的像素个数//IIC从用户控件接收的数据格式
struct display_stru 
{int  x;             //x坐标int  y;             //y坐标char *buf;          //接收数据缓冲区
};/* 设备结构体 */
struct oled_dev
{dev_t devid;            /* 设备号 */struct cdev cdev;       /* cdev */struct class *class;    /* 类 */struct device *device;  /* 设备 */struct device_node *nd; /* 设备结点 */int major;              /* 主设备号 */void *private_data;     /* 私有数据 */
};/* OLED 设备 */
struct oled_dev oleddev;/*** @description:            向 OLED 写入若干个字节的数据* @param - dev     :       OLED 设备* @param - reg     :       寄存器首地址* @param - buf     :       要写入的数据缓冲区* @param - len     :       要写入的字节数* @return          :       成功则返回(发送的 msg 数量),失败则返回(负值) */
static s32 oled_write_regs(struct oled_dev *dev,u8 reg,u8 *buf,int len)
{u8 b[256] = {};struct i2c_msg msg;struct i2c_client *client = (struct i2c_client *)dev->private_data;b[0] = reg;                 //填充寄存器的首地址memcpy(&b[1],buf,len);      //填充要写入的数据msg.addr = client->addr;    //OLED 设备msg.buf = b;msg.flags = 0;              //表示为写数据msg.len = len + 1;          //数据长度 = 1个字节的寄存器首地址 + 要写入的数据长度return i2c_transfer(client->adapter,&msg,1);
}/*** @description:            向 OLED 写入单个字节的数据* @param - dev     :       OLED 设备* @param - reg     :       寄存器首地址* @param - data    :       要写入的单个字节的数据* @return          :       成功则返回(发送的 msg 数量),失败则返回(负值)*/
static s32 oled_write_reg(struct oled_dev *dev,u8 reg,u8 data)
{u8 buf = data;return oled_write_regs(dev,reg,&buf,1);
}/*** @description:            oled 初始化* @param           :       无* @return          :       无*/
void oled_init(void)
{int ret;u8 i = 0;u8 data[] ={ 0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6,0xA8, 0x3F, 0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05,0xD9, 0xF1, 0xDA, 0x12, 0xDB, 0x30, 0x8D, 0x14, 0xAF };for(i = 0 ; i < sizeof(data) ; i++){ret = oled_write_reg(&oleddev,OLED_CMD,data[i]);}
}/*** @description:            oled 清屏* @param           :       无* @return          :       无 */
void oled_clear(void)
{u8 i,n;for(i = 0 ; i < 8 ; i++){oled_write_reg(&oleddev,OLED_CMD,0XB0+i);               //设置页地址oled_write_reg(&oleddev,OLED_CMD,0x00);                 //设置显示位置-列低地址oled_write_reg(&oleddev,OLED_CMD,0x10);                 //设置显示位置-列高地址}for(n = 0 ; n < 128 ; n++){oled_write_reg(&oleddev,OLED_DATA,0x00);}
}/*** @description:            设置 OLED 某个点* @param - x       :       x坐标* @param - y       :       y坐标* @return          :       无*/
void oled_set_pos(u8 x, u8 y){  oled_write_reg(&oleddev,OLED_CMD, 0xb0 + y);oled_write_reg(&oleddev,OLED_CMD, ((x & 0xf0) >> 4) | 0x10);oled_write_reg(&oleddev,OLED_CMD, x & 0x0f);}/*** @description:            oled 显示单个字符* @param - x           :   x坐标* @param - y           :   y坐标* @param - chr         :   要显示的字符* @return              :   无*/
void oled_showchar(u8 x, u8 y, u8 chr){     u8 c=0, i=0;c = chr - ' ';                    if(x > Max_Column-1){x = 0;y = y + 2;}oled_set_pos(x, y);for(i=0; i<8; i++){oled_write_reg(&oleddev,OLED_DATA, F8X16[c*16+i]);}oled_set_pos(x,y+1);for(i=0; i<8; i++){oled_write_reg(&oleddev,OLED_DATA, F8X16[c*16+i+8]);  }}/*** @description:            oled显示字符串* @param - x       :       x坐标* @param - y       :       y坐标* @param - chr     :       字符串首地址* @return          :       无*/
void oled_showstring(u8 x, u8 y, u8 *chr){unsigned char j=0;while(chr[j] != '\0'){     oled_showchar(x, y, chr[j]);x += 8;if(x > 120){x = 0;y += 2;}j++;}
}/*** @description:            open 函数*/
static int oled_open(struct inode *inode,struct file *filp)
{filp->private_data = &oleddev;/* 初始化 OLED */oled_init();oled_clear();return 0;
}/*** @description:            write 函数*/
static ssize_t oled_write(struct file *filp,const char __user *buf,size_t cnt,loff_t *offt)
{/* 可根据用户空间传进来的 buf , 自行编写对应的逻辑实现 */oled_showstring(0,0,"hello");return 0;
}/*** @description:            release 函数*/
static int oled_release(struct inode *inode,struct file *filp)
{return 0;
}/* 绑定设备操作函数 */
static const struct file_operations fops = 
{.open = oled_open,.write = oled_write,.release = oled_release,
};/*** @description:            probe 函数*/
static int oled_probe(struct i2c_client *client,const struct i2c_device_id *id)
{dev_err(oleddev.device,"enter oled_probe\r\n");/* 1.创建设备号 */if(oleddev.major){oleddev.devid = MKDEV(oleddev.major,0);register_chrdev_region(oleddev.devid,OLED_CNT,OLED_NAME);}else{alloc_chrdev_region(&oleddev.devid,0,OLED_CNT,OLED_NAME);oleddev.major = MAJOR(oleddev.devid);}/* 2.注册cdev */cdev_init(&oleddev.cdev,&fops);cdev_add(&oleddev.cdev,oleddev.devid,OLED_CNT);/* 3.创建类 */oleddev.class = class_create(THIS_MODULE,OLED_NAME);if(IS_ERR(oleddev.class)){return PTR_ERR(oleddev.class);}/* 4.创建设备 */oleddev.device = device_create(oleddev.class,NULL,oleddev.devid,NULL,OLED_NAME);if(IS_ERR(oleddev.device)){return PTR_ERR(oleddev.device);}oleddev.private_data = client;return 0;
}/*** @description:            remove 函数*/
static int oled_remove(struct i2c_client *client)
{   dev_err(oleddev.device,"enter oled_remove\r\n");/* 1.注销字符设备驱动 */cdev_del(&oleddev.cdev);unregister_chrdev_region(oleddev.devid,OLED_CNT);/* 2.注销类和设备 */device_destroy(oleddev.class,oleddev.devid);class_destroy(oleddev.class);return 0;
}/* 无设备树时的匹配方式 - ID列表 */
static const struct i2c_device_id oled_id[] = 
{{"oled_test",0},{},
};/* 设备树下的匹配方式 - 匹配列表 */
static const struct of_device_id oled_of_match[] = 
{{.compatible = "oled_test"},{},
};/* i2c 驱动结构体 */
static struct i2c_driver oled_driver = 
{.probe  = oled_probe,.remove = oled_remove,.driver = {.owner = THIS_MODULE,.name = "oled",.of_match_table = oled_of_match,},.id_table = oled_id,
};/*** @description:            驱动入口函数*/
static int __init oled_module_init(void)
{return i2c_add_driver(&oled_driver);
}/*** @description:            驱动出口函数*/
static void __exit oled_module_exit(void)
{i2c_del_driver(&oled_driver);
}module_init(oled_module_init);
module_exit(oled_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kaneki");


http://www.ppmy.cn/embedded/139433.html

相关文章

Excel365和WPS中提取字符串的五种方法

一、问题的提出 如何在WPS或者Excel365中提取A列指定的字符串&#xff0c;从"面"开始一直到".pdf"? 问题的提出 二、问题的分析 我们可以采用多种方法解决这个问题&#xff0c;由于A列到B列的提取是非常有规律的&#xff0c;因此我们可以采用如下几种方…

机器翻译基础与模型 之一: 基于RNN的模型

一、机器翻译发展历程 基于规则的-->基于实例的-->基于统计方法的-->基于神经网络的 传统统计机器翻译把词序列看作离散空间里的由多个特征函数描述的点&#xff0c;类似 于 n-gram 语言模型&#xff0c;这类模型对数据稀疏问题非常敏感。神经机器翻译把文字序列表示…

Docker和VMWare有什么不同

Docker与VMWare在虚拟化技术方面存在显著的差异。以下是对两者区别的详细分析&#xff1a; 一、虚拟化类型与实现方式 Docker 虚拟化类型&#xff1a;Docker采用的是操作系统级别的虚拟化&#xff08;也称为容器化&#xff09;。实现方式&#xff1a;Docker容器共享宿主操作系…

[JAVA]MyBatis框架—获取SqlSession对象

SqlSessionFactory作为MyBatis框架的核心接口有三大特性 SqlSessionFactory是MyBatis的核心对象 用于初始化MyBatis&#xff0c;创建SqlSession对象 保证SqlSessionFactory在应用中全局唯一 1.SqlSessionFactory是MyBatis的核心对象 假设我们要查询数据库的用户信息&#x…

PHP Date 函数:日期和时间处理的全指南

PHP Date 函数:日期和时间处理的全指南 PHP Date 函数是 PHP 编程语言中用于处理日期和时间的核心函数之一。它提供了强大的功能,允许开发者轻松地格式化、计算和操作日期和时间值。本文将详细介绍 PHP Date 函数的用法,包括基本格式化、时间戳处理、时区设置以及一些高级特…

Ubuntu问题 -- 设置ubuntu的IP为静态IP (图形化界面设置) 小白友好

目的 为了将ubuntu服务器IP固定, 方便ssh连接人在服务器前使用图形化界面设置 设置 找到自己的网卡名称, 我的是 eno1, 并进入设置界面 查看当前的IP, 网关, 掩码和DNS (注意对应eno1) nmcli dev show掩码可以通过以下命令查看完整的 (注意对应eno1) , 我这里是255.255.255.…

微信小程序 最新获取用户头像以及用户名

一.在小程序改版为了安全起见 使用用户填写来获取头像以及用户名 二.代码实现 <view class"login_box"><!-- 头像 --><view class"avator_box"><button wx:if"{{ !userInfo.avatarUrl }}" class"avatorbtn" op…

【Node.js】深入理解 V8 JavaScript 引擎

V8 是 Google 开发的高性能 JavaScript 和 WebAssembly 引擎&#xff0c;是 Node.js 和 Google Chrome 的核心组件之一。它的强大性能和高效设计&#xff0c;使其成为现代 JavaScript 应用的基石。在本文中&#xff0c;我们将全面解析 V8 引擎的架构、运行原理及其在 Node.js 中…