双11狂欢大促

盲盒赢 定制羽绒服

开启惊喜盲盒,抽取你的专属好礼

— 惊喜奖品抢先看 —

xilinx zynq7000, ad9361与spi驱动移植问题

心上枫叶红 心上枫叶红 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
各位大神请教一下。我用的是xilinux zynq7000的板子。我现在,需要移植SPI驱动和ADI的AD9361驱动进去。添加spidev.c驱动执行到init函数之后probe函数就没执行了。在/sys/bus/spi/drivers目录下有spidev驱动。但是/dev目录下一直没有设备文件。而且ad9361编译之后在报错好像就是因为是spi驱动的问题。我想知道这是怎么回事?谢谢
spidev.c的部分驱动
static int spidev_probe(struct spi_device *spi)
{
printk("========================enter spi0_probe======================\n");
struct spidev_data *spidev;
int status;
unsigned long minor;

/*
* spidev should never be referenced in DT without a specific
* compatible string, it is a Linux implementation thing
* rather than a description of the hardware.
*/
if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) {
dev_err(&spi->dev, "buggy DT: spidev listed directly in DT\n");
WARN_ON(spi->dev.of_node &&
!of_match_device(spidev_dt_ids, &spi->dev));
}



/* Allocate driver data */
spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
if (!spidev)
return -ENOMEM;

/* Initialize the driver data */
spidev->spi = spi;
spin_lock_init(&spidev->spi_lock);
mutex_init(&spidev->buf_lock);

INIT_LIST_HEAD(&spidev->device_entry);

/* If we can allocate a minor number, hook up this device.
* Reusing minors is fine so long as udev or mdev is working.
*/
mutex_lock(&device_list_lock);
minor = find_first_zero_bit(minors, N_SPI_MINORS);
if (minor < N_SPI_MINORS) {
struct device *dev;

spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
dev = device_create(spidev_class, &spi->dev, spidev->devt,
spidev, "spidev%d.%d",
spi->master->bus_num, spi->chip_select);
status = PTR_ERR_OR_ZERO(dev);
} else {
dev_dbg(&spi->dev, "no minor number available!\n");
status = -ENODEV;
}
if (status == 0) {
set_bit(minor, minors);
list_add(&spidev->device_entry, &device_list);
}
mutex_unlock(&device_list_lock);

spidev->speed_hz = spi->max_speed_hz;

if (status == 0)
spi_set_drvdata(spi, spidev);
else
kfree(spidev);

return status;
}

static int spidev_remove(struct spi_device *spi)
{
struct spidev_data *spidev = spi_get_drvdata(spi);
printk("========================enter spi remove======================\n");
/* make sure ops on existing fds can abort cleanly */
spin_lock_irq(&spidev->spi_lock);
spidev->spi = NULL;
spin_unlock_irq(&spidev->spi_lock);

/* prevent new opens */
mutex_lock(&device_list_lock);
list_del(&spidev->device_entry);
device_destroy(spidev_class, spidev->devt);
clear_bit(MINOR(spidev->devt), minors);
if (spidev->users == 0)
kfree(spidev);
mutex_unlock(&device_list_lock);

return 0;
}

static struct spi_driver spidev_spi_driver = {
.driver = {
.name = "spidev",
.of_match_table = of_match_ptr(spidev_dt_ids),
},
.probe = spidev_probe,
.remove = spidev_remove,
/* NOTE: suspend/resume methods are not necessary here.
* We don't do anything except pass the requests to/from
* the underlying controller. The refrigerator handles
* most issues; the controller driver handles the rest.
*/
};

/*-------------------------------------------------------------------------*/

