SPI总线(三):驱动实例

相关文章:

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

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

平台:firefly-rk3399

详细配置参照:Firefly | 让科技更简单,让生活更智能

/*
 * 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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>

#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接口。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kevin@1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值