Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.9.4.
  1/*
  2 * Copyright (C) 2012 CERN (www.cern.ch)
  3 * Author: Alessandro Rubini <rubini@gnudd.com>
  4 *
  5 * Permission to use, copy, modify, and/or distribute this software for any
  6 * purpose with or without fee is hereby granted, provided that the above
  7 * copyright notice and this permission notice appear in all copies.
  8 *
  9 * The software is provided "as is"; the copyright holders disclaim
 10 * all warranties and liabilities, to the extent permitted by
 11 * applicable law.
 12 */
 13
 14/* A trivial fmc driver that can load a gateware file and reports interrupts */
 15#include <linux/module.h>
 16#include <linux/init.h>
 17#include <linux/interrupt.h>
 18#include <linux/gpio.h>
 19#include <linux/fmc.h>
 20
 21static struct fmc_driver t_drv; /* initialized later */
 22
 23static irqreturn_t t_handler(int irq, void *dev_id)
 24{
 25	struct fmc_device *fmc = dev_id;
 26
 27	fmc_irq_ack(fmc);
 28	dev_info(&fmc->dev, "received irq %i\n", irq);
 29	return IRQ_HANDLED;
 30}
 31
 32static struct fmc_gpio t_gpio[] = {
 33	{
 34		.gpio = FMC_GPIO_IRQ(0),
 35		.mode = GPIOF_DIR_IN,
 36		.irqmode = IRQF_TRIGGER_RISING,
 37	}, {
 38		.gpio = FMC_GPIO_IRQ(1),
 39		.mode = GPIOF_DIR_IN,
 40		.irqmode = IRQF_TRIGGER_RISING,
 41	}
 42};
 43
 44static int t_probe(struct fmc_device *fmc)
 45{
 46	int ret;
 47	int index = 0;
 48
 49	index = fmc_validate(fmc, &t_drv);
 50	if (index < 0)
 51		return -EINVAL; /* not our device: invalid */
 52
 53	ret = fmc_irq_request(fmc, t_handler, "fmc-trivial", IRQF_SHARED);
 54	if (ret < 0)
 55		return ret;
 56	/* ignore error code of call below, we really don't care */
 57	fmc_gpio_config(fmc, t_gpio, ARRAY_SIZE(t_gpio));
 58
 59	ret = fmc_reprogram(fmc, &t_drv, "", 0);
 60	if (ret == -EPERM) /* programming not supported */
 61		ret = 0;
 62	if (ret < 0)
 63		fmc_irq_free(fmc);
 64
 65	/* FIXME: reprogram LM32 too */
 66	return ret;
 67}
 68
 69static int t_remove(struct fmc_device *fmc)
 70{
 71	fmc_irq_free(fmc);
 72	return 0;
 73}
 74
 75static struct fmc_driver t_drv = {
 76	.version = FMC_VERSION,
 77	.driver.name = KBUILD_MODNAME,
 78	.probe = t_probe,
 79	.remove = t_remove,
 80	/* no table, as the current match just matches everything */
 81};
 82
 83 /* We accept the generic parameters */
 84FMC_PARAM_BUSID(t_drv);
 85FMC_PARAM_GATEWARE(t_drv);
 86
 87static int t_init(void)
 88{
 89	int ret;
 90
 91	ret = fmc_driver_register(&t_drv);
 92	return ret;
 93}
 94
 95static void t_exit(void)
 96{
 97	fmc_driver_unregister(&t_drv);
 98}
 99
100module_init(t_init);
101module_exit(t_exit);
102
103MODULE_LICENSE("Dual BSD/GPL");