Linux下SPI和IIC驱动免在设备树上添加设备信息的编写方法

编写驱动时,一般需要往设备树上添加节点信息,这里提供一种直接在驱动中添加设备信息的方法。

i2c的驱动模板如下

#include <linux/module.h>
#include <linux/i2c.h>

#define SENSOR_BUS_NUM 0
#define SENSOR_SLAVE_ADDRESS 0x3e
#define SENSOR_NAME "sensor"
struct i2c_client *sensor_client=NULL;

static int sensor_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
    sensor_client=client;
    return 0;
}

static int sensor_remove(struct i2c_client *client)
{
    return 0;
}

static const struct i2c_device_id sensor_id[] = {
    {SENSOR_NAME, 0},
    { }
};
MODULE_DEVICE_TABLE(i2c, sensor_id);

static struct i2c_driver sensor_driver = {
    .driver = {
             .name = SENSOR_NAME,
    },
    .probe    = sensor_probe,
    .remove   = sensor_remove,
    .id_table = sensor_id,
};

static struct i2c_board_info sensor_device = {
    I2C_BOARD_INFO("hmc5883l-i2c", SENSOR_SLAVE_ADDRESS),
};

static int __init sensor_init(void)
{
    struct i2c_adapter *adap;
    struct i2c_client *client;

    adap = i2c_get_adapter(sensor_bus_num);
    if (!adap) {
        printk("i2c adapter %d\n",sensor_bus_num);
        return -ENODEV;
    } else {
        printk("get ii2 adapter %d ok\n", sensor_bus_num);
        client = i2c_new_device(adap, &sensor_device);
    }
    if (!client) {
        printk("get i2c client %s @ 0x%02x fail!\n", sensor_device.type,
                sensor_device.addr);
        return -ENODEV;
    } else {
        printk("get i2c client ok!\n");
    }
    i2c_put_adapter(adap);
    i2c_add_driver(&sensor_driver);
    printk("sensor init success!\n");
    return 0;
}

static void __exit sensor_exit(void)
{
    i2c_del_driver(&sensor_driver);
    if(sensor_client!=NULL)
    i2c_unregister_device(sensor_client);
    printk("Module removed\n");
}

module_init(sensor_init);
module_exit(sensor_exit);
ODULE_AUTHOR("GPL");
ODULE_LICENSE("GPL");

spi的驱动模板如下

#include <linux/module.h>
#include <linux/spi/spi.h>

#define DEVICE_NAME   "sensor"
#define SENSOR_SPI_BUS 0
struct spi_device *sensor_spi=NULL;

int sensor_spi_write(void)
{
	return 0;
}

int sensor_spi_read(void)
{
	return 0;
}

static const struct spi_device_id sensor_spi_id[] = {
	{ DEVICE_NAME, 0 },
	{ }
};

MODULE_DEVICE_TABLE(spi, sensor_spi_id);

static int  sensor_probe(struct spi_device *spi)
{
	sensor_spi=spi;
	return 0;
}

static int  sensor_remove(struct spi_device *spi)
{
	return 0;
}

static struct spi_driver sensor_driver = {
	.driver = {
		.name  = DEVICE_NAME,
		.owner = THIS_MODULE,
	},
	.probe    =  sensor_probe,
	.remove   =  sensor_remove,
	.id_table =  sensor_spi_id,
};

static __init int sensor_spi_init(void)
{
	int status=-1;
	struct spi_master *master;
	struct spi_device *spi;
	struct spi_board_info chip =
	{
        .modalias	  = DEVICE_NAME,
        .mode         = 0x00,
        .bus_num	  = 0,
        .chip_select  = 0,
        .max_speed_hz = 2000000,
    };
	spi_register_driver(&sensor_driver);
	if (status<0)
	{
		pr_err("%s: spi_register_driver spi_driver failure. status = %d\n", __func__, status);
	}
	pr_err("%s: spi_register_driver spi_driver success. status = %d\n", __func__, status);
	master = spi_busnum_to_master(SENSOR_SPI_BUS);
    if (!master)
    {
        status = -ENODEV;
        goto error_busnum;
    }
    spi = spi_new_device(master, &chip);
    if (!spi)
    {
        status = -EBUSY;
        goto error_mem;
    }
	return status;

error_mem:
error_busnum:
    spi_unregister_driver(&sensor_driver);
    return status;
}

static __exit void sensor_spi_exit(void)
{
	spi_unregister_driver(&sensor_driver);
	if(sensor_spi!=NULL)
	spi_unregister_device(sensor_spi);
}

module_init(sensor_spi_init);
module_exit(sensor_spi_exit);
MODULE_LICENSE("GPL v2");
时间: 2024-10-14 21:59:42

