整个SPI驱动架构可以分为协议驱动、通用接口层和控制器驱动三大部分。其中,控制器驱动即spi主机,负责最底层的数据收发工作,为了完成数据的收发工作,控制器驱动需要完成以下这些功能:
(1)申请必要的硬件资源,例如中断,DMA通道,DMA内存缓冲区等等;
(2)配置SPI控制器的工作模式和参数,使之可以和相应的设备进行正确的数据交换工作;
(3)向通用接口层提供接口,使得上层的协议驱动可以通过通用接口层访问控制器驱动;
(4)配合通用接口层,完成数据消息队列的排队和处理,直到消息队列变空为止。
1 控制器设备platform_device
1.1 定义platform_device
spi控制器遵循linux的设备模型框架,所以,一个spi控制器在代码中对应一个挂在platfrom bus下面的一个device设备。所以在板级的代码中为SPI控制器定义一个platform_device结构即可。spi的platform_device其实就是spi_master即spi主机。下面以Samsung的SOC芯片:S32440,做为例子,看看如何定义这个platform_device。以下的代码来自:arch\arm\mach-s3c24xx\mach-mini2440.c中:
因为会有多个platfrom device,所以定义为数组:
1 static struct platform_device *mini2440_devices[] __initdata = {
2 &s3c_device_ohci,
3 &s3c_device_wdt,
4 &s3c_device_i2c0,
5 &s3c_device_rtc,
6 &s3c_device_usbgadget,
7 &mini2440_device_eth,
8 &mini2440_led1,
9 &mini2440_led2,
10 &mini2440_led3,
11 &mini2440_led4,
12 &mini2440_button_device,
13 &s3c_device_nand,
14 &s3c_device_sdi,
15 &s3c_device_iis,
16 &uda1340_codec,
17 &mini2440_audio,
18 };
上面数组中没有添加spi的platfrom,需要自己定义并添加。如下:
1 struct platform_device s3c2440_device_spi0 = {
2 .name = "s3c6410-spi",
3 .id = 0,
4 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
5 .resource = s3c2440_spi0_resource,
6 .dev = {
7 .dma_mask = &samsung_device_dma_mask,
8 .coherent_dma_mask = DMA_BIT_MASK(32),
9 },
10 };
定义s3c2440_spi0_resource
1 static struct resource s3c2440_spi0_resource[] = {
2 [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256),
3 [1] = DEFINE_RES_DMA(DMACH_SPI0_TX),
4 [2] = DEFINE_RES_DMA(DMACH_SPI0_RX),
5 [3] = DEFINE_RES_IRQ(IRQ_SPI0),
6 };
然后还要定义s3c2440_spi0_resource.
最终在kernel初始化的是会去调用。
1 static void __init mini2440_init(void)
2 {
3 struct mini2440_features_t features = { 0 };
4 int i;
5
6 printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
7 mini2440_features_str);
8
9 /* Parse the feature string */
10 mini2440_parse_features(&features, mini2440_features_str);
11
12 /* turn LCD on */
13 s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
14
15 /* Turn the backlight early on */
16 WARN_ON(gpio_request_one(S3C2410_GPG(4), GPIOF_OUT_INIT_HIGH, NULL));
17 gpio_free(S3C2410_GPG(4));
18
19 /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
20 gpio_request_one(S3C2410_GPB(1), GPIOF_IN, NULL);
21 s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
22 gpio_free(S3C2410_GPB(1));
23
24 /* mark the key as input, without pullups (there is one on the board) */
25 for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
26 s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
27 s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
28 }
29 if (features.lcd_index != -1) {
30 int li;
31
32 mini2440_fb_info.displays =
33 &mini2440_lcd_cfg[features.lcd_index];
34
35 printk(KERN_INFO "MINI2440: LCD");
36 for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
37 if (li == features.lcd_index)
38 printk(" [%d:%dx%d]", li,
39 mini2440_lcd_cfg[li].width,
40 mini2440_lcd_cfg[li].height);
41 else
42 printk(" %d:%dx%d", li,
43 mini2440_lcd_cfg[li].width,
44 mini2440_lcd_cfg[li].height);
45 printk("\n");
46 s3c24xx_fb_set_platdata(&mini2440_fb_info);
47 }
48
49 s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
50 s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
51 s3c_nand_set_platdata(&mini2440_nand_info);
52 s3c_i2c0_set_platdata(NULL);
53
54 i2c_register_board_info(0, mini2440_i2c_devs,
55 ARRAY_SIZE(mini2440_i2c_devs));
56
57 platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
58
59 if (features.count) /* the optional features */
60 platform_add_devices(features.optional, features.count);
61
62 }
2 spi的platform_driver
既然spi控制器是挂在platform下的device,有platform_device,肯定也要有platform_driver
定义位于:/drivers/spi/spi-s3c24xx.c
1 static struct platform_driver s3c24xx_spi_driver = {
2 .probe = s3c24xx_spi_probe,
3 .remove = s3c24xx_spi_remove,
4 .driver = {
5 .name = "s3c2410-spi",
6 .owner = THIS_MODULE,
7 .pm = S3C24XX_SPI_PMOPS,
8 },
9 };
然后注册spi platform_driver
module_platform_driver(s3c24xx_spi_driver);
宏展开后:
定义为于:include\linux\Platform_device.h
#define module_platform_driver(__platform_driver) \
module_driver(__platform_driver, platform_driver_register, \
platform_driver_unregister)
最终展开为驱动的入口和出口:
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);
3 platform_device和platform_driver的匹配
当platform_device或者platform_driver添加到platform_bus的时候会调用platform_match()去匹配。
static int platform_match(struct device *dev, struct device_driver *drv)
{
....
}
匹配成功就会调用probe函数s3c24xx_spi_probe() :
除了完成必要的硬件资源初始化工作以外,最重要的工作就是通过spi_bitbang_start()完成了对控制器的注册工作。
1 static int s3c24xx_spi_probe(struct platform_device *pdev)
2 {
3 struct s3c2410_spi_info *pdata;
4 struct s3c24xx_spi *hw;
5 struct spi_master *master;
6 struct resource *res;
7 int err = 0;
8
9 master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
10 if (master == NULL) {
11 dev_err(&pdev->dev, "No memory for spi_master\n");
12 err = -ENOMEM;
13 goto err_nomem;
14 }
15
16 hw = spi_master_get_devdata(master);
17 memset(hw, 0, sizeof(struct s3c24xx_spi));
18
19 hw->master = spi_master_get(master);
20 hw->pdata = pdata = pdev->dev.platform_data;
21 hw->dev = &pdev->dev;
22
23 if (pdata == NULL) {
24 dev_err(&pdev->dev, "No platform data supplied\n");
25 err = -ENOENT;
26 goto err_no_pdata;
27 }
28
29 platform_set_drvdata(pdev, hw);
30 init_completion(&hw->done);
31
32 /* initialise fiq handler */
33
34 s3c24xx_spi_initfiq(hw);
35
36 /* setup the master state. */
37
38 /* the spi->mode bits understood by this driver: */
39 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
40
41 master->num_chipselect = hw->pdata->num_cs;
42 master->bus_num = pdata->bus_num;
43
44 /* setup the state for the bitbang driver */
45
46 hw->bitbang.master = hw->master;
47 hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
48 hw->bitbang.chipselect = s3c24xx_spi_chipsel;
49 hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;
50
51 hw->master->setup = s3c24xx_spi_setup;
52 hw->master->cleanup = s3c24xx_spi_cleanup;
53
54 dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
55
56 /* find and map our resources */
57
58 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
59 if (res == NULL) {
60 dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
61 err = -ENOENT;
62 goto err_no_iores;
63 }
64
65 hw->ioarea = request_mem_region(res->start, resource_size(res),
66 pdev->name);
67
68 if (hw->ioarea == NULL) {
69 dev_err(&pdev->dev, "Cannot reserve region\n");
70 err = -ENXIO;
71 goto err_no_iores;
72 }
73
74 hw->regs = ioremap(res->start, resource_size(res));
75 if (hw->regs == NULL) {
76 dev_err(&pdev->dev, "Cannot map IO\n");
77 err = -ENXIO;
78 goto err_no_iomap;
79 }
80
81 hw->irq = platform_get_irq(pdev, 0);
82 if (hw->irq < 0) {
83 dev_err(&pdev->dev, "No IRQ specified\n");
84 err = -ENOENT;
85 goto err_no_irq;
86 }
87
88 err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw);
89 if (err) {
90 dev_err(&pdev->dev, "Cannot claim IRQ\n");
91 goto err_no_irq;
92 }
93
94 hw->clk = clk_get(&pdev->dev, "spi");
95 if (IS_ERR(hw->clk)) {
96 dev_err(&pdev->dev, "No clock for device\n");
97 err = PTR_ERR(hw->clk);
98 goto err_no_clk;
99 }
100
101 /* setup any gpio we can */
102
103 if (!pdata->set_cs) {
104 if (pdata->pin_cs < 0) {
105 dev_err(&pdev->dev, "No chipselect pin\n");
106 err = -EINVAL;
107 goto err_register;
108 }
109
110 err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev));
111 if (err) {
112 dev_err(&pdev->dev, "Failed to get gpio for cs\n");
113 goto err_register;
114 }
115
116 hw->set_cs = s3c24xx_spi_gpiocs;
117 gpio_direction_output(pdata->pin_cs, 1);
118 } else
119 hw->set_cs = pdata->set_cs;
120
121 s3c24xx_spi_initialsetup(hw);
122
123 /* register our spi controller */
124
125 err = spi_bitbang_start(&hw->bitbang);//注册spi控制器,即spi_master
126 if (err) {
127 dev_err(&pdev->dev, "Failed to register SPI master\n");
128 goto err_register;
129 }
130
131 return 0;
132
133 err_register:
134 if (hw->set_cs == s3c24xx_spi_gpiocs)
135 gpio_free(pdata->pin_cs);
136
137 clk_disable(hw->clk);
138 clk_put(hw->clk);
139
140 err_no_clk:
141 free_irq(hw->irq, hw);
142
143 err_no_irq:
144 iounmap(hw->regs);
145
146 err_no_iomap:
147 release_resource(hw->ioarea);
148 kfree(hw->ioarea);
149
150 err_no_iores:
151 err_no_pdata:
152 spi_master_put(hw->master);
153
154 err_nomem:
155 return err;
156 }
4 注册spi控制器
1 int spi_bitbang_start(struct spi_bitbang *bitbang)
2 {
3 struct spi_master *master = bitbang->master;
4 int status;
5
6 if (!master || !bitbang->chipselect)
7 return -EINVAL;
8
9 INIT_WORK(&bitbang->work, bitbang_work);
10 spin_lock_init(&bitbang->lock);
11 INIT_LIST_HEAD(&bitbang->queue);
12
13 if (!master->mode_bits)
14 master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
15
16 if (!master->transfer)
17 master->transfer = spi_bitbang_transfer;
18 if (!bitbang->txrx_bufs) {
19 bitbang->use_dma = 0;
20 bitbang->txrx_bufs = spi_bitbang_bufs;
21 if (!master->setup) {
22 if (!bitbang->setup_transfer)
23 bitbang->setup_transfer =
24 spi_bitbang_setup_transfer;
25 master->setup = spi_bitbang_setup;
26 master->cleanup = spi_bitbang_cleanup;
27 }
28 } else if (!master->setup)
29 return -EINVAL;
30 if (master->transfer == spi_bitbang_transfer &&
31 !bitbang->setup_transfer)
32 return -EINVAL;
33
34 /* this task is the only thing to touch the SPI bits */
35 bitbang->busy = 0;
36 bitbang->workqueue = create_singlethread_workqueue(
37 dev_name(master->dev.parent));
38 if (bitbang->workqueue == NULL) {
39 status = -EBUSY;
40 goto err1;
41 }
42
43 /* driver may get busy before register() returns, especially
44 * if someone registered boardinfo for devices
45 */
46 status = spi_register_master(master);//注册spi控制器
47 if (status < 0)
48 goto err2;
49
50 return status;
51
52 err2:
53 destroy_workqueue(bitbang->workqueue);
54 err1:
55 return status;
56 }
4.2 spi_register_master
对应spi控制器,即spi主机,负责按照设定的物理信号格式在主控和spi设备之间交换数据,SPI控制器数据是如何被传输的,而不关心数据的内容。SPI通用接口层用spi_master结构来表示一个spi控制器。
1 struct spi_master {
2 struct device dev;
3
4 struct list_head list;//系统可能有多个控制器,用该链表链接在一个全局链表变量上
5
6 /* other than negative (== assign one dynamically), bus_num is fully
7 * board-specific. usually that simplifies to being SOC-specific.
8 * example: one SOC has three SPI controllers, numbered 0..2,
9 * and one board's schematics might show it using SPI-2. software
10 * would normally use bus_num=2 for that controller.
11 */
12 s16 bus_num;//控制器对应的spi总线编号,从0开始,通常由板级代码设定
13
14 /* chipselects will be integral to many controllers; some others
15 * might use board-specific GPIOs.
16 */
17 u16 num_chipselect;//连接到该spi控制器的片选信号的个数
18
19 /* some SPI controllers pose alignment requirements on DMAable
20 * buffers; let protocol drivers know about these requirements.
21 */
22 u16 dma_alignment;
23
24 /* spi_device.mode flags understood by this controller driver */
25 u16 mode_bits;//工作模式,由驱动解释该模式的意义
26
27 /* bitmask of supported bits_per_word for transfers */
28 u32 bits_per_word_mask;
29
30 /* other constraints relevant to this driver */
31 u16 flags;
32 #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */
33 #define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */
34 #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */
35
36 /* lock and mutex for SPI bus locking */
37 spinlock_t bus_lock_spinlock;
38 struct mutex bus_lock_mutex;
39
40 /* flag indicating that the SPI bus is locked for exclusive use */
41 bool bus_lock_flag;
42
43 /* Setup mode and clock, etc (spi driver may call many times).
44 *
45 * IMPORTANT: this may be called when transfers to another
46 * device are active. DO NOT UPDATE SHARED REGISTERS in ways
47 * which could break those transfers.
48 */
49 int (*setup)(struct spi_device *spi);//回调函数,用于设置某个spi设备在该控制器上的工作参数
50
51 /* bidirectional bulk transfers
52 *
53 * + The transfer() method may not sleep; its main role is
54 * just to add the message to the queue.
55 * + For now there's no remove-from-queue operation, or
56 * any other request management
57 * + To a given spi_device, message queueing is pure fifo
58 *
59 * + The master's main job is to process its message queue,
60 * selecting a chip then transferring data
61 * + If there are multiple spi_device children, the i/o queue
62 * arbitration algorithm is unspecified (round robin, fifo,
63 * priority, reservations, preemption, etc)
64 *
65 * + Chipselect stays active during the entire message
66 * (unless modified by spi_transfer.cs_change != 0).
67 * + The message transfers use clock and SPI mode parameters
68 * previously established by setup() for this device
69 */
70 int (*transfer)(struct spi_device *spi,//用于把包含数据信息的mesg结构加入控制器的消息链表中的回调函数
71 struct spi_message *mesg);
72
73 /* called on release() to free memory provided by spi_master */
74 void (*cleanup)(struct spi_device *spi);//当spi_master被释放时,该函数被调用
75
76 /*
77 * These hooks are for drivers that want to use the generic
78 * master transfer queueing mechanism. If these are used, the
79 * transfer() function above must NOT be specified by the driver.
80 * Over time we expect SPI drivers to be phased over to this API.
81 */
82 bool queued;
83 struct kthread_worker kworker;//用于管理数据传输消息队列的工作队列线程
84 struct task_struct *kworker_task;
85 struct kthread_work pump_messages;//具体实现数据传输队列的工作队列
86 spinlock_t queue_lock;
87 struct list_head queue;//控制器的消息队列,所有等待传输的消息队列挂在该链表下
88 struct spi_message *cur_msg;//正带处理的消息队列
89 bool busy;
90 bool running;
91 bool rt;
92
93 int (*prepare_transfer_hardware)(struct spi_master *master);//回调函数,正式发起传送前会被调用,用于准备硬件资源
94 int (*transfer_one_message)(struct spi_master *master,//单个消息的原子传送回调函数,队列中的每个消息都会调用一次该回调来完成传输工作
95 struct spi_message *mesg);
96 int (*unprepare_transfer_hardware)(struct spi_master *master);//清理回调函数
97 /* gpio chip select */
98 int *cs_gpios;//片选信号所用到的gpio
99 }
spi_master结构通常由控制器驱动定义,然后通过以下通用接口层的API注册到系统中:
1 int spi_register_master(struct spi_master *master)
2 {
3 static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
4 struct device *dev = master->dev.parent;
5 struct boardinfo *bi;
6 int status = -ENODEV;
7 int dynamic = 0;
8
9 if (!dev)
10 return -ENODEV;
11
12 status = of_spi_register_master(master);
13 if (status)
14 return status;
15
16 /* even if it's just one always-selected device, there must
17 * be at least one chipselect
18 */
19 if (master->num_chipselect == 0)
20 return -EINVAL;
21
22 if ((master->bus_num < 0) && master->dev.of_node)
23 master->bus_num = of_alias_get_id(master->dev.of_node, "spi");
24
25 /* convention: dynamically assigned bus IDs count down from the max */
26 if (master->bus_num < 0) {
27 /* FIXME switch to an IDR based scheme, something like
28 * I2C now uses, so we can't run out of "dynamic" IDs
29 */
30 master->bus_num = atomic_dec_return(&dyn_bus_id);
31 dynamic = 1;
32 }
33
34 spin_lock_init(&master->bus_lock_spinlock);
35 mutex_init(&master->bus_lock_mutex);
36 master->bus_lock_flag = 0;
37
38 /* register the device, then userspace will see it.
39 * registration fails if the bus ID is in use.
40 */
41 dev_set_name(&master->dev, "spi%u", master->bus_num);
42 status = device_add(&master->dev);//添加spi主机设备(master->dev),spi_device是挂在这个下面,即spi_device的父设备
43 if (status < 0)
44 goto done;
45 dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev),
46 dynamic ? " (dynamic)" : "");
47
48 /* If we're using a queued driver, start the queue */
49 if (master->transfer)
50 dev_info(dev, "master is unqueued, this is deprecated\n");
51 else {
52 status = spi_master_initialize_queue(master);
53 if (status) {
54 device_unregister(&master->dev);
55 goto done;
56 }
57 }
58
59 mutex_lock(&board_lock);
60 list_add_tail(&master->list, &spi_master_list);
61 list_for_each_entry(bi, &board_list, list)
62 spi_match_master_to_boardinfo(master, &bi->board_info);//匹配spi主机和spi板机设备,建立spi_device。
63 mutex_unlock(&board_lock);
64
65 /* Register devices from the device tree and ACPI */
66 of_register_spi_devices(master);//设备树匹配操作这个待分析???
67 acpi_register_spi_devices(master);
68 done:
69 return status;
70 }
然后调用spi_match_master_to_boardinfo
1 static void spi_match_master_to_boardinfo(struct spi_master *master,
2 struct spi_board_info *bi)
3 {
4 struct spi_device *dev;
5
6 if (master->bus_num != bi->bus_num)
7 return;
8
9 dev = spi_new_device(master, bi);//注册spi_device
10 if (!dev)
11 dev_err(master->dev.parent, "can't create new device for %s\n",
12 bi->modalias);
13 }
4.3 设备树匹配操作
1 /**
2 * of_register_spi_devices() - Register child devices onto the SPI bus
3 * @master: Pointer to spi_master device
4 *
5 * Registers an spi_device for each child node of master node which has a 'reg'
6 * property.
7 */
8 static void of_register_spi_devices(struct spi_master *master)
9 {
10 struct spi_device *spi;
11 struct device_node *nc;
12 const __be32 *prop;
13 char modalias[SPI_NAME_SIZE + 4];
14 int rc;
15 int len;
16
17 if (!master->dev.of_node)
18 return;
19
20 for_each_available_child_of_node(master->dev.of_node, nc) {
21 /* Alloc an spi_device */
22 spi = spi_alloc_device(master);
23 if (!spi) {
24 dev_err(&master->dev, "spi_device alloc error for %s\n",
25 nc->full_name);
26 spi_dev_put(spi);
27 continue;
28 }
29
30 /* Select device driver */
31 if (of_modalias_node(nc, spi->modalias,
32 sizeof(spi->modalias)) < 0) {
33 dev_err(&master->dev, "cannot find modalias for %s\n",
34 nc->full_name);
35 spi_dev_put(spi);
36 continue;
37 }
38
39 /* Device address */
40 prop = of_get_property(nc, "reg", &len);
41 if (!prop || len < sizeof(*prop)) {
42 dev_err(&master->dev, "%s has no 'reg' property\n",
43 nc->full_name);
44 spi_dev_put(spi);
45 continue;
46 }
47 spi->chip_select = be32_to_cpup(prop);
48
49 /* Mode (clock phase/polarity/etc.) */
50 if (of_find_property(nc, "spi-cpha", NULL))
51 spi->mode |= SPI_CPHA;
52 if (of_find_property(nc, "spi-cpol", NULL))
53 spi->mode |= SPI_CPOL;
54 if (of_find_property(nc, "spi-cs-high", NULL))
55 spi->mode |= SPI_CS_HIGH;
56 if (of_find_property(nc, "spi-3wire", NULL))
57 spi->mode |= SPI_3WIRE;
58
59 /* Device speed */
60 prop = of_get_property(nc, "spi-max-frequency", &len);
61 if (!prop || len < sizeof(*prop)) {
62 dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n",
63 nc->full_name);
64 spi_dev_put(spi);
65 continue;
66 }
67 spi->max_speed_hz = be32_to_cpup(prop);
68
69 /* IRQ */
70 spi->irq = irq_of_parse_and_map(nc, 0);
71
72 /* Store a pointer to the node in the device structure */
73 of_node_get(nc);
74 spi->dev.of_node = nc;
75
76 /* Register the new device */
77 snprintf(modalias, sizeof(modalias), "%s%s", SPI_MODULE_PREFIX,
78 spi->modalias);
79 request_module(modalias);
80 rc = spi_add_device(spi);
81 if (rc) {
82 dev_err(&master->dev, "spi_device register error %s\n",
83 nc->full_name);
84 spi_dev_put(spi);
85 }
86
87 }
88 }
5 spi_device的注册建立
当spi主机和spi板机设备匹配时调用spi_new_device 注册spi设备。详见: linux设备驱动SPI详解2-通用接口层 , 将spi_device添加到spi_bus上。所以对于spi来说,spi控制器是挂在platform虚拟总线上,但spi同时又有自己的bus,bus下有spi_device和spi_driver。
(追寻spi_init也就是spi_bus)
6 实现spi_master中的回调函数
事实上,SPI控制器驱动程序的主要工作,就是要实现spi_master结构中的几个回调函数,其它的工作逻辑,均由通用接口层帮我们完成,通用接口层会在适当的时机调用这几个回调函数,各个回调函数的作用如下,具体的实现例子位于:drivers\spi\Spi-s3c24xx.c
int (*setup)(struct spi_device *spi)
当协议驱动希望修改控制器的工作模式或参数时,会调用通用接口层提供的API:spi_setup(),该API函数最后会调用setup回调函数来完成设置工作。
int (*transfer)(struct spi_device *spi, struct spi_message *mesg)
目前已经可以不用我们自己实现该回调函数,初始化时直接设为NULL即可,目前的通用接口层已经实现了消息队列化,注册spi_master时,通用接口层会提供实现好的通用函数。现在只有一些老的驱动还在使用该回调方式,新的驱动应该停止使用该回调函数,而是应该使用队列化的transfer_one_message回调。需要注意的是,我们只能选择其中一种方式,设置了transfer_one_message回调,就不能设置transfer回调,反之亦然。
void (*cleanup)(struct spi_device *spi)
当一个SPI从设备(spi_device结构)被释放时,该回调函数会被调用,以便释放该从设备所占用的硬件资源。
int (*prepare_transfer_hardware)(struct spi_master *master)
int (*unprepare_transfer_hardware)(struct spi_master *master)
这两个回调函数用于在发起一个数据传送过程前和后,给控制器驱动一个机会,申请或释放某些必要的硬件资源,例如DMA资源和内存资源等等。int (*transfer_one_message)(struct spi_master *master, struct spi_message *mesg)
当通用接口层发现master的队列中有消息需要传送时,会调用该回调函数,所以该函数是真正完成一个消息传送的工作函数,当传送工作完成时,应该调用spi_finalize_current_message函数,以便通知通用接口层,发起队列中的下一个消息的传送工作。
6.1 spi_master中transfer 回调函数
transfer回调函数的定义flow如下:
s3c24xx_spi_probe()
1 static int s3c24xx_spi_probe(struct platform_device *pdev)
2 {
3 ...
4
5 /* register our spi controller */
6
7 err = spi_bitbang_start(&hw->bitbang);
8 if (err) {
9 dev_err(&pdev->dev, "Failed to register SPI master\n");
10 goto err_register;
11 }
12 ...
13 }
函数:spi_bitbang_start,定义位于:drivers\spi\spi-bitbang.c
1 int spi_bitbang_start(struct spi_bitbang *bitbang)
2 {
3 struct spi_master *master = bitbang->master;
4 int status;
5
6 if (!master || !bitbang->chipselect)
7 return -EINVAL;
8
9 INIT_WORK(&bitbang->work, bitbang_work);
10 spin_lock_init(&bitbang->lock);
11 INIT_LIST_HEAD(&bitbang->queue);
12
13 if (!master->mode_bits)
14 master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
15
16 if (!master->transfer)//判断master中transfer回调函数是否存在,s3c24xx_spi_probe函数中没有为其赋值定义
17 master->transfer = spi_bitbang_transfer;回调函数tranfer赋值
...
}
tranfer回调函数定义:
1 /**
2 * spi_bitbang_transfer - default submit to transfer queue
3 */
4 int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
5 {
6 struct spi_bitbang *bitbang;
7 unsigned long flags;
8 int status = 0;
9
10 m->actual_length = 0;
11 m->status = -EINPROGRESS;
12
13 bitbang = spi_master_get_devdata(spi->master);
14
15 spin_lock_irqsave(&bitbang->lock, flags);
16 if (!spi->max_speed_hz)
17 status = -ENETDOWN;
18 else {
19 list_add_tail(&m->queue, &bitbang->queue);
20 queue_work(bitbang->workqueue, &bitbang->work);
21 }
22 spin_unlock_irqrestore(&bitbang->lock, flags);
23
24 return status;
25 }
行胜于言,自强不息。