fa-core.c 16.9 KB
Newer Older
Federico Vaga's avatar
Federico Vaga committed
1
/*
2
 * core fmc-adc-100m14b driver
Federico Vaga's avatar
Federico Vaga committed
3 4 5 6 7 8 9 10 11 12
 *
 * Copyright (C) 2012 CERN (www.cern.ch)
 * Author: Federico Vaga <federico.vaga@gmail.com>
 *		Copied from fine-delay fd-core.c
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
13
#include <linux/version.h>
14

15
#include "fmc-adc-100m14b4cha.h"
Federico Vaga's avatar
Federico Vaga committed
16

17
/* Module parameters */
18
static struct fmc_driver fa_dev_drv;
19
FMC_PARAM_BUSID(fa_dev_drv);
20
FMC_PARAM_GATEWARE(fa_dev_drv);
21

22 23 24 25 26 27 28
static int fa_enable_test_data_fpga;
module_param_named(enable_test_data_fpga, fa_enable_test_data_fpga, int, 0444);
static int fa_enable_test_data_adc;
module_param_named(enable_test_data_adc, fa_enable_test_data_adc, int, 0444);
static int fa_enable_test_data_adc_pattern = 0x555;
module_param_named(enable_test_data_adc_pattern, fa_enable_test_data_adc_pattern, int, 0664);

29

30
static const int zfad_hw_range[] = {
31 32 33 34
	[FA100M14B4C_RANGE_10V]   = 0x45,
	[FA100M14B4C_RANGE_1V]    = 0x11,
	[FA100M14B4C_RANGE_100mV] = 0x23,
	[FA100M14B4C_RANGE_OPEN]  = 0x00,
35 36
};

37 38 39
/* fmc-adc specific workqueue */
struct workqueue_struct *fa_workqueue;

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
/*
 * zfad_convert_hw_range
 * @usr_val: range value
 *
 * return the enum associated to the range value
 */
int zfad_convert_hw_range(uint32_t bitmask)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(zfad_hw_range); i++)
		if (zfad_hw_range[i] == bitmask)
			return i;
	return -EINVAL;
}

56 57
/* Calculate correct index in fa_regfield array for channel from CHx indexes */
int zfad_get_chx_index(unsigned long addr, struct zio_channel *chan)
58 59 60
{
	int offset;

61
	offset = ZFA_CHx_MULT  * (FA100M14B4C_NCHAN - chan->index);
62 63 64 65

	return addr - offset;
}

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

/**
 * It enables or disables the pattern data on the ADC
 * @fa The ADC device instance
 * @pattern the pattern data to get from the ADC
 * @enable 0 to disable, 1 to enable
 */
int zfad_pattern_data_enable(struct fa_dev *fa, uint16_t pattern,
			     unsigned int enable)
{
	uint32_t frame_tx;
	int err;

	frame_tx  = 0x0000; /* write mode */
	frame_tx |= 0x0400; /* A4 pattern */
	frame_tx |= pattern & 0xFF; /* LSB pattern */
	err = fa_spi_xfer(fa, FA_SPI_SS_ADC, 16, frame_tx, NULL);
	if (err)
		return err;

	frame_tx  = 0x0000; /* write mode */
	frame_tx |= 0x0300; /* A3 pattern + enable */
	frame_tx |= (pattern & 0xFF00) >> 8; /* MSB pattern */
	frame_tx |= (enable ? 0x80 : 0x00); /* Enable the pattern data */
	err = fa_spi_xfer(fa, FA_SPI_SS_ADC, 16, frame_tx, NULL);
	if (err)
		return err;

	return 0;
}

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
/*
 * zfad_apply_user_offset
 * @fa: the fmc-adc descriptor
 * @chan: the channel where apply offset
 * @usr_val: the offset value to apply, expressed as millivolts (-5000..5000)
 *
 * Apply user offset to the channel input. Before apply the user offset it must
 * be corrected with offset and gain calibration value. An open input does not
 * need any correction.
 */
int zfad_apply_user_offset(struct fa_dev *fa, struct zio_channel *chan,
				  uint32_t usr_val)
{
	uint32_t range_reg;
	int32_t uval =  (int32_t)usr_val;
	int offset, gain, hwval, i, range;

	if (uval < -5000 || uval > 5000)
		return -EINVAL;

	i = zfad_get_chx_index(ZFA_CHx_CTL_RANGE, chan);
118
	range_reg = fa_readl(fa, fa->fa_adc_csr_base, &zfad_regs[i]);
119 120 121 122 123

	range = zfad_convert_hw_range(range_reg);
	if (range < 0)
		return range;

124
	if (range == FA100M14B4C_RANGE_OPEN) {
125 126 127 128 129 130 131 132
		offset = FA_CAL_NO_OFFSET;
		gain = FA_CAL_NO_GAIN;
	} else {
		offset = fa->calib.dac[range].offset[chan->index];
		gain = fa->calib.dac[range].gain[chan->index];
	}

	hwval = uval * 0x8000 / 5000;
133 134
	if (hwval == 0x8000)
		hwval = 0x7fff; /* -32768 .. 32767 */
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

	hwval = ((hwval + offset) * gain) >> 15; /* signed */
	hwval += 0x8000; /* offset binary */
	if (hwval < 0)
		hwval = 0;
	if (hwval > 0xffff)
		hwval = 0xffff;

	/* Apply calibrated offset to DAC */
	return fa_spi_xfer(fa, FA_SPI_SS_DAC(chan->index), 16, hwval, NULL);
}

/*
 * zfad_reset_offset
 * @fa: the fmc-adc descriptor
 *
 * Reset channel's offsets
 */
void zfad_reset_offset(struct fa_dev *fa)
{
	int i;

157
	for (i = 0; i < FA100M14B4C_NCHAN; ++i)
158 159 160
		zfad_apply_user_offset(fa, &fa->zdev->cset->chan[i], 0);
}

161 162 163 164 165 166 167 168 169 170
/*
 * zfad_init_saturation
 * @fa: the fmc-adc descriptor
 *
 * Initialize all saturation registers to the maximum value
 */
void zfad_init_saturation(struct fa_dev *fa)
{
	int idx, i;

171
	for (i = 0, idx = ZFA_CH1_SAT; i < FA100M14B4C_NCHAN; ++i, idx += ZFA_CHx_MULT)
172 173 174
		fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[idx], 0x7fff);
}

175 176 177 178 179 180
/*
 * zfad_set_range
 * @fa: the fmc-adc descriptor
 * @chan: the channel to calibrate
 * @usr_val: the volt range to set and calibrate
 *
181 182 183
 * When the input range changes, we must write new fixup values.
 * Gain ad offsets must be corrected with offset and gain calibration value.
 * An open input and test data do not need any correction.
184 185 186 187 188 189 190 191
 */
int zfad_set_range(struct fa_dev *fa, struct zio_channel *chan,
			  int range)
{
	int i, offset, gain;

	/* Actually set the range */
	i = zfad_get_chx_index(ZFA_CHx_CTL_RANGE, chan);
192
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i], zfad_hw_range[range]);
193

194 195 196 197 198 199 200
	if (range == FA100M14B4C_RANGE_OPEN || fa_enable_test_data_adc) {
		/*
		 * With OPEN range we do not use calibration values
		 *
		 * In test mode we do not apply the gain/offset because
		 * this compromises the test pattern
		 */
201 202 203 204
		offset = FA_CAL_NO_OFFSET;
		gain = FA_CAL_NO_GAIN;
	} else {
		if (range < 0 || range > ARRAY_SIZE(fa->calib.adc)) {
205
			dev_info(fa->msgdev, "Invalid range %i or ch %i\n",
206 207 208 209 210 211 212 213
				 range, chan->index);
			return -EINVAL;
		}
		offset = fa->calib.adc[range].offset[chan->index];
		gain = fa->calib.adc[range].gain[chan->index];
	}

	i = zfad_get_chx_index(ZFA_CHx_OFFSET, chan);
214
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i],
Federico Vaga's avatar
Federico Vaga committed
215
		  offset & 0xffff /* prevent warning */);
216
	i = zfad_get_chx_index(ZFA_CHx_GAIN, chan);
217
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[i], gain);
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

	/* recalculate user offset for the new range */
	zfad_apply_user_offset(fa, chan, fa->user_offset[chan->index]);

	return 0;
}

/*
 * zfad_fsm_command
 * @fa: the fmc-adc descriptor
 * @command: the command to apply to FSM
 *
 * This function checks if the command can be done and performs some
 * preliminary operation beforehand
 */
