Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/kdev_t.h>
- #include <linux/fs.h>
- #include <linux/device.h>
- #include <linux/cdev.h>
- #include <asm/uaccess.h>
- #include <linux/init.h>
- #include <linux/mutex.h>
- #include <linux/slab.h>
- #include <linux/string.h>
- #include <linux/of.h>
- #include <linux/interrupt.h>
- #include <linux/irq.h>
- #include <linux/spi/spi.h>
- #include <linux/gpio.h>
- #include <linux/pinctrl/consumer.h>
- #include <linux/of_gpio.h>
- #include "r0005spi.h"
- #define MAX_CARDS 6
- const char this_driver_name[] = "r0005spi";
- static int r0005spi_probe(struct spi_device *pdev);
- static int r0005spi_remove(struct spi_device *pdev);
- static const struct of_device_id db_r0005spi_of_ids[] = {
- {
- .compatible = "dbbroadcast,r0005spi",
- },
- { },
- };
- MODULE_DEVICE_TABLE(of, db_r0005spi_of_ids);
- static struct spi_driver r0005spi_driver =
- {
- .driver = {
- .name = this_driver_name,
- .owner = THIS_MODULE,
- .of_match_table = db_r0005spi_of_ids,
- },
- .probe = r0005spi_probe,
- .remove = r0005spi_remove,
- };
- /****************
- * IRQ Handling *
- ***************/
- static irqreturn_t r0005spi_irq_handler(int irq, void* devID)
- {
- pr_debug("%s: IRQ: %d\n", __func__, irq);
- return IRQ_HANDLED;
- }
- /***********
- * Probing *
- * ********/
- static int r0005spi_probe(struct spi_device *spi)
- {
- struct device_node *parent_node = spi->master->dev.of_node;
- struct device_node *child_node;
- struct r0005spi_data *data;
- struct card_config *card;
- int num_cards = 0;
- struct pinctrl *pinctrl;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- pr_debug("%s: SPI Bus %d probed\n", __func__, spi->master->bus_num);
- if (IS_ERR(parent_node))
- {
- pr_debug("%s: Failed to get parent node\n", __func__);
- }
- pinctrl = devm_pinctrl_get_select_default(&spi->dev);
- if (IS_ERR(pinctrl))
- {
- pr_debug("%s: Setting pins failed: %d\n", __func__, (s32) pinctrl);
- }
- for_each_available_child_of_node(parent_node, child_node)
- {
- data->cards[num_cards] = kzalloc(sizeof(*card), GFP_KERNEL);
- card = data->cards[num_cards];
- of_property_read_u32(child_node, "card", &(card->position));
- pr_debug("%s: Loaded node: %s with position: %d\n", __func__, child_node->name, card->position);
- num_cards++;
- }
- data->num_cards = num_cards;
- spi_set_drvdata(spi, data);
- pr_debug("%s: Finished probing\n", __func__);
- return 0;
- }
- static int r0005spi_remove(struct spi_device *spi)
- {
- int i;
- struct r0005spi_data *data;
- pr_debug("%s: Removing\n", __func__);
- data = spi_get_drvdata(spi);
- for(i=0; i<data->num_cards; i++)
- {
- if (!IS_ERR(data->cards[i]))
- {
- pr_debug("%s: card at position %d is to be set free\n", __func__, data->cards[i]->position);
- kfree(data->cards[i]);
- pr_debug("%s: card at index %d memory was set free\n", __func__, i);
- }
- }
- kfree(data);
- pr_debug("%s: data memory was set free\n", __func__);
- pr_debug("%s: Removed\n", __func__);
- return 0;
- }
- /*****************************************
- * Module Intialisation/Deinitialisation *
- *****************************************/
- static int r0005spi_init(void)
- {
- pr_debug("%s: Inititialising Driver r0005spi\n", __func__);
- return spi_register_driver(&r0005spi_driver);
- }
- static void r0005spi_exit(void)
- {
- spi_unregister_driver(&r0005spi_driver);
- pr_debug("%s: Exiting Driver r0005spi\n", __func__);
- }
- module_init(r0005spi_init);
- module_exit(r0005spi_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Jack Mitchell <jack.mitchell@dbbroadcast.co.uk>");
- MODULE_DESCRIPTION("r0005spi driver");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement