一、I2C子系统大致框架
I2C核心层:(由内核实现)
注册了i2c_bus,以及一些中间层的函数,如i2c_driver注册,i2c_master_send,i2c_master_recv,i2c_transfer等函数
I2C控制器层:(一般由厂家实现)
注册了platform,实现了一些底层的发送与接收函数(i2c时序),i2c_transfer底层都是调用到这里。
我们要干的事情:
所以我们需要做的就是注册i2c_driver,并且实现它的probe,用i2c子系统提供的上层i2c_transfer函数进行收发数据。
桥梁:i2c_adapter与i2c_client结构体
在底层驱动的probe中,初始化并注册了i2c_adapter,以及注册了i2c_client,然后将i2c_adapter传给i2c_client。在match中会将client给probe。
二、SPI子系统框架
SPI核心层:(由内核实现)
注册了spi_bus,以及一些中间层的函数,如spi_register_driver注册,spi_message_add_tail,spi_sync等函数
SPI控制器层也叫master驱动层:(一般由厂家实现)
注册了platform,实现了一些底层的发送与接收函数(spi时序),spi_message_add_tail底层都是调用到这里。
我们要干的事情:
所以我们需要做的就是注册spi_driver,并且实现它的probe,用spi子系统提供的上层spi_message_add_tail与spi_sync函数进行收发数据。
桥梁:spi_master结构体
在底层的platform的probe中初始化并注册了spi_master,然后将其传给spi_deivce,最终,spi_bus的probe传入的就是spi_device。
三、LCD子系统
注:lcd驱动也是字符设备驱动,因为lcd也是字符设备。
核心层:
实现fop(中间层的接口),分配设备号,注册类,没有注册设备,没有总线
驱动层:(厂家实现)
注册platform,probe中实现底层的fops,注册fb_info,获取硬件信息,注册核心层的device,也就是字符设备。
桥梁:struct fb_info结构体
上层的fops一般都会从fb_info中获取底层实现的fops。而底层的任务主要是实现底层fops并且注册info结构体。
四、pwm子系统
上层sysfs:
注册pwm字符设备类,但是没有注册pwm设备。提供在sysfs层提供一些修改pwm属性文件的函数。
中间层:
主要是提供一些中间层的函数,方便上层与底层之间联系
底层驱动:
注册platform,实现底层函数,注册pwm_chip结构体,注册pwm字符设备。
桥梁:
pwm_chip结构体
五、USB驱动框架
核心层:
注册usb_bus,实现检测usb硬件插入到自动将其设备注册入usb_bus的过程。在其中也要包括要获取usb硬件的一些必要信息,如:各种描述符。
调用栈:
hub_probe:中
INIT_WORK(&hub->events, hub_event);说明hub_event是一个工作队列,它被绑定到&hub->event这个工作项中,那么又在哪里注册这个工作项呢?
hub_event:
port_event:
hub_port_connect_change:
hub_port_connect:
hub_port_init://插上时打印信息
hub_irq:
kick_hub_wq:
queue_work(hub_wq, &hub->events):
hub_port_connect:
->hub_port_init
-> hub_set_address(udev, devnum);//设置从设备地址
获取描述符
->usb_get_device_descriptor(udev, 8);//一开始不知道这个设备描述符一次最大多少个字节
->usb_get_bos_descriptor(udev);
->usb_new_device
->err = usb_enumerate_device(udev); /* Read descriptors */读出获取的描述符
->err = device_add(&udev->dev);//在将这个从设备加入到usb bus中
驱动层:
所以我们驱动层的任务就是注册usb_driver,并实现probe。