int zfad_fsm_command(struct fa_dev *fa, uint32_t command)
{
	struct zio_cset *cset = fa->zdev->cset;
	uint32_t val;
237
	int err;
238

Federico Vaga's avatar
Federico Vaga committed
239 240
	if (command != FA100M14B4C_CMD_START &&
	    command != FA100M14B4C_CMD_STOP) {
241
		dev_info(fa->msgdev, "Invalid command %i\n", command);
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
		return -EINVAL;
	}

	/*
	 * When any command occurs we are ready to start a new acquisition, so
	 * we must abort any previous one. If it is STOP, we abort because we
	 * abort an acquisition. If it is START, we abort because if there was
	 * a previous start but the acquisition end interrupt doesn't occurs,
	 * START mean RESTART. If it is a clean START, the abort has not
	 * effects.
	 *
	 * This is done only if ADC is using its own trigger, otherwise it is
	 * not necessary.
	 *
	 * The case of fmc-adc-trg is optimized because is the most common
	 * case
	 */
259
	if (likely(cset->trig == &zfat_type || command == FA100M14B4C_CMD_STOP))
260 261 262 263 264 265 266
		zio_trigger_abort_disable(cset, 0);

	/* Reset counters */
	fa->n_shots = 0;
	fa->n_fires = 0;

	/* If START, check if we can start */
267
	if (command == FA100M14B4C_CMD_START) {
268
		/* Verify that SerDes PLL is lockes */
269 270
		val = fa_readl(fa, fa->fa_adc_csr_base,
			       &zfad_regs[ZFA_STA_SERDES_PLL]);
271
		if (!val) {
272
			dev_info(fa->msgdev, "Cannot start acquisition: "
273 274 275 276
				 "SerDes PLL not locked\n");
			return -EBUSY;
		}
		/* Verify that SerDes is synched */
277 278
		val = fa_readl(fa, fa->fa_adc_csr_base,
			       &zfad_regs[ZFA_STA_SERDES_SYNCED]);
279
		if (!val) {
280
			dev_info(fa->msgdev, "Cannot start acquisition: "
281 282 283 284 285 286 287 288 289 290 291 292 293 294
				 "SerDes not synchronized\n");
			return -EBUSY;
		}

		/* Now we can arm the trigger for the incoming acquisition */
		zio_arm_trigger(cset->ti);
		/*
		 *  FIXME maybe zio_arm_trigger() can return an error when it
		 * is not able to arm a trigger.
		 *
		 * It returns -EPERM, but the error can be -ENOMEM or -EINVAL
		 * from zfat_arm_trigger() or zfad_input_cset()
		 */
		if (!(cset->ti->flags & ZIO_TI_ARMED)) {
295
			dev_info(fa->msgdev, "Cannot start acquisition: "
296 297 298 299
				 "Trigger refuses to arm\n");
			return -EIO;
		}

300
		dev_dbg(fa->msgdev, "FSM START Command, Enable interrupts\n");
301
		fa_enable_irqs(fa);
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

		/*
		 * Set the test data if necessary. This is unlikely to happen,
		 * and when this is the case we do not care about performances
		 */
		if (unlikely(fa_enable_test_data_adc)) {
			fa_enable_test_data_adc_pattern &= 0xFFF;
			err = zfad_pattern_data_enable(fa, fa_enable_test_data_adc_pattern,
						       fa_enable_test_data_adc);
			if (err)
				dev_warn(fa->msgdev,
					 "Failed to set the ADC test data. Continue without\n");
			else if (fa_enable_test_data_adc)
				dev_info(fa->msgdev, "the ADC test data is enabled on all channels\n");
		}
317 318
		fa_writel(fa, fa->fa_adc_csr_base,
			  &zfad_regs[ZFA_CTL_RST_TRG_STA], 1);
319
	} else {
320
		dev_dbg(fa->msgdev, "FSM STOP Command, Disable interrupts\n");
321
		fa->enable_auto_start = 0;
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
		fa_disable_irqs(fa);
	}

	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFA_CTL_FMS_CMD],
		  command);
	return 0;
}