static int __init spidev_init(void)
{
int status;

/* Claim our 256 reserved device numbers. Then register a class
* that will key udev/mdev to add/remove /dev nodes. Last, register
* the driver which manages those device numbers.
*/
BUILD_BUG_ON(N_SPI_MINORS > 256);
status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
if (status < 0)
return status;

spidev_class = class_create(THIS_MODULE, "spidev");
if (IS_ERR(spidev_class)) {
unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
return PTR_ERR(spidev_class);
}
status = spi_register_driver(&spidev_spi_driver);
if (status < 0) {
class_destroy(spidev_class);
unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
}
printk("==============:%d:==========spi0_init out ======================\n",status);
return status;
}
module_init(spidev_init);
内核打印信息::
bootconsole [earlycon0] disabled
bootconsole [earlycon0] disabled
xdevcfg f8007000.devcfg: ioremap 0xf8007000 to f08b0000
[drm] Initialized drm 1.1.0 20060810
brd: module loaded
loop: module loaded
==============:0:==========spi0_init out ======================
m25p80 spi0.0: SPI-NOR-UniqueID 0000000000000000000000000000000000
m25p80 spi0.0: m25p80 (2048 Kbytes)
4 ofpart partitions found on MTD device spi0.0
Creating 4 MTD partitions on "spi0.0":
0x000000000000-0x000000500000 : "boot"
mtd: partition "boot" extends beyond the end of device "spi0.0" -- size truncated to 0x200000
0x000000500000-0x000000520000 : "bootenv"
mtd: partition "bootenv" is out of reach -- disabled
0x000000520000-0x000000fa0000 : "kernel"
mtd: partition "kernel" is out of reach -- disabled
0x000000fa0000-0x000000200000 : "spare"
mtd: partition "spare" is out of reach -- disabled
CAN device driver interface
libphy: MACB_mii_bus: probed
macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 146 (00:0a:35:00:1e:53)
Generic PHY e000b000.etherne:00: attached PHY driver [Generic PHY] (mii_bus:phy_addr=e000b000.etherne:00, irq=-1)
e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
usbcore: registered new interface driver usb-storage
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
EDAC MC: ECC not enabled
Xilinx Zynq CpuIdle Driver started
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
mmc0: SDHCI controller on e0101000.sdhci [e0101000.sdhci] using ADMA
ledtrig-cpu: registered to indicate activity on CPUs
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
ad9361 spi32766.0: ad9361_probe : enter (ad9361)
ad9361 spi32766.0: ---------------gpio:0--------------------------!
ad9361 spi32766.0: --------------------------1----------------!
ad9361 spi32766.0: SPI transfer timed out
ad9361 spi32766.0: Write Error -110
ad9361 spi32766.0: SPI transfer timed out
ad9361 spi32766.0: Write Error -110
ad9361 spi32766.0: ad9361_reset: by SPI, this may cause unpredicted behavior!
ad9361 spi32766.0: SPI transfer timed out
ad9361 spi32766.0: Read Error -110
ad9361 spi32766.0: ad9361_probe : Unsupported PRODUCT_ID 0xFFFFFF92
NET: Registered protocol family 10
sit: IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
can: controller area network core (rev 20120528 abi 9)
NET: Registered protocol family 29
can: raw protocol (rev 20120528)
can: broadcast manager protocol (rev 20120528 t)
can: netlink gateway (rev 20130117) max_hops=1
zynq_pm_remap_ocm: OCM pool is not available
zynq_pm_suspend_init: Unable to map OCM.
Registering SWP/SWPB emulation handler
hctosys: unable to open rtc device (rtc0)

这里ad9361的部分驱动代码:
static int ad9361_reset(struct ad9361_rf_phy *phy)
{

dev_err(&phy->spi->dev, " ---------------gpio:%d--------------------------!\n",phy->pdata->reset_gpio);
if (phy->pdata->reset_gpio) {
dev_err(&phy->spi->dev, " --------------------------in----------------!\n");
gpiod_set_value(phy->pdata->reset_gpio, 0);
mdelay(1);
gpiod_set_value(phy->pdata->reset_gpio, 1);
mdelay(1);
dev_dbg(&phy->spi->dev, "%s: by GPIO", __func__);
return 0;
}
dev_err(&phy->spi->dev, " --------------------------1----------------!\n");

/* SPI Soft Reset was removed from the register map, since it doesn't
* work reliably. Without a prober HW reset randomness may happen.
* Please specify a RESET GPIO.
*/

ad9361_spi_write(phy->spi, REG_SPI_CONF, SOFT_RESET | _SOFT_RESET);
ad9361_spi_write(phy->spi, REG_SPI_CONF, 0x0);
dev_err(&phy->spi->dev,
"%s: by SPI, this may cause unpredicted behavior!", __func__);

return -ENODEV;
}

static int ad9361_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct ad9361_rf_phy *phy;
struct clk *clk = NULL;
int ret, rev;

dev_info(&spi->dev, "%s : enter (%s)", __func__,
spi_get_device_id(spi)->name);

clk = devm_clk_get(&spi->dev, NULL);
if (IS_ERR(clk)) {
return -EPROBE_DEFER;
}

indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*phy));
if (indio_dev == NULL)
return -ENOMEM;

phy = iio_priv(indio_dev);
phy->indio_dev = indio_dev;
phy->spi = spi;
phy->clk_refin = clk;

