首页 > 系统相关 >Linux Kernel 设备驱动之I2C之client描述

Linux Kernel 设备驱动之I2C之client描述

时间:2023-06-04 13:08:00浏览次数:41  
标签:Kernel I2C slave struct driver client Linux device i2c


前面我们已经了解到i2c的host描述,对于设备来说,其描述较为简单,数据结构实现如下:


/**
 * struct i2c_client - represent an I2C slave device
 * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
 * I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
 * @addr: Address used on the I2C bus connected to the parent adapter.
 * @name: Indicates the type of the device, usually a chip name that's
 * generic enough to hide second-sourcing and compatible revisions.
 * @adapter: manages the bus segment hosting this I2C device
 * @dev: Driver model device node for the slave.
 * @irq: indicates the IRQ generated by this device (if any)
 * @detected: member of an i2c_driver.clients list or i2c-core's
 * userspace_devices list
 * @slave_cb: Callback when I2C slave mode of an adapter is used. The adapter
 * calls it to pass on slave events to the slave driver.
 *
 * An i2c_client identifies a single device (i.e. chip) connected to an
 * i2c bus. The behaviour exposed to Linux is defined by the driver
 * managing the device.
 */
struct i2c_client {
 unsigned short flags;  /* div., see below  */
 unsigned short addr;  /* chip address - NOTE: 7bit */
     /* addresses are stored in the */
     /* _LOWER_ 7 bits  */
 char name[I2C_NAME_SIZE];
 struct i2c_adapter *adapter; /* the adapter we sit on */
 struct device dev;  /* the device structure  */
 int irq;   /* irq issued by device  */
 struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
 i2c_slave_cb_t slave_cb; /* callback for slave mode */
#endif
};


显然,对于I2c设备来说,其最主要是提供的i2c地址,这里用addr描述。对于内核驱动模型来说,任何设备都需要内嵌


struct device dev,以能完全跟踪描述设备。


 


对于一个I2C设备来说,其驱动类型定义如下:


 


struct i2c_driver

/* Notifies the driver that a new bus has appeared. You should avoid
  * using this, it will be removed in a near future.
  */
 int (*attach_adapter)(struct i2c_adapter *) __deprecated;
 /* Standard driver model interfaces */
 int (*probe)(struct i2c_client *, const struct i2c_device_id *);
 int (*remove)(struct i2c_client *);
 /* driver model interfaces that don't relate to enumeration  */
 void (*shutdown)(struct i2c_client *);
 /* Alert callback, for example for the SMBus alert protocol.
  * The format and meaning of the data value depends on the protocol.
  * For the SMBus alert protocol, there is a single bit of data passed
  * as the alert response's low bit ("event flag").
  * For the SMBus Host Notify protocol, the data corresponds to the
  * 16-bit payload data reported by the slave device acting as master.
  */
 void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol,
        unsigned int data);
 /* a ioctl like command that can be used to perform specific functions
  * with the device.
  */
 int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
 struct device_driver driver;
 const struct i2c_device_id *id_table;
 /* Device detection callback for automatic device creation */
 int (*detect)(struct i2c_client *, struct i2c_board_info *);
 const unsigned short *address_list;
 struct list_head clients;
};
显然,设备驱动是完成对I2C设备的驱动。

需要注意里面struct device_driver driver的设置,其也是用于满足设备驱动模型要求。

 

需要注意,一般来说,i2c_client是静态定义或者DTS分析得到的一个内核对象,也就是说其是内核I2C框架层

分析得到的对象,一般不需要用户直接分配。而I2C设备的驱动则需要静态定义实现,并通过函数

i2c_register_driver()注册到I2C框架层,此函数对外提供i2c_add_driver().
#define i2c_add_driver(driver) \
 i2c_register_driver(THIS_MODULE, driver)


/*
 * An i2c_driver is used with one or more i2c_client (device) nodes to access
 * i2c slave chips, on a bus instance associated with some i2c_adapter.
 */
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
 int res;
 /* Can't register until after driver model init */
 if (unlikely(WARN_ON(!i2c_bus_type.p)))
  return -EAGAIN;
 /* add the driver to the list of i2c drivers in the driver core */
 driver->driver.owner = owner;设备驱动
 driver->driver.bus = &i2c_bus_type;设备驱动所在总线类型
 /* When registration returns, the driver core
  * will have called probe() for all matching-but-unbound devices.
  */
 res = driver_register(&driver->driver);注册设备驱动,设备驱动模型要求
 if (res)
  return res;
 /* Drivers should switch to dev_pm_ops instead. */
 if (driver->suspend)
  pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
   driver->driver.name);
 if (driver->resume)
  pr_warn("i2c-core: driver [%s] using legacy resume method\n",
   driver->driver.name);
 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
 INIT_LIST_HEAD(&driver->clients);
 /* Walk the adapters that are already present */
 i2c_for_each_dev(driver, __process_new_driver);驱动开始探测设备,如果有设备,则初始化它。
 return 0;
}