/* Extract from SDB the base address of the core components */
/* which are not carrier specific */
static int __fa_sdb_get_device(struct fa_dev *fa)
{
	struct fmc_device *fmc = fa->fmc;
	int ret;

	ret = fmc_scan_sdb_tree(fmc, 0);
338 339 340 341 342
	if (ret == -EBUSY) {
		/* Not a problem, it's already there. We assume that
		   it's the correct one */
		ret = 0;
	}
343
	if (ret < 0) {
344
		dev_err(fa->msgdev,
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
			"%s: no SDB in the bitstream."
			"Are you sure you've provided the correct one?\n",
			KBUILD_MODNAME);
		return ret;
	}

	/* Now use SDB to find the base addresses */
	fa->fa_irq_vic_base = fmc_find_sdb_device(fmc->sdb, 0xce42,
						  0x13, NULL);
	fa->fa_adc_csr_base = fmc_find_sdb_device_ext(fmc->sdb, 0xce42,
						      0x608,
						      fmc->slot_id, NULL);
	fa->fa_irq_adc_base = fmc_find_sdb_device_ext(fmc->sdb, 0xce42,
						      0x26ec6086,
						      fmc->slot_id, NULL);
	fa->fa_utc_base = fmc_find_sdb_device_ext(fmc->sdb, 0xce42,
						  0x604, fmc->slot_id, NULL);
	fa->fa_spi_base = fmc_find_sdb_device_ext(fmc->sdb, 0xce42, 0xe503947e,
							fmc->slot_id, NULL);
	fa->fa_ow_base = fmc_find_sdb_device_ext(fmc->sdb, 0xce42, 0x779c5443,
							fmc->slot_id, NULL);

	return ret;
}

/*
 * Specific check and init
 */
static int __fa_init(struct fa_dev *fa)
{
	struct device *hwdev = fa->fmc->hwdev;
	struct zio_device *zdev = fa->zdev;
	int i, addr;

	/* Check if hardware supports 64-bit DMA */
	if (dma_set_mask(hwdev, DMA_BIT_MASK(64))) {
		/* Check if hardware supports 32-bit DMA */
		if (dma_set_mask(hwdev, DMA_BIT_MASK(32))) {
383
			dev_err(fa->msgdev, "32-bit DMA addressing not available\n");
384 385 386 387 388 389
			return -EINVAL;
		}
	}

	/* Retrieve calibration from the eeprom and validate*/
	fa_read_eeprom_calib(fa);
390 391
	fa->mshot_max_samples = fa_readl(fa, fa->fa_adc_csr_base,
					 &zfad_regs[ZFA_MULT_MAX_SAMP]);
392 393 394

	/* Force stop FSM to prevent early trigger fire */
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFA_CTL_FMS_CMD],
395
		   FA100M14B4C_CMD_STOP);
396 397 398 399 400
	/* Initialize channels to use 1V range */
	for (i = 0; i < 4; ++i) {
		addr = zfad_get_chx_index(ZFA_CHx_CTL_RANGE,
						&zdev->cset->chan[i]);
		fa_writel(fa,  fa->fa_adc_csr_base, &zfad_regs[addr],
401 402
			  FA100M14B4C_RANGE_1V);
		zfad_set_range(fa, &zdev->cset->chan[i], FA100M14B4C_RANGE_1V);
403 404 405 406 407 408
	}
	zfad_reset_offset(fa);

	/* Enable mezzanine clock */
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFA_CTL_CLK_EN], 1);
	/* Set decimation to minimum */
409
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_SR_UNDER], 1);
410 411
	/* Set test data register */
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFA_CTL_TEST_DATA_EN],
412
		  fa_enable_test_data_fpga);
413

414 415
	/* Set to single shot mode by default */
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_SHOTS_NB], 1);
416

417 418 419
	/* Enable the software trigger by default: there is no arm in this */
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_CFG_SRC],
		  FA100M14B4C_TRG_SRC_SW);
420

421 422 423 424
	/* Zero offsets and release the DAC clear */
	zfad_reset_offset(fa);
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFA_CTL_DAC_CLR_N], 1);

425 426 427
	/* Initialize channel saturation values */
	zfad_init_saturation(fa);

428 429 430 431
	/* Set UTC seconds from the kernel seconds */
	fa_writel(fa, fa->fa_utc_base, &zfad_regs[ZFA_UTC_SECONDS],
		  get_seconds());

432
	fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_EXT_DLY], 0);
433

434 435
	/* disable auto_start */
	fa->enable_auto_start = 0;
436 437 438
	return 0;
}

