diff options
author | Michael Büsch <mb@bu3sch.de> | 2008-07-18 20:53:08 +0000 |
---|---|---|
committer | Michael Büsch <mb@bu3sch.de> | 2008-07-18 20:53:08 +0000 |
commit | df41dbe6e1eeb8b94012e6f361cb1668d955857b (patch) | |
tree | e7934c9ef108ca16af31b2ebd6e8b3665ea3794e /package/mmc_over_gpio/src/mmc_over_spigpio.c | |
parent | f4ddadc99fef88dc1b88420622b551e50a4a4c53 (diff) | |
download | master-187ad058-df41dbe6e1eeb8b94012e6f361cb1668d955857b.tar.gz master-187ad058-df41dbe6e1eeb8b94012e6f361cb1668d955857b.tar.bz2 master-187ad058-df41dbe6e1eeb8b94012e6f361cb1668d955857b.zip |
Update GPIO-based MMC driver
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@11864 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mmc_over_gpio/src/mmc_over_spigpio.c')
-rw-r--r-- | package/mmc_over_gpio/src/mmc_over_spigpio.c | 339 |
1 files changed, 0 insertions, 339 deletions
diff --git a/package/mmc_over_gpio/src/mmc_over_spigpio.c b/package/mmc_over_gpio/src/mmc_over_spigpio.c deleted file mode 100644 index 113b518a56..0000000000 --- a/package/mmc_over_gpio/src/mmc_over_spigpio.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Driver for driving an MMC card over a bitbanging GPIO SPI bus. - * - * Copyright 2008 Michael Buesch <mb@bu3sch.de> - * - * Licensed under the GNU/GPL. See COPYING for details. - */ - -#include <linux/platform_device.h> -#include <linux/list.h> -#include <linux/mutex.h> -#include <linux/spi/spi_gpio.h> - - -/* This is the maximum speed in Hz */ -#define GPIOMMC_MAXSPEED 5000000 /* Hz */ - - -#define DRIVER_NAME "spi-gpio-mmc" -#define PFX DRIVER_NAME ": " - - -#define GPIOMMC_MAX_NAMELEN 15 -#define GPIOMMC_MAX_NAMELEN_STR __stringify(GPIOMMC_MAX_NAMELEN) - -struct gpiommc_pins { - unsigned int gpio_di; /* Card DI pin */ - unsigned int gpio_do; /* Card DO pin */ - unsigned int gpio_clk; /* Card CLK pin */ - unsigned int gpio_cs; /* Card CS pin */ -}; - -struct gpiommc_device { - char name[GPIOMMC_MAX_NAMELEN + 1]; - struct platform_device *pdev; - struct platform_device *spi_pdev; - struct gpiommc_pins pins; - u8 mode; /* SPI_MODE_X */ - struct spi_board_info boardinfo; - - struct list_head list; -}; - - -static LIST_HEAD(gpiommc_devices_list); -static DEFINE_MUTEX(gpiommc_mutex); - - -MODULE_DESCRIPTION("SPI-GPIO based MMC driver"); -MODULE_AUTHOR("Michael Buesch"); -MODULE_LICENSE("GPL"); - - -static int gpiommc_boardinfo_setup(struct spi_board_info *bi, - struct spi_master *master, - void *data) -{ - struct gpiommc_device *d = data; - - /* Bind the SPI master to the MMC-SPI host driver. */ - strlcpy(bi->modalias, "mmc_spi", sizeof(bi->modalias)); - - bi->max_speed_hz = GPIOMMC_MAXSPEED; - bi->bus_num = master->bus_num; - bi->mode = d->mode; - - return 0; -} - -static int gpiommc_probe(struct platform_device *pdev) -{ - static int instance; - struct gpiommc_device *d = platform_get_drvdata(pdev); - struct spi_gpio_platform_data pdata; - int err = -ENOMEM; - - d->spi_pdev = platform_device_alloc("spi-gpio", instance++); - if (!d->spi_pdev) - goto out; - - memset(&pdata, 0, sizeof(pdata)); - pdata.pin_clk = d->pins.gpio_clk; - pdata.pin_miso = d->pins.gpio_do; - pdata.pin_mosi = d->pins.gpio_di; - pdata.pin_cs = d->pins.gpio_cs; - pdata.cs_activelow = 1; - pdata.no_spi_delay = 1; - pdata.boardinfo_setup = gpiommc_boardinfo_setup; - pdata.boardinfo_setup_data = d; - - err = platform_device_add_data(d->spi_pdev, &pdata, sizeof(pdata)); - if (err) - goto err_free_pdev; - err = platform_device_register(d->spi_pdev); - if (err) - goto err_free_pdata; - - printk(KERN_INFO PFX "MMC-Card \"%s\" " - "attached to GPIO pins %u,%u,%u,%u\n", - d->name, d->pins.gpio_di, d->pins.gpio_do, - d->pins.gpio_clk, d->pins.gpio_cs); -out: - return err; - -err_free_pdata: - kfree(d->spi_pdev->dev.platform_data); - d->spi_pdev->dev.platform_data = NULL; -err_free_pdev: - platform_device_put(d->spi_pdev); - return err; -} - -static int gpiommc_remove(struct platform_device *pdev) -{ - struct gpiommc_device *d = platform_get_drvdata(pdev); - - platform_device_unregister(d->spi_pdev); - printk(KERN_INFO PFX "MMC-Card \"%s\" removed\n", d->name); - - return 0; -} - -static void gpiommc_free(struct gpiommc_device *d) -{ - kfree(d); -} - -static struct gpiommc_device * gpiommc_alloc(struct platform_device *pdev, - const char *name, - const struct gpiommc_pins *pins, - u8 mode) -{ - struct gpiommc_device *d; - - d = kmalloc(sizeof(*d), GFP_KERNEL); - if (!d) - return NULL; - - strcpy(d->name, name); - memcpy(&d->pins, pins, sizeof(d->pins)); - d->mode = mode; - INIT_LIST_HEAD(&d->list); - - return d; -} - -/* List must be locked. */ -static struct gpiommc_device * gpiommc_find_device(const char *name) -{ - struct gpiommc_device *d; - - list_for_each_entry(d, &gpiommc_devices_list, list) { - if (strcmp(d->name, name) == 0) - return d; - } - - return NULL; -} - -static void gpiommc_do_destroy_device(struct gpiommc_device *d) -{ - list_del(&d->list); - platform_device_unregister(d->pdev); - gpiommc_free(d); -} - -static int gpiommc_destroy_device(const char *name) -{ - struct gpiommc_device *d; - int err = -ENODEV; - - mutex_lock(&gpiommc_mutex); - d = gpiommc_find_device(name); - if (!d) - goto out_unlock; - gpiommc_do_destroy_device(d); - err = 0; -out_unlock: - mutex_unlock(&gpiommc_mutex); - - return err; -} - -static int gpiommc_create_device(const char *name, - const struct gpiommc_pins *pins, - u8 mode) -{ - static int instance; - struct platform_device *pdev; - struct gpiommc_device *d; - int err; - - mutex_lock(&gpiommc_mutex); - err = -EEXIST; - if (gpiommc_find_device(name)) - goto out_unlock; - err = -ENOMEM; - pdev = platform_device_alloc(DRIVER_NAME, instance++); - if (!pdev) - goto out_unlock; - d = gpiommc_alloc(pdev, name, pins, mode); - if (!d) - goto err_free_pdev; - platform_set_drvdata(pdev, d); - d->pdev = pdev; - err = platform_device_register(pdev); - if (err) - goto err_free_mdev; - list_add(&d->list, &gpiommc_devices_list); - - err = 0; -out_unlock: - mutex_unlock(&gpiommc_mutex); - - return err; - -err_free_mdev: - gpiommc_free(d); -err_free_pdev: - platform_device_put(pdev); - goto out_unlock; -} - -static ssize_t gpiommc_add_show(struct device_driver *drv, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "NAME DI_pin,DO_pin,CLK_pin,CS_pin [MODE]\n"); -} - -static ssize_t gpiommc_add_store(struct device_driver *drv, - const char *buf, size_t count) -{ - int res, err; - char name[GPIOMMC_MAX_NAMELEN + 1]; - struct gpiommc_pins pins; - unsigned int mode; - - res = sscanf(buf, "%" GPIOMMC_MAX_NAMELEN_STR "s %u,%u,%u,%u %u", - name, &pins.gpio_di, &pins.gpio_do, - &pins.gpio_clk, &pins.gpio_cs, &mode); - if (res == 5) - mode = 0; - else if (res != 6) - return -EINVAL; - switch (mode) { - case 0: - mode = SPI_MODE_0; - break; - case 1: - mode = SPI_MODE_1; - break; - case 2: - mode = SPI_MODE_2; - break; - case 3: - mode = SPI_MODE_3; - break; - default: - return -EINVAL; - } - err = gpiommc_create_device(name, &pins, mode); - - return err ? err : count; -} - -static ssize_t gpiommc_remove_show(struct device_driver *drv, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "write device-name to remove the device\n"); -} - -static ssize_t gpiommc_remove_store(struct device_driver *drv, - const char *buf, size_t count) -{ - int err; - - err = gpiommc_destroy_device(buf); - - return err ? err : count; -} - -static DRIVER_ATTR(add, 0600, - gpiommc_add_show, gpiommc_add_store); -static DRIVER_ATTR(remove, 0600, - gpiommc_remove_show, gpiommc_remove_store); - -static struct platform_driver gpiommc_plat_driver = { - .probe = gpiommc_probe, - .remove = gpiommc_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init gpiommc_modinit(void) -{ - int err; - - err = platform_driver_register(&gpiommc_plat_driver); - if (err) - return err; - err = driver_create_file(&gpiommc_plat_driver.driver, - &driver_attr_add); - if (err) - goto err_drv_unreg; - err = driver_create_file(&gpiommc_plat_driver.driver, - &driver_attr_remove); - if (err) - goto err_remove_add; - - return 0; - -err_remove_add: - driver_remove_file(&gpiommc_plat_driver.driver, - &driver_attr_add); -err_drv_unreg: - platform_driver_unregister(&gpiommc_plat_driver); - return err; -} -module_init(gpiommc_modinit); - -static void __exit gpiommc_modexit(void) -{ - struct gpiommc_device *d, *tmp; - - driver_remove_file(&gpiommc_plat_driver.driver, - &driver_attr_remove); - driver_remove_file(&gpiommc_plat_driver.driver, - &driver_attr_add); - - mutex_lock(&gpiommc_mutex); - list_for_each_entry_safe(d, tmp, &gpiommc_devices_list, list) - gpiommc_do_destroy_device(d); - mutex_unlock(&gpiommc_mutex); - - platform_driver_unregister(&gpiommc_plat_driver); -} -module_exit(gpiommc_modexit); |