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 --- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