phy->pdata = ad9361_phy_parse_dt(indio_dev, &spi->dev);
if (phy->pdata == NULL)
return -EINVAL;

phy->pdata->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
GPIOD_OUT_HIGH);


if (IS_ERR(phy->pdata->reset_gpio))
return PTR_ERR(phy->pdata->reset_gpio);

/* Optional: next three used for MCS synchronization */
phy->pdata->sync_gpio = devm_gpiod_get_optional(&spi->dev, "sync",
GPIOD_OUT_LOW);
if (IS_ERR(phy->pdata->sync_gpio))
return PTR_ERR(phy->pdata->sync_gpio);

phy->pdata->cal_sw1_gpio = devm_gpiod_get_optional(&spi->dev, "cal-sw1",
GPIOD_OUT_LOW);
if (IS_ERR(phy->pdata->cal_sw1_gpio))
return PTR_ERR(phy->pdata->cal_sw1_gpio);

phy->pdata->cal_sw2_gpio = devm_gpiod_get_optional(&spi->dev, "cal-sw2",
GPIOD_OUT_LOW);
if (IS_ERR(phy->pdata->cal_sw2_gpio))
return PTR_ERR(phy->pdata->cal_sw2_gpio);


phy->current_table = -1;
phy->bypass_tx_fir = true;
phy->bypass_rx_fir = true;
phy->rate_governor = 1;
phy->rfdc_track_en = true;
phy->bbdc_track_en = true;
phy->quad_track_en = true;

phy->gt_info = ad9361_adi_gt_info;

ad9361_request_gt(phy, NULL);

ad9361_reset(phy);


ret = ad9361_spi_read(spi, REG_PRODUCT_ID);
if ((ret & PRODUCT_ID_MASK) != PRODUCT_ID_9361) {
dev_err(&spi->dev, "%s : Unsupported PRODUCT_ID 0x%X",
__func__, ret);
return -ENODEV;

}

rev = ret & REV_MASK;

if (spi_get_device_id(spi)->driver_data == ID_AD9364) {
phy->pdata->rx2tx2 = false;
phy->pdata->rx1tx1_mode_use_rx_num = 1;
phy->pdata->rx1tx1_mode_use_tx_num = 1;
}
.....................................
...全文

相关推荐

研究生组会汇报模板 (1).pptx

研究生组会汇报模板 (1).pptx

weixin_43587816

【飞机能量-机动性(E-M)特性】飞机评估的最大转弯速度(即机动速度)、最大可持续转弯速度和最大可持续载荷系数对应的真空速度(Matlab代码实现)

内容概要:本文详细阐述了利用Matlab代码实现飞机能量-机动性(E-M)特性分析的方法,重点评估飞机的最大转弯速度(即机动速度)、最大可持续转弯速度以及最大可持续载荷系数所对应的真空速度。该方法基于飞行力学与空气动力学理论,构建飞机性能模型,计算不同飞行状态下飞机的转弯性能极限,进而提取关键机动性指标。文中提供的Matlab代码支持数据可视化与性能包线绘制,能够直观展现飞机在多种高度和速度条件下的机动能力边界,适用于飞机性能包线的快速生成与分析。; 适合人群:具备航空工程、飞行器设计或飞行力学等相关专业知识背景,从事飞机总体设计、飞行性能评估、空战战术研究或飞行仿真的科研人员及高校研究生。; 使用场景及目标:①用于飞机概念设计与初步设计阶段的机动性能评估与方案比选;②支撑飞行模拟器中机动包线的建模与验证;③为空战战术仿真提供飞机机动能力边界数据;④辅助飞行员培训中对飞机操纵极限的理解; 阅读建议:建议读者结合经典飞行力学教材深入理解E-M图的物理内涵,运行并调试所提供的Matlab代码,掌握各气动参数与飞行状态对机动性的影响规律,进一步可拓展至多机型对比分析、作战效能评估或多约束条件下的飞行性能优化研究。

荔枝科研社

政府科技管理者在推动科技成果转化时,如何解决技术成果难以匹配产业需求的问题?.docx

政府科技管理者在推动科技成果转化时,如何解决技术成果难以匹配产业需求的问题?

BIZKEEN

高校技术转移办公室人员如何提升成果推介效率?.docx

高校技术转移办公室人员如何提升成果推介效率?

BIZKEEN

U盘烧录rufus下载

U盘烧录rufus下载

weixin_49897572
评论 11
收藏 已收藏
分享
返回顶部