Commit 62c15412 authored by Federico Vaga's avatar Federico Vaga

drv: use platform_data to get options

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 6044ea57
......@@ -14,7 +14,7 @@
#include <linux/fmc.h>
#include "fmc-adc-100m14b4cha.h"
#include <platform_data/fmc-adc-100m14b4cha.h>
static int fa_enable_test_data_fpga;
module_param_named(enable_test_data_fpga, fa_enable_test_data_fpga, int, 0444);
......@@ -513,6 +513,30 @@ err:
return false;
}
static void fa_memops_detect(struct fa_dev *fa)
{
if (fa_is_flag_set(fa, FMC_ADC_BIG_ENDIAN)) {
fa->memops.read = ioread32be;
fa->memops.write = iowrite32be;
} else {
fa->memops.read = ioread32;
fa->memops.write = iowrite32;
}
}
static void fa_sg_alloc_table_init(struct fa_dev *fa)
{
if (fa_is_flag_set(fa, FMC_ADC_NOSQUASH_SCATTERLIST))
fa->sg_alloc_table_from_pages = sg_alloc_table_from_pages_no_squash;
else
fa->sg_alloc_table_from_pages = __sg_alloc_table_from_pages;
}
static struct fmc_adc_platform_data fmc_adc_pdata_default = {
.flags = 0,
};
/* probe and remove are called by fa-spec.c */
int fa_probe(struct platform_device *pdev)
{
......@@ -533,25 +557,14 @@ int fa_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, fa);
fa->pdev = pdev;
fa->msgdev = &fa->pdev->dev;
/* Assign IO operation */
switch (pdev->id_entry->driver_data) {
case ADC_VER_SPEC:
fa->memops.read = ioread32;
fa->memops.write = iowrite32;
fa->sg_alloc_table_from_pages = __sg_alloc_table_from_pages;
break;
case ADC_VER_SVEC:
fa->memops.read = ioread32be;
fa->memops.write = iowrite32be;
fa->sg_alloc_table_from_pages = sg_alloc_table_from_pages_no_squash;
break;
default:
dev_err(fa->msgdev, "Unknow version %lu\n",
pdev->id_entry->driver_data);
goto out_ops;
if (!pdev->dev.platform_data) {
dev_err(fa->msgdev, "Missing platform data, use default\n");
pdev->dev.platform_data = &fmc_adc_pdata_default;
}
fa_memops_detect(fa);
fa_sg_alloc_table_init(fa);
r = platform_get_resource(pdev, IORESOURCE_MEM, ADC_MEM_BASE);
fa->fa_top_level = ioremap(r->start, resource_size(r));
fa->fa_adc_csr_base = fa->fa_top_level + ADC_CSR_OFF;
......@@ -621,7 +634,6 @@ out_fmc_eeprom:
out_fmc_pre:
fmc_slot_put(fa->slot);
out_fmc:
out_ops:
devm_kfree(&pdev->dev, fa);
platform_set_drvdata(pdev, NULL);
return err;
......@@ -654,13 +666,9 @@ int fa_remove(struct platform_device *pdev)
static const struct platform_device_id fa_id[] = {
{
.name = "adc-100m-spec",
.driver_data = ADC_VER_SPEC,
},
{
.name = "adc-100m-svec",
.driver_data = ADC_VER_SVEC,
},
.name = "fmc-adc-100m",
.driver_data = ADC_VER,
}
/* TODO we should support different version */
};
......@@ -729,6 +737,6 @@ module_exit(fa_exit);
MODULE_AUTHOR("Federico Vaga");
MODULE_DESCRIPTION("FMC-ADC-100MS-14b Linux Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(GIT_VERSION);
MODULE_VERSION(VERSION);
ADDITIONAL_VERSIONS;
......@@ -186,7 +186,7 @@ static void zfad_dma_context_exit(struct zio_cset *cset,
{
struct fa_dev *fa = cset->zdev->priv_d;
if (fa->pdev->id_entry->driver_data == ADC_VER_SVEC) {
if (fa_is_flag_set(fa, FMC_ADC_SVEC)) {
__endianness(zfad_block->block->datalen,
zfad_block->block->data);
......@@ -204,7 +204,7 @@ static int zfad_dma_context_init(struct zio_cset *cset,
#ifdef CONFIG_FMC_ADC_SVEC
struct fa_dev *fa = cset->zdev->priv_d;
if (fa->pdev->id_entry->driver_data == ADC_VER_SVEC) {
if (fa_is_flag_set(fa, FMC_ADC_SVEC))) {
struct fa_svec_data *svec_data = fa->carrier_data;
unsigned long vme_addr;
struct vme_dma *desc;
......@@ -384,31 +384,11 @@ err_alloc_pages:
*/
static bool fa_dmaengine_filter(struct dma_chan *dchan, void *arg)
{
struct zio_cset *cset = arg;
struct fa_dev *fa = cset->zdev->priv_d;
struct device *device_ref = NULL;
switch (fa->pdev->id_entry->driver_data) {
case ADC_VER_SPEC:
/*
*The DMA channel and the ADC must be on the same carrier
* dev - current device
* parent - the application top level design
* parent - the SPEC device
*/
device_ref = fa->pdev->dev.parent->parent->parent;
break;
case ADC_VER_SVEC:
/* The channel must be on the VME bus */
device_ref = fa->pdev->dev.parent->parent->parent->parent->parent;
break;
default:
dev_warn(&cset->head.dev,
"Carrier not recognized. Accept the first available DMA channel\n");
return -ENODEV;
}
struct dma_device *ddev = dchan->device;
int dev_id = (*((int *)arg) >> 16) & 0xFFFF;
int chan_id = *((int *)arg) & 0xFFFF;
return (dchan->device->dev == device_ref);
return ddev->dev_id == dev_id && dchan->chan_id == chan_id;
}
......@@ -468,7 +448,7 @@ static int zfad_dma_start(struct zio_cset *cset)
* But sice the blocks are contigous, perhaps there is no need
* because the address of shot 2 is exactly after shot 1
*/
if (fa->pdev->id_entry->driver_data == ADC_VER_SPEC && fa->n_shots == 1)
if (!fa_is_flag_set(fa, FMC_ADC_SVEC) && fa->n_shots == 1)
sconfig.src_addr = zfad_dev_mem_offset(cset);
else
sconfig.src_addr = i * data_offset;
......
......@@ -36,8 +36,7 @@
#define FA100M14B4C_TRG_POL_CHx(_x) (FA100M14B4C_TRG_POL_CH1 << ((_x) - 1))
enum fa_versions {
ADC_VER_SPEC = 0,
ADC_VER_SVEC,
ADC_VER = 0,
};
/*
......@@ -168,6 +167,7 @@ struct fa_calib {
#include <linux/zio-trigger.h>
#include "field-desc.h"
#include <platform_data/fmc-adc-100m14b4cha.h>
#define ADC_CSR_OFF 0x1000
#define ADC_EIC_OFF 0x1500
......@@ -575,6 +575,15 @@ static inline void fa_writel(struct fa_dev *fa,
fa_iowrite(fa, val, base_off + field->offset);
}
static inline int fa_is_flag_set(struct fa_dev *fa, unsigned long flag)
{
const struct fmc_adc_platform_data *fmc_adc_pdata;
fmc_adc_pdata = fa->pdev->dev.platform_data;
return !!(fmc_adc_pdata->flags & flag);
}
extern struct bin_attribute dev_attr_calibration;
/* Global variable exported by fa-core.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment