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.