SPI总线(三):驱动实例

 

相关文章:

                 SPI总线(一):基本原理篇

                 SPI总线(二):驱动分析篇 

平台:firefly-rk3399

详细配置参照:http://www.t-firefly.com/doc/product/info/id/92.html#SPI.E5.B7.A5.E4.BD.9C.E6.96.B9.E5.BC.8F

/*
 * Driver for pwm demo on Firefly board.
 *
 * Copyright (C) 2016, Zhongshan T-chip Intelligent Technology Co.,ltd.
 * Copyright 2006  Sam Chan
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#define DEBUG
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define FIREFLY_SPI_READ_ID_CMD 0x9F

#define FIREFLY_SPI_PRINT_ID(rbuf) \
	do { \
		if (status == 0) \
			dev_dbg(&spi->dev, "%s: ID = %02x %02x %02x %02x %02x\n", __FUNCTION__, \
				rbuf[0], rbuf[1], rbuf[2], rbuf[3], rbuf[4]); \
		else \
			dev_err(&spi->dev, "%s: read ID error\n", __FUNCTION__); \
	}while(0)

static int firefly_spi_read_w25x_id_0(struct spi_device *spi)
{	
	int	status;
	char tbuf[]={FIREFLY_SPI_READ_ID_CMD};
	char rbuf[5];

	struct spi_transfer	t = {
		.tx_buf		= tbuf,
		.len		= sizeof(tbuf),
	};

	struct spi_transfer     r = {
		.rx_buf         = rbuf,
		.len            = sizeof(rbuf),
	};
	struct spi_message      m;

	spi_message_init(&m);
	spi_message_add_tail(&t, &m);
	spi_message_add_tail(&r, &m);
	status = spi_sync(spi, &m);

	FIREFLY_SPI_PRINT_ID(rbuf);
	return status;
}


static int firefly_spi_read_w25x_id_1(struct spi_device *spi)
{
	int	status;
	char tbuf[] = {FIREFLY_SPI_READ_ID_CMD};
	char rbuf[5];

	status = spi_write_then_read(spi, tbuf, sizeof(tbuf), rbuf, sizeof(rbuf));
	
	FIREFLY_SPI_PRINT_ID(rbuf);
	return status;
}

static int firefly_spi_probe(struct spi_device *spi)
{
    int ret = 0;
    struct device_node __maybe_unused *np = spi->dev.of_node;

    dev_dbg(&spi->dev, "Firefly SPI demo program\n");

	if(!spi)	
		return -ENOMEM;

	dev_dbg(&spi->dev, "firefly_spi_probe: setup mode %d, %s%s%s%s%u bits/w, %u Hz max\n",
			(int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
			(spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
			(spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
			(spi->mode & SPI_3WIRE) ? "3wire, " : "",
			(spi->mode & SPI_LOOP) ? "loopback, " : "",
			spi->bits_per_word, spi->max_speed_hz);

	firefly_spi_read_w25x_id_0(spi);
	firefly_spi_read_w25x_id_1(spi);
	
    return ret;
}

static struct of_device_id firefly_match_table[] = {
	{ .compatible = "firefly,rk3399-spi",},
	{},
};

static struct spi_driver firefly_spi_driver = {
	.driver = {
		.name = "firefly-spi",
		.owner = THIS_MODULE,
		.of_match_table = firefly_match_table,
	},
	.probe = firefly_spi_probe,
};

static int firefly_spi_init(void)
{
	return spi_register_driver(&firefly_spi_driver);
}
module_init(firefly_spi_init);

static void firefly_spi_exit(void)
{
	spi_unregister_driver(&firefly_spi_driver);
}
module_exit(firefly_spi_exit);


MODULE_DESCRIPTION("Firefly SPI demo driver");
MODULE_ALIAS("platform:firefly-spi");
MODULE_LICENSE("GPL");

 

此驱动只是实现简单的读取设备的ID,然后打印出来,并没有实现API接口

 

 

firefly_spi_probe中使用了两种接口操作读取W25Q128FV的ID:
firefly_spi_read_w25x_id_0接口直接使用了spi_transfer和spi_message来传送数据。
firefly_spi_read_w25x_id_1接口则使用SPI接口spi_write_then_read来读写数据。

编写spi驱动时,读写设备科参照此驱动,添加spi的API接口。

 

 

 

你可能感兴趣的:(linux)