Linux下SPI和IIC驱动免在设备树上添加设备信息的编写方法的相关文章

Linux下spi驱动开发

转载至:http://www.embedu.org/Column/Column367.htm 作者:刘洪涛,华清远见嵌入式学院讲师. 一.概述 基于子系统去开发驱动程序已经是linux内核中普遍的做法了.前面写过基于I2C子系 统的驱动开发.本文介绍另外一种常用总线SPI的开发方法.SPI子系统的开发和I2C有很多的相似性,大家可以对比学习.本主题分为两个部分叙述,第一 部分介绍基于SPI子系统开发的理论框架:第二部分以华清远见教学平台FS_S5PC100上的M25P10芯片为例(内核版本2.6

分享在Linux下使用OSGi.NET插件框架快速实现一个分布式服务集群的方法

在这篇文章我分享了如何使用分层与模块化的方法来设计一个分布式服务集群.这个分布式服务集群是基于DynamicProxy.WCF和OSGi.NET插件框架实现的.我将从设计思路.目标和实现三方面来描述. 1 设计思路 首先,我来说明一下设计思路.我们先来看看目前OSGi.NET插件框架的服务.在这里,服务不是远程服务,它是轻量级的服务,由接口和实现类组成,如下图所示.服务契约插件定义了服务接口,服务实现插件向服务总线注册服务,服务调用插件利用服务契约(接口)从服务总线获取实现的服务并调用,服务实现

linux下安装编译网卡驱动的方法

安装linux操作系统后发现没有网卡驱动,表现为 system → Administration → Network下Hardware列表为空. 以下为安装编译网卡驱动的过程,本人是菜鸟,以下是我从网上找的资料进行整理,并实际操作的过程,仅供借鉴.  一.检测linux系统内核版本和网卡类型,相关命令如下: uname -r                    查看linux内核版本 (uname -a 可显示所有信息)lsmod                        设备加载情况 l

在linux下安装某个硬件驱动到方法

东西很简单,几句话就能说清除. 使用lsipc检查你需要安装到硬件,记住硬件到关键型号,去搜索引擎搜索linux下的驱动文件 对文件进行安装简单的解压后基本上是 ./configure && make && make install 安装完成后可能需要重启计算机,重启后检查驱动是否安装完成.

嵌入式Linux下3G无线上网卡的驱动

内核:需要有以下模块:option usbserial usbstorage 主要是要在编译内核的时候选中 [*] Network device support  ---> <*>   PPP (point-to-point protocol) support <*>     PPP BSD-Compress compression <*>     PPP Deflate compression [*]     PPP filtering <*>   

Linux下使用Vi是方向键变乱码 退格键不能使用的解决方法

在Linux下编辑一些文件,这就涉及到了vi这个编辑器了.在Linux下,初始使用vi的时候有点问题,就是在编辑模式下使用方向键的时候,并不会使光标移动,而是在命令行中出现[A [B [C [D之类的字母,而且编辑错误的话,就连平时关于的退格键(Backspace键)都使用不了,只能用Delete来删除.针对这个问题,网上的答案有很多,例如是安装完整版的vim啊,编辑/etc/vim/vimrc.tiny等方法,很杂很乱,在这里我就做个详细的总结吧: 一.编辑/etc/vim/vimrc.tin

方法:Linux 下用JAVA获取CPU、内存、磁盘的系统资源信息

CPU使用率: InputStream is = null; InputStreamReader isr = null; BufferedReader brStat = null; StringTokenizer tokenStat = null; // 用来分隔String的应用类 try { System.out.println("Get usage rate of CUP : "); Process process = Runtime.getRuntime().exec(&quo

linux下Pl353 NAND Flash驱动分析

linux的NAND Flash驱动位于drivers/mtd/nand子目录下: nand_base.c-->定义通用的nand flash基本操作函数,如读写page,可自己重写这些函数 nand_bbt.c-->与坏块管理有关的函数和结构体 nand_ids.c-->nand_flash_ids[](芯片ID)和nand_manuf_ids[](厂商ID) nand_ecc.c-->软件ECC代码,若系统支持硬件ECC,则不用理会这个文件 pl353_nand.c-->

linux下EC20 4G模块驱动移植

之前有移植过ME909s MU609,主要工作就是把4G模块当做USB设备,挂载在linux上,驱动移植主要是能够让板子识别到模块,并产生SUB多个虚拟的节点,用于操作模块,拨号上网 关于内核的配置,请参考:https://www.cnblogs.com/ChenChangXiong/p/10852177.html 内核配置: Device Drivers ---> [*] USB support ---> <*> USB Serial Converter support ---&