439 440 441
/* This structure lists the various subsystems */
struct fa_modlist {
	char *name;
442 443
	int (*init)(struct fa_dev *);
	void (*exit)(struct fa_dev *);
444
};
445

446
static struct fa_modlist mods[] = {
Alessandro Rubini's avatar
Alessandro Rubini committed
447
	{"spi", fa_spi_init, fa_spi_exit},
448 449
	{"onewire", fa_onewire_init, fa_onewire_exit},
	{"zio", fa_zio_init, fa_zio_exit},
450
	{"debug", fa_debug_init, fa_debug_exit},
451 452 453
};

/* probe and remove are called by fa-spec.c */
454
int fa_probe(struct fmc_device *fmc)
Federico Vaga's avatar
Federico Vaga committed
455
{
456
	struct fa_modlist *m = NULL;
457
	struct fa_dev *fa;
458
	int err, i = 0;
459
	char *fwname;
Federico Vaga's avatar
Federico Vaga committed
460

461
	/* Validate the new FMC device */
462
	i = fmc_validate(fmc, &fa_dev_drv);
463
	if (i < 0) {
464
		dev_info(&fmc->dev, "not using \"%s\" according to "
465 466 467 468
			 "modparam\n", KBUILD_MODNAME);
		return -ENODEV;
	}

469
	/* Driver data */
470
	fa = devm_kzalloc(&fmc->dev, sizeof(struct fa_dev), GFP_KERNEL);
Federico Vaga's avatar
Federico Vaga committed
471 472
	if (!fa)
		return -ENOMEM;
473 474
	fmc_set_drvdata(fmc, fa);
	fa->fmc = fmc;
475
	fa->msgdev = &fa->fmc->dev;
Federico Vaga's avatar
Federico Vaga committed
476

477
	/* apply carrier-specific hacks and workarounds */
478 479
	fa->carrier_op = NULL;
	if (!strcmp(fmc->carrier_name, "SPEC")) {
480
		fa->carrier_op = &fa_spec_op;
481 482
	} else if (!strcmp(fmc->carrier_name, "SVEC")) {
#ifdef CONFIG_FMC_ADC_SVEC
Michel Arruat's avatar
Michel Arruat committed
483
		fa->carrier_op = &fa_svec_op;
484 485 486 487 488 489 490 491
#endif
	}

	/*
	 * Check if carrier operations exists. Otherwise it means that the
	 * driver was compiled without enable any carrier, so it cannot work
	 */
	if (!fa->carrier_op) {
492
		dev_err(fa->msgdev,
493 494
			"This binary doesn't support the '%s' carrier\n",
			fmc->carrier_name);
495 496 497
		return -ENODEV;
	}

498 499 500 501 502 503 504 505 506 507 508 509
	/*
	 * If the carrier is still using the golden bitstream or the user is
	 * asking for a particular one, then program our bistream, otherwise
	 * we already have our bitstream
	 */
	if (fmc->flags & FMC_DEVICE_HAS_GOLDEN || fa_dev_drv.gw_n) {
		if (fa_dev_drv.gw_n)
			fwname = ""; /* reprogram will pick from module parameter */
		else
			fwname = fa->carrier_op->get_gwname();

		/* We first write a new binary (and lm32) within the carrier */
510
		err = fmc_reprogram(fmc, &fa_dev_drv, fwname, 0x0);
511
		if (err) {
512
			dev_err(fa->msgdev, "write firmware \"%s\": error %i\n",
513
				fwname, err);
514 515 516
			goto out;
		}
	} else {
517
		dev_info(fa->msgdev,
518
			 "Gateware already there. Set the \"gateware\" parameter to overwrite the current gateware\n");
519 520
	}

521 522 523 524 525 526 527 528 529 530 531 532
	/* Extract whisbone core base address fron SDB */
	err = __fa_sdb_get_device(fa);
	if (err < 0)
		goto out;

	err = fa->carrier_op->init(fa);
	if (err < 0)
		goto out;

	err = fa->carrier_op->reset_core(fa);
	if (err < 0)
		goto out;
533

534 535
	/* init all subsystems */
	for (i = 0, m = mods; i < ARRAY_SIZE(mods); i++, m++) {
536
		dev_dbg(fa->msgdev, "Calling init for \"%s\"\n", m->name);
537 538
		err = m->init(fa);
		if (err) {
539
			dev_err(fa->msgdev, "error initializing %s\n", m->name);
540 541
			goto out;
		}
Federico Vaga's avatar
Federico Vaga committed
542
	}
543

544 545 546 547 548 549 550 551 552
	/* time to execute specific driver init */
	err = __fa_init(fa);
	if (err < 0)
		goto out;

	err = fa_setup_irqs(fa);
	if (err < 0)
		goto out;

553 554 555 556
	/* Pin the carrier */
	if (!try_module_get(fmc->owner))
		goto out_mod;

Federico Vaga's avatar
Federico Vaga committed
557
	return 0;
558

559 560
out_mod:
	fa_free_irqs(fa);
561 562 563 564 565
out:
	while (--m, --i >= 0)
		if (m->exit)
			m->exit(fa);
	return err;
Federico Vaga's avatar
Federico Vaga committed
566
}
567

