Look at how this is done in drivers/mmc/host/mmc_spi.c

Regards,
John




> On Mar 18, 2016, at 6:53 AM, 'ilikepepsi' via BeagleBoard 
> <beagleboard@googlegroups.com> wrote:
> 
> Hi,
> 
> I'm developing a kernel module that is supposed to communicate with a TI 
> ADS1274 ADC via SPI. So far I have a working kernel module that doesn't use 
> DMA for the SPI communication. Therefore the CPU get's a hell of a load and I 
> need to fix that. The way to do it presumably is using DMA but that's where 
> the struggle starts. At first I delved into the SPI interface structures 
> struct spi_device and struct spi_master. From the device tree (am33xx.dtsi 
> <http://lxr.free-electrons.com/source/arch/arm/boot/dts/am33xx.dtsi#L510>) I 
> know that the SPI controller has 2 DMA channels assigned for each CS, namely 
> 'tx0', 'rx0', 'tx1' and 'rx1'.
> 
> I thought these can be used through the struct dma_chan pointers in struct 
> spi_master but the pointers are null (I tried to print out their values 
> within my probing function). The respective dmesg output is.
> 
> [  +0.000010] DEBUG /root/Code/kmod/selton.c:970: ads_spi_probe: spi m rx:   
> (null)
> [  +0.000008] DEBUG /root/Code/kmod/selton.c:971: ads_spi_probe: spi m tx:   
> (null)
> 
> As a next step I tried to figure out how these pointers could get initialized 
> and found that in the TI driver omap2_mcspi.c a function 
> omap2_mcspi_request_dma( struct spi_device *spi) 
> <http://lxr.free-electrons.com/source/drivers/spi/spi-omap2-mcspi.c#L962> is 
> defined and called by omap2_mcspi_setup( struct spi_device *spi) 
> <http://lxr.free-electrons.com/source/drivers/spi/spi-omap2-mcspi.c#L1006>. 
> The latter is assigned to the setup function of the struct spi_master 
> allocated in the drivers probe function omap2_mcspi_probe( struct 
> platform_device *pdev) 
> <http://lxr.free-electrons.com/source/drivers/spi/spi-omap2-mcspi.c#L1353>.
> 
> So I thought everything left to do is calling the SPI masters setup function 
> (what seems to be done in spi_setup( struct spi_device *spi) 
> <http://lxr.free-electrons.com/source/drivers/spi/spi.c#L2057>) to make the 
> DMA channels accessible but they still remain as null pointers. Here is my 
> probe function.
> 
> 
> static int
> ads_spi_probe(struct spi_device *spi)
> {
>     ads_data_t  *ads; //--> driver data struct
>     int         err = 0;
>     
>     /* Is there a matching device in the device tree? */
>     if (!of_match_device(ads1274_dt_ids, &spi->dev)) {
>         err = -ENODEV;
>         goto error;
>     }
>     debug("Probed compat. devices: %s", //--> .compatible = "ti,ads1274",
>             ads1274_dt_ids[0].compatible);
> 
>     /* Then allocate the driver data */
>     ads = (ads_data_t *)kzalloc(sizeof(ads_data_t), GFP_KERNEL);
>     if (IS_ERR(ads)) {
>         err = PTR_ERR(ads);
>         debug("Could not allocate driver data: ERR %d", err);
>         goto error;
>     }
>     debug("Initialized SPI data structure at %p", ads);
> 
>     init_waitqueue_head(&ads->wait_read);
>     spin_lock_init(&ads->spi_lock);
>     
>     INIT_LIST_HEAD(&device_list);
>     mutex_lock(&device_list_lock);
>     
>     /* Request and configure GPIO trigger */
>     err = ads_gpio_init(&ads->gpio, p9, true, true);
>     if (err < 0) {
>         pr_err("%s: Could not initialze GPIO %d", MODNAME, p9);
>         goto free_driver_data;
>     }
>     debug("GPIO pin %d mapped to irq %d", 
>             ads->gpio.pin, ads->gpio.irq_number);
> 
>     /* Request 1 minor device number from the kernel */
>     if (alloc_chrdev_region(&ads->devt, 0, 1, MODNAME) < 0) {
>         err = -EIO;
>         goto free_workqueue;
>     }
>     debug("Requested major/minor %d : %d", MAJOR(ads->devt), 
> MINOR(ads->devt));
>     
>     /* SPI setup */
>     ads->spi = spi;
>     spi_set_drvdata(spi, ads);
>     spi_setup(ads->spi); //--> should init dma channels
>     
>     debug("spi: %p", ads->spi);
>     debug("spi m: %p", ads->spi->master);
>     debug("spi m rx: %p", ads->spi->master->dma_rx); //--> NULL
>     debug("spi m tx: %p", ads->spi->master->dma_tx); //--> NULL
> 
>     /* Create character device */
>     ads->cdev = cdev_alloc();
> 
>     if (ads->cdev == NULL)
>         goto free_chrdev_region;
>         
>     debug("Cdev initialized");
>     
>     ads->cdev->owner = THIS_MODULE;
>     ads->cdev->ops = &fops;
> 
>     if (cdev_add(ads->cdev, ads->devt, 1))
>         goto free_cdev;
> 
>     device_create(ads_class, &ads->spi->dev, ads->devt, ads->spi,
>             "ads1274-spi%d.%d", ads->spi->master->bus_num, 
> ads->spi->chip_select);
>    
>     list_add_tail(&(ads->device_entry), &device_list);
>     mutex_unlock(&device_list_lock);
> 
>     pr_info("%s: Added SPI device %s-spi%d.%d", MODNAME, spi->modalias,
>         spi->master->bus_num, spi->chip_select);
>     
>     /* Should be 0 */
>     return err;    
> 
> free_cdev:
>     kobject_put(&(ads->cdev->kobj));
> free_chrdev_region:
>     unregister_chrdev_region(ads->devt, 1);
> free_workqueue:
> //    ads_workqueue_free(&ads);
> //free_gpio:
>     ads_gpio_free(&(ads->gpio));
> free_driver_data:
>     kfree(ads);
>     debug("There was an error while probing devices");
> 
> error:
>     return err;
> }
> 
> So can anybody tell me how to initialize the DMA channels in spi_master or 
> how to use SPI with DMA generally. 
> 
> Thx in advance.
> 
> 
> 
> -- 
> For more options, visit http://beagleboard.org/discuss 
> <http://beagleboard.org/discuss>
> --- 
> You received this message because you are subscribed to the Google Groups 
> "BeagleBoard" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to beagleboard+unsubscr...@googlegroups.com 
> <mailto:beagleboard+unsubscr...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to