设备驱动定义形式如下:

static const struct i2c_device_id i2c_slave_eeprom_id[] = {
 { "slave-24c02", 2048 / 8 },
 { }
};
MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id);
static struct i2c_driver i2c_slave_eeprom_driver = {
 .driver = {
  .name = "i2c-slave-eeprom",
 },
 .probe = i2c_slave_eeprom_probe,
 .remove = i2c_slave_eeprom_remove,
 .id_table = i2c_slave_eeprom_id,
};
module_i2c_driver(i2c_slave_eeprom_driver);


 


 


 


 


 


 

标签:Kernel,I2C,slave,struct,driver,client,Linux,device,i2c
From: https://blog.51cto.com/u_11860992/6410364

相关文章

  • Linux 内核等待队列
    Linux内核中的等待队列是一种延时机制,其用于当前进程需要等待某些资源而进入一种sleep状态,当等待条件为真时,进程被唤醒,继续执行。显然,这里涉及三个方面,即,一是等待时当前进程处理,二是进程等待时所关注的资源处理,三时进程何时被唤醒继续执行。所以,我们这里需要几个数据结构,主要描......
  • Linux下安装jdk和Tomcat
    一、下载jdk1.5从http://www.sun.com/网站下载jdk1.5 下载:jdk-1_5_0_15-linux-i586-rpm.bin 二、安装jdk  1.#chmod+xjdk-1_5_0_15-linux-i586-rpm.bin#./jdk-1_5_0_15-linux-i586-rpm.bin按提示按输入yes,在同一目录会得到一个jdk-1_5_0_15-linux-i586-rpm通过#rpm–iv......
  • Linux操作系统安装及服务控制
    Linux操作系统安装及服务控制一、设置Linux操作系统每次开机后自动进入字符模式界面。二、使用ntsysv工具同时调整2,3,4,5运行级别中的服务状态,关闭下列服务:atd,bluetooth,mdmonitor,rhnsd,rpcgssd,postfix.关闭下列服务:atd,bluetooth,mdmonitor,rhnsd,rpcgssd,postfix.atdbluetoothmdmo......
  • 5、半虚拟化驱动--virtio(linux和windows)和安装Windows server虚拟机
    KVM的功能主要体现在利用KVM的硬件辅助性虚拟化可以提高处理速度。但在虚拟机中,有些硬件不是KVM来实现加速的,如磁盘、内存、网络的性能,如果更好的提升速度,需要安装半虚拟化驱动半虚拟化驱动在软件层通过修改源代码让硬件的操作被虚拟机和宿主机所识别半虚拟化驱动--virtio红帽RHE......
  • 串口(PL011)在Linux启动运行过程中扮演的角色
    关键词:PL011、earlyprintk、AMBA、UART、tty、console等等。串口虽然是一种简单的工具,但是在Linux启动、运行、调试中扮演了重要角色。其稳定、易用、高效(某些场景)。串口依赖的模块少,在FPGA初期调试中扮演重要角色。往往是CPU基本功能可用后,即可使能串口进行功能调试。下面记......
  • Linux常用的shell命令
    shell linux命令行就是由shell提供的,shell其实是所有命令行程序的统称,而CentOS系统中默认使用的shell程序就是bash,他是linux系统中运行的一种特殊程序,其文件位于/bin/bash,用户在登录linux系统时,系统就会自动加载一个shell程序,在用户和内核之间充当“翻译官”。 这里要跟shel......
  • 查看linux中某个端口(port)是否被占用(netstat,lsof)
    netstat-tunlp会显示所有端口和所有对应的程序,用grep管道可以过滤出想要的关键字段.列一下22端口占用的程序[root@leiwantmp]#netstat-tunlp|grep22tcp000.0.0.0:429570.0.0.0:*LISTEN2230/rpc.statdtc......
  • linux 性能自我学习 ———— cpu 快速定位问题 [六]
    前言主要介绍一下cpu如何快速定位问题。正文cpu的一些性能指标:1.cpu使用率cpu使用率描述了非空闲时间占总cpu时间的百分比,根据cpu上运行任务的不同,又被分为用户cpu、系统cpu、i/o等待cpu、软中断、硬中断。用户cpu使用率,包括用户态cpu使用率,和低优先级用户态cpu使用......
  • Linux会替代Windows吗?
    Windows用户们,去还是留?Windows依然是高居榜首的桌面操作系统,占据90%以上的市场份额,远超macOS和 Linux 。从数据来看,尽管linux并不是Windows的头号接班人,但近几年越来越多用户转向Ubuntu、LinuxMint等发行版,的确为Linux带来了不小的增长。面对Windows10发布......
  • Linux会替代Windows吗?
    Windows用户们,去还是留?Windows依然是高居榜首的桌面操作系统,占据90%以上的市场份额,远超macOS和 Linux 。从数据来看,尽管linux并不是Windows的头号接班人,但近几年越来越多用户转向Ubuntu、LinuxMint等发行版,的确为Linux带来了不小的增长。面对Windows10发布......