568
int fa_remove(struct fmc_device *fmc)
Federico Vaga's avatar
Federico Vaga committed
569
{
570
	struct fa_dev *fa = fmc_get_drvdata(fmc);
571 572 573
	struct fa_modlist *m;
	int i = ARRAY_SIZE(mods);

574
	fa_free_irqs(fa);
575
	flush_workqueue(fa_workqueue);
576

577 578 579 580 581
	while (--i >= 0) {
		m = mods + i;
		if (m->exit)
			m->exit(fa);
	}
582

583 584
	fa->carrier_op->exit(fa);

585 586 587
	/* Release the carrier */
	module_put(fmc->owner);

588
	return 0;
Federico Vaga's avatar
Federico Vaga committed
589
}
590 591 592 593 594 595 596

static struct fmc_fru_id fa_fru_id[] = {
	{
		.product_name = "FmcAdc100m14b4cha",
	},
};

597
static struct fmc_driver fa_dev_drv = {
598
	.version = FMC_VERSION,
599 600 601
	.driver.name = KBUILD_MODNAME,
	.probe = fa_probe,
	.remove = fa_remove,
602 603 604 605
	.id_table = {
		.fru_id = fa_fru_id,
		.fru_id_nr = ARRAY_SIZE(fa_fru_id),
	},
606
};
Federico Vaga's avatar
Federico Vaga committed
607 608 609 610 611

static int fa_init(void)
{
	int ret;

612
	#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)
613
	fa_workqueue = alloc_workqueue(fa_dev_drv.driver.name,
Federico Vaga's avatar
Federico Vaga committed
614 615
					WQ_NON_REENTRANT | WQ_UNBOUND |
					WQ_MEM_RECLAIM, 1);
616 617 618 619
	#else
	fa_workqueue = alloc_workqueue(fa_dev_drv.driver.name,
				       WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
	#endif
620 621 622
	if (fa_workqueue == NULL)
		return -ENOMEM;

623 624
	/* First trigger and zio driver */
	ret = fa_trig_init();
625
	if (ret)
626
		goto out1;
627 628

	ret = fa_zio_register();
629 630 631
	if (ret)
		goto out2;

632 633
	/* Finally the fmc driver, whose probe instantiates zio devices */
	ret = fmc_driver_register(&fa_dev_drv);
634 635 636 637 638 639 640 641 642 643 644 645 646
	if (ret)
		goto out3;

	return ret;

out3:
	fa_zio_unregister();
out2:
	fa_trig_exit();
out1:
	destroy_workqueue(fa_workqueue);

	return ret;
Federico Vaga's avatar
Federico Vaga committed
647 648 649 650
}

static void fa_exit(void)
{
651
	fmc_driver_unregister(&fa_dev_drv);
652 653
	fa_zio_unregister();
	fa_trig_exit();
654 655
	if (fa_workqueue != NULL)
		destroy_workqueue(fa_workqueue);
Federico Vaga's avatar
Federico Vaga committed
656 657 658 659 660 661
}

module_init(fa_init);
module_exit(fa_exit);

MODULE_AUTHOR("Federico Vaga");
662
MODULE_DESCRIPTION("FMC-ADC-100MS-14b Linux Driver");
Federico Vaga's avatar
Federico Vaga committed
663
MODULE_LICENSE("GPL");
664
MODULE_VERSION(GIT_VERSION);
665

666
ADDITIONAL_VERSIONS;