linux内核SPI总线驱动(二)

上一节讲到了spi_register_master注册SPI控制器驱动

这一节描述调用spi_register_driver注册spi_driver,通过与device匹配驱动设备。

 

使用m25p10a举例

 

 

spi_register_driver功能跟名称一样

 

根据传入的spi_device参数,可以找到对应的spi_master。接下来就可以利用spi子系统为我们完成数据交互了。

 

定义了prob函数在prob里向上提供接口即可

 

 

spi_device端

struct spi_board_info {

       /* the device name and module name are coupled, like platform_bus;

        * "modalias" is normally the driver name.

        *

        * platform_data goes to spi_device.dev.platform_data,

        * controller_data goes to spi_device.controller_data,

        * irq is copied too

        */

       char        modalias[SPI_NAME_SIZE];

       const void      *platform_data;

       void        *controller_data;

       int          irq;

 

       /* slower signaling on noisy or low voltage boards */

       u32         max_speed_hz;

 

 

       /* bus_num is board specific and matches the bus_num of some

        * spi_master that will probably be registered later.

        *

        * chip_select reflects how this chip is wired to that master;

        * it's less than num_chipselect.

        */

       u16         bus_num;

       u16         chip_select;

 

       /* mode becomes spi_device.mode, and is essential for chips

        * where the default of SPI_CS_HIGH = 0 is wrong.

        */

       u8          mode;

 

       /* ... may need additional spi_device chip config data here.

        * avoid stuff protocol drivers can set; but include stuff

        * needed to behave without being bound to a driver:

        *  - quirks like clock rate mattering when not selected

        */

}

描述一个设备

 

/**

 * spi_busnum_to_master - look up master associated with bus_num

 * @bus_num: the master's bus number

 * Context: can sleep

 *

 * This call may be used with devices that are registered after

 * arch init time.  It returns a refcounted pointer to the relevant

 * spi_master (which the caller must release), or NULL if there is

 * no such master registered.

 */

struct spi_master *spi_busnum_to_master(u16 bus_num)

{

       struct device         *dev;

       struct spi_master   *master = NULL;

 

       dev = class_find_device(&spi_master_class, NULL, &bus_num,

                            __spi_master_match);

       if (dev)

              master = container_of(dev, struct spi_master, dev);

       /* reference got in class_find_device */

       return master;

}

获取spi控制器

 

/**

 * spi_new_device - instantiate one new SPI device

 * @master: Controller to which device is connected

 * @chip: Describes the SPI device

 * Context: can sleep

 *

 * On typical mainboards, this is purely internal; and it's not needed

 * after board init creates the hard-wired devices.  Some development

 * platforms may not be able to use spi_register_board_info though, and

 * this is exported so that for example a USB or parport based adapter

 * driver could add devices (which it would learn about out-of-band).

 *

 * Returns the new device, or NULL.

 */

struct spi_device *spi_new_device(struct spi_master *master,

                              struct spi_board_info *chip)

{

       struct spi_device    *proxy;

       int                 status;

 

       /* NOTE:  caller did any chip->bus_num checks necessary.

        *

        * Also, unless we change the return value convention to use

        * error-or-pointer (not NULL-or-pointer), troubleshootability

        * suggests syslogged diagnostics are best here (ugh).

        */

 

       proxy = spi_alloc_device(master);

       if (!proxy)

              return NULL;

 

       WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));

 

       proxy->chip_select = chip->chip_select;

       proxy->max_speed_hz = chip->max_speed_hz;

       proxy->mode = chip->mode;

       proxy->irq = chip->irq;

       strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));

       proxy->dev.platform_data = (void *) chip->platform_data;

       proxy->controller_data = chip->controller_data;

       proxy->controller_state = NULL;

 

       status = spi_add_device(proxy);

       if (status < 0) {

              spi_dev_put(proxy);

              return NULL;

       }

 

       return proxy;

}

注册设备

 

设备端的流程也一样简单,等着下周总结一下啦,88

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值