source: trunk/target/linux/generic-2.6/patches-2.6.34/922-gpiommc.patch @ 20999

Last change on this file since 20999 was 20999, checked in by hauke, 7 years ago

kernel: refresh patches with 2.6.34-rc4

File size: 22.4 KB
  • new file drivers/mmc/host/gpiommc.c

    - +  
     1/* 
     2 * Driver an MMC/SD card on a bitbanging GPIO SPI bus. 
     3 * This module hooks up the mmc_spi and spi_gpio modules and also 
     4 * provides a configfs interface. 
     5 * 
     6 * Copyright 2008 Michael Buesch <mb@bu3sch.de> 
     7 * 
     8 * Licensed under the GNU/GPL. See COPYING for details. 
     9 */ 
     10 
     11#include <linux/mmc/gpiommc.h> 
     12#include <linux/platform_device.h> 
     13#include <linux/list.h> 
     14#include <linux/mutex.h> 
     15#include <linux/spi/spi_gpio_old.h> 
     16#include <linux/configfs.h> 
     17#include <linux/gpio.h> 
     18#include <asm/atomic.h> 
     19 
     20 
     21#define PFX                             "gpio-mmc: " 
     22 
     23 
     24struct gpiommc_device { 
     25        struct platform_device *pdev; 
     26        struct platform_device *spi_pdev; 
     27        struct spi_board_info boardinfo; 
     28}; 
     29 
     30 
     31MODULE_DESCRIPTION("GPIO based MMC driver"); 
     32MODULE_AUTHOR("Michael Buesch"); 
     33MODULE_LICENSE("GPL"); 
     34 
     35 
     36static int gpiommc_boardinfo_setup(struct spi_board_info *bi, 
     37                                   struct spi_master *master, 
     38                                   void *data) 
     39{ 
     40        struct gpiommc_device *d = data; 
     41        struct gpiommc_platform_data *pdata = d->pdev->dev.platform_data; 
     42 
     43        /* Bind the SPI master to the MMC-SPI host driver. */ 
     44        strlcpy(bi->modalias, "mmc_spi", sizeof(bi->modalias)); 
     45 
     46        bi->max_speed_hz = pdata->max_bus_speed; 
     47        bi->bus_num = master->bus_num; 
     48        bi->mode = pdata->mode; 
     49 
     50        return 0; 
     51} 
     52 
     53static int gpiommc_probe(struct platform_device *pdev) 
     54{ 
     55        struct gpiommc_platform_data *mmc_pdata = pdev->dev.platform_data; 
     56        struct spi_gpio_platform_data spi_pdata; 
     57        struct gpiommc_device *d; 
     58        int err; 
     59 
     60        err = -ENXIO; 
     61        if (!mmc_pdata) 
     62                goto error; 
     63 
     64#ifdef CONFIG_MMC_SPI_MODULE 
     65        err = request_module("mmc_spi"); 
     66        if (err) { 
     67                printk(KERN_WARNING PFX 
     68                       "Failed to request mmc_spi module.\n"); 
     69        } 
     70#endif /* CONFIG_MMC_SPI_MODULE */ 
     71 
     72        /* Allocate the GPIO-MMC device */ 
     73        err = -ENOMEM; 
     74        d = kzalloc(sizeof(*d), GFP_KERNEL); 
     75        if (!d) 
     76                goto error; 
     77        d->pdev = pdev; 
     78 
     79        /* Create the SPI-GPIO device */ 
     80        d->spi_pdev = platform_device_alloc(SPI_GPIO_PLATDEV_NAME, 
     81                                            spi_gpio_next_id()); 
     82        if (!d->spi_pdev) 
     83                goto err_free_d; 
     84 
     85        memset(&spi_pdata, 0, sizeof(spi_pdata)); 
     86        spi_pdata.pin_clk = mmc_pdata->pins.gpio_clk; 
     87        spi_pdata.pin_miso = mmc_pdata->pins.gpio_do; 
     88        spi_pdata.pin_mosi = mmc_pdata->pins.gpio_di; 
     89        spi_pdata.pin_cs = mmc_pdata->pins.gpio_cs; 
     90        spi_pdata.cs_activelow = mmc_pdata->pins.cs_activelow; 
     91        spi_pdata.no_spi_delay = mmc_pdata->no_spi_delay; 
     92        spi_pdata.boardinfo_setup = gpiommc_boardinfo_setup; 
     93        spi_pdata.boardinfo_setup_data = d; 
     94 
     95        err = platform_device_add_data(d->spi_pdev, &spi_pdata, 
     96                                       sizeof(spi_pdata)); 
     97        if (err) 
     98                goto err_free_pdev; 
     99        err = platform_device_add(d->spi_pdev); 
     100        if (err) 
     101                goto err_free_pdata; 
     102        platform_set_drvdata(pdev, d); 
     103 
     104        printk(KERN_INFO PFX "MMC-Card \"%s\" " 
     105               "attached to GPIO pins di=%u, do=%u, clk=%u, cs=%u\n", 
     106               mmc_pdata->name, mmc_pdata->pins.gpio_di, 
     107               mmc_pdata->pins.gpio_do, 
     108               mmc_pdata->pins.gpio_clk, 
     109               mmc_pdata->pins.gpio_cs); 
     110 
     111        return 0; 
     112 
     113err_free_pdata: 
     114        kfree(d->spi_pdev->dev.platform_data); 
     115        d->spi_pdev->dev.platform_data = NULL; 
     116err_free_pdev: 
     117        platform_device_put(d->spi_pdev); 
     118err_free_d: 
     119        kfree(d); 
     120error: 
     121        return err; 
     122} 
     123 
     124static int gpiommc_remove(struct platform_device *pdev) 
     125{ 
     126        struct gpiommc_device *d = platform_get_drvdata(pdev); 
     127        struct gpiommc_platform_data *pdata = d->pdev->dev.platform_data; 
     128 
     129        platform_device_unregister(d->spi_pdev); 
     130        printk(KERN_INFO PFX "GPIO based MMC-Card \"%s\" removed\n", 
     131               pdata->name); 
     132        platform_device_put(d->spi_pdev); 
     133 
     134        return 0; 
     135} 
     136 
     137#ifdef CONFIG_GPIOMMC_CONFIGFS 
     138 
     139/* A device that was created through configfs */ 
     140struct gpiommc_configfs_device { 
     141        struct config_item item; 
     142        /* The platform device, after registration. */ 
     143        struct platform_device *pdev; 
     144        /* The configuration */ 
     145        struct gpiommc_platform_data pdata; 
     146}; 
     147 
     148#define GPIO_INVALID    -1 
     149 
     150static inline bool gpiommc_is_registered(struct gpiommc_configfs_device *dev) 
     151{ 
     152        return (dev->pdev != NULL); 
     153} 
     154 
     155static inline struct gpiommc_configfs_device *ci_to_gpiommc(struct config_item *item) 
     156{ 
     157        return item ? container_of(item, struct gpiommc_configfs_device, item) : NULL; 
     158} 
     159 
     160static struct configfs_attribute gpiommc_attr_DI = { 
     161        .ca_owner = THIS_MODULE, 
     162        .ca_name = "gpio_data_in", 
     163        .ca_mode = S_IRUGO | S_IWUSR, 
     164}; 
     165 
     166static struct configfs_attribute gpiommc_attr_DO = { 
     167        .ca_owner = THIS_MODULE, 
     168        .ca_name = "gpio_data_out", 
     169        .ca_mode = S_IRUGO | S_IWUSR, 
     170}; 
     171 
     172static struct configfs_attribute gpiommc_attr_CLK = { 
     173        .ca_owner = THIS_MODULE, 
     174        .ca_name = "gpio_clock", 
     175        .ca_mode = S_IRUGO | S_IWUSR, 
     176}; 
     177 
     178static struct configfs_attribute gpiommc_attr_CS = { 
     179        .ca_owner = THIS_MODULE, 
     180        .ca_name = "gpio_chipselect", 
     181        .ca_mode = S_IRUGO | S_IWUSR, 
     182}; 
     183 
     184static struct configfs_attribute gpiommc_attr_CS_activelow = { 
     185        .ca_owner = THIS_MODULE, 
     186        .ca_name = "gpio_chipselect_activelow", 
     187        .ca_mode = S_IRUGO | S_IWUSR, 
     188}; 
     189 
     190static struct configfs_attribute gpiommc_attr_spimode = { 
     191        .ca_owner = THIS_MODULE, 
     192        .ca_name = "spi_mode", 
     193        .ca_mode = S_IRUGO | S_IWUSR, 
     194}; 
     195 
     196static struct configfs_attribute gpiommc_attr_spidelay = { 
     197        .ca_owner = THIS_MODULE, 
     198        .ca_name = "spi_delay", 
     199        .ca_mode = S_IRUGO | S_IWUSR, 
     200}; 
     201 
     202static struct configfs_attribute gpiommc_attr_max_bus_speed = { 
     203        .ca_owner = THIS_MODULE, 
     204        .ca_name = "max_bus_speed", 
     205        .ca_mode = S_IRUGO | S_IWUSR, 
     206}; 
     207 
     208static struct configfs_attribute gpiommc_attr_register = { 
     209        .ca_owner = THIS_MODULE, 
     210        .ca_name = "register", 
     211        .ca_mode = S_IRUGO | S_IWUSR, 
     212}; 
     213 
     214static struct configfs_attribute *gpiommc_config_attrs[] = { 
     215        &gpiommc_attr_DI, 
     216        &gpiommc_attr_DO, 
     217        &gpiommc_attr_CLK, 
     218        &gpiommc_attr_CS, 
     219        &gpiommc_attr_CS_activelow, 
     220        &gpiommc_attr_spimode, 
     221        &gpiommc_attr_spidelay, 
     222        &gpiommc_attr_max_bus_speed, 
     223        &gpiommc_attr_register, 
     224        NULL, 
     225}; 
     226 
     227static ssize_t gpiommc_config_attr_show(struct config_item *item, 
     228                                        struct configfs_attribute *attr, 
     229                                        char *page) 
     230{ 
     231        struct gpiommc_configfs_device *dev = ci_to_gpiommc(item); 
     232        ssize_t count = 0; 
     233        unsigned int gpio; 
     234        int err = 0; 
     235 
     236        if (attr == &gpiommc_attr_DI) { 
     237                gpio = dev->pdata.pins.gpio_di; 
     238                if (gpio == GPIO_INVALID) 
     239                        count = snprintf(page, PAGE_SIZE, "not configured\n"); 
     240                else 
     241                        count = snprintf(page, PAGE_SIZE, "%u\n", gpio); 
     242                goto out; 
     243        } 
     244        if (attr == &gpiommc_attr_DO) { 
     245                gpio = dev->pdata.pins.gpio_do; 
     246                if (gpio == GPIO_INVALID) 
     247                        count = snprintf(page, PAGE_SIZE, "not configured\n"); 
     248                else 
     249                        count = snprintf(page, PAGE_SIZE, "%u\n", gpio); 
     250                goto out; 
     251        } 
     252        if (attr == &gpiommc_attr_CLK) { 
     253                gpio = dev->pdata.pins.gpio_clk; 
     254                if (gpio == GPIO_INVALID) 
     255                        count = snprintf(page, PAGE_SIZE, "not configured\n"); 
     256                else 
     257                        count = snprintf(page, PAGE_SIZE, "%u\n", gpio); 
     258                goto out; 
     259        } 
     260        if (attr == &gpiommc_attr_CS) { 
     261                gpio = dev->pdata.pins.gpio_cs; 
     262                if (gpio == GPIO_INVALID) 
     263                        count = snprintf(page, PAGE_SIZE, "not configured\n"); 
     264                else 
     265                        count = snprintf(page, PAGE_SIZE, "%u\n", gpio); 
     266                goto out; 
     267        } 
     268        if (attr == &gpiommc_attr_CS_activelow) { 
     269                count = snprintf(page, PAGE_SIZE, "%u\n", 
     270                                 dev->pdata.pins.cs_activelow); 
     271                goto out; 
     272        } 
     273        if (attr == &gpiommc_attr_spimode) { 
     274                count = snprintf(page, PAGE_SIZE, "%u\n", 
     275                                 dev->pdata.mode); 
     276                goto out; 
     277        } 
     278        if (attr == &gpiommc_attr_spidelay) { 
     279                count = snprintf(page, PAGE_SIZE, "%u\n", 
     280                                 !dev->pdata.no_spi_delay); 
     281                goto out; 
     282        } 
     283        if (attr == &gpiommc_attr_max_bus_speed) { 
     284                count = snprintf(page, PAGE_SIZE, "%u\n", 
     285                                 dev->pdata.max_bus_speed); 
     286                goto out; 
     287        } 
     288        if (attr == &gpiommc_attr_register) { 
     289                count = snprintf(page, PAGE_SIZE, "%u\n", 
     290                                 gpiommc_is_registered(dev)); 
     291                goto out; 
     292        } 
     293        WARN_ON(1); 
     294        err = -ENOSYS; 
     295out: 
     296        return err ? err : count; 
     297} 
     298 
     299static int gpiommc_do_register(struct gpiommc_configfs_device *dev, 
     300                               const char *name) 
     301{ 
     302        int err; 
     303 
     304        if (gpiommc_is_registered(dev)) 
     305                return 0; 
     306 
     307        if (!gpio_is_valid(dev->pdata.pins.gpio_di) || 
     308            !gpio_is_valid(dev->pdata.pins.gpio_do) || 
     309            !gpio_is_valid(dev->pdata.pins.gpio_clk) || 
     310            !gpio_is_valid(dev->pdata.pins.gpio_cs)) { 
     311                printk(KERN_ERR PFX 
     312                       "configfs: Invalid GPIO pin number(s)\n"); 
     313                return -EINVAL; 
     314        } 
     315 
     316        strlcpy(dev->pdata.name, name, 
     317                sizeof(dev->pdata.name)); 
     318 
     319        dev->pdev = platform_device_alloc(GPIOMMC_PLATDEV_NAME, 
     320                                          gpiommc_next_id()); 
     321        if (!dev->pdev) 
     322                return -ENOMEM; 
     323        err = platform_device_add_data(dev->pdev, &dev->pdata, 
     324                                       sizeof(dev->pdata)); 
     325        if (err) { 
     326                platform_device_put(dev->pdev); 
     327                return err; 
     328        } 
     329        err = platform_device_add(dev->pdev); 
     330        if (err) { 
     331                platform_device_put(dev->pdev); 
     332                return err; 
     333        } 
     334 
     335        return 0; 
     336} 
     337 
     338static void gpiommc_do_unregister(struct gpiommc_configfs_device *dev) 
     339{ 
     340        if (!gpiommc_is_registered(dev)) 
     341                return; 
     342 
     343        platform_device_unregister(dev->pdev); 
     344        dev->pdev = NULL; 
     345} 
     346 
     347static ssize_t gpiommc_config_attr_store(struct config_item *item, 
     348                                         struct configfs_attribute *attr, 
     349                                         const char *page, size_t count) 
     350{ 
     351        struct gpiommc_configfs_device *dev = ci_to_gpiommc(item); 
     352        int err = -EINVAL; 
     353        unsigned long data; 
     354 
     355        if (attr == &gpiommc_attr_register) { 
     356                err = strict_strtoul(page, 10, &data); 
     357                if (err) 
     358                        goto out; 
     359                err = -EINVAL; 
     360                if (data == 1) 
     361                        err = gpiommc_do_register(dev, item->ci_name); 
     362                if (data == 0) { 
     363                        gpiommc_do_unregister(dev); 
     364                        err = 0; 
     365                } 
     366                goto out; 
     367        } 
     368 
     369        if (gpiommc_is_registered(dev)) { 
     370                /* The rest of the config parameters can only be set 
     371                 * as long as the device is not registered, yet. */ 
     372                err = -EBUSY; 
     373                goto out; 
     374        } 
     375 
     376        if (attr == &gpiommc_attr_DI) { 
     377                err = strict_strtoul(page, 10, &data); 
     378                if (err) 
     379                        goto out; 
     380                err = -EINVAL; 
     381                if (!gpio_is_valid(data)) 
     382                        goto out; 
     383                dev->pdata.pins.gpio_di = data; 
     384                err = 0; 
     385                goto out; 
     386        } 
     387        if (attr == &gpiommc_attr_DO) { 
     388                err = strict_strtoul(page, 10, &data); 
     389                if (err) 
     390                        goto out; 
     391                err = -EINVAL; 
     392                if (!gpio_is_valid(data)) 
     393                        goto out; 
     394                dev->pdata.pins.gpio_do = data; 
     395                err = 0; 
     396                goto out; 
     397        } 
     398        if (attr == &gpiommc_attr_CLK) { 
     399                err = strict_strtoul(page, 10, &data); 
     400                if (err) 
     401                        goto out; 
     402                err = -EINVAL; 
     403                if (!gpio_is_valid(data)) 
     404                        goto out; 
     405                dev->pdata.pins.gpio_clk = data; 
     406                err = 0; 
     407                goto out; 
     408        } 
     409        if (attr == &gpiommc_attr_CS) { 
     410                err = strict_strtoul(page, 10, &data); 
     411                if (err) 
     412                        goto out; 
     413                err = -EINVAL; 
     414                if (!gpio_is_valid(data)) 
     415                        goto out; 
     416                dev->pdata.pins.gpio_cs = data; 
     417                err = 0; 
     418                goto out; 
     419        } 
     420        if (attr == &gpiommc_attr_CS_activelow) { 
     421                err = strict_strtoul(page, 10, &data); 
     422                if (err) 
     423                        goto out; 
     424                err = -EINVAL; 
     425                if (data != 0 && data != 1) 
     426                        goto out; 
     427                dev->pdata.pins.cs_activelow = data; 
     428                err = 0; 
     429                goto out; 
     430        } 
     431        if (attr == &gpiommc_attr_spimode) { 
     432                err = strict_strtoul(page, 10, &data); 
     433                if (err) 
     434                        goto out; 
     435                err = -EINVAL; 
     436                switch (data) { 
     437                case 0: 
     438                        dev->pdata.mode = SPI_MODE_0; 
     439                        break; 
     440                case 1: 
     441                        dev->pdata.mode = SPI_MODE_1; 
     442                        break; 
     443                case 2: 
     444                        dev->pdata.mode = SPI_MODE_2; 
     445                        break; 
     446                case 3: 
     447                        dev->pdata.mode = SPI_MODE_3; 
     448                        break; 
     449                default: 
     450                        goto out; 
     451                } 
     452                err = 0; 
     453                goto out; 
     454        } 
     455        if (attr == &gpiommc_attr_spidelay) { 
     456                err = strict_strtoul(page, 10, &data); 
     457                if (err) 
     458                        goto out; 
     459                err = -EINVAL; 
     460                if (data != 0 && data != 1) 
     461                        goto out; 
     462                dev->pdata.no_spi_delay = !data; 
     463                err = 0; 
     464                goto out; 
     465        } 
     466        if (attr == &gpiommc_attr_max_bus_speed) { 
     467                err = strict_strtoul(page, 10, &data); 
     468                if (err) 
     469                        goto out; 
     470                err = -EINVAL; 
     471                if (data > UINT_MAX) 
     472                        goto out; 
     473                dev->pdata.max_bus_speed = data; 
     474                err = 0; 
     475                goto out; 
     476        } 
     477        WARN_ON(1); 
     478        err = -ENOSYS; 
     479out: 
     480        return err ? err : count; 
     481} 
     482 
     483static void gpiommc_config_item_release(struct config_item *item) 
     484{ 
     485        struct gpiommc_configfs_device *dev = ci_to_gpiommc(item); 
     486 
     487        kfree(dev); 
     488} 
     489 
     490static struct configfs_item_operations gpiommc_config_item_ops = { 
     491        .release                = gpiommc_config_item_release, 
     492        .show_attribute         = gpiommc_config_attr_show, 
     493        .store_attribute        = gpiommc_config_attr_store, 
     494}; 
     495 
     496static struct config_item_type gpiommc_dev_ci_type = { 
     497        .ct_item_ops    = &gpiommc_config_item_ops, 
     498        .ct_attrs       = gpiommc_config_attrs, 
     499        .ct_owner       = THIS_MODULE, 
     500}; 
     501 
     502static struct config_item *gpiommc_make_item(struct config_group *group, 
     503                                             const char *name) 
     504{ 
     505        struct gpiommc_configfs_device *dev; 
     506 
     507        if (strlen(name) > GPIOMMC_MAX_NAMELEN) { 
     508                printk(KERN_ERR PFX "configfs: device name too long\n"); 
     509                return NULL; 
     510        } 
     511 
     512        dev = kzalloc(sizeof(*dev), GFP_KERNEL); 
     513        if (!dev) 
     514                return NULL; 
     515 
     516        config_item_init_type_name(&dev->item, name, 
     517                                   &gpiommc_dev_ci_type); 
     518 
     519        /* Assign default configuration */ 
     520        dev->pdata.pins.gpio_di = GPIO_INVALID; 
     521        dev->pdata.pins.gpio_do = GPIO_INVALID; 
     522        dev->pdata.pins.gpio_clk = GPIO_INVALID; 
     523        dev->pdata.pins.gpio_cs = GPIO_INVALID; 
     524        dev->pdata.pins.cs_activelow = 1; 
     525        dev->pdata.mode = SPI_MODE_0; 
     526        dev->pdata.no_spi_delay = 0; 
     527        dev->pdata.max_bus_speed = 5000000; /* 5 MHz */ 
     528 
     529        return &(dev->item); 
     530} 
     531 
     532static void gpiommc_drop_item(struct config_group *group, 
     533                              struct config_item *item) 
     534{ 
     535        struct gpiommc_configfs_device *dev = ci_to_gpiommc(item); 
     536 
     537        gpiommc_do_unregister(dev); 
     538        kfree(dev); 
     539} 
     540 
     541static struct configfs_group_operations gpiommc_ct_group_ops = { 
     542        .make_item      = gpiommc_make_item, 
     543        .drop_item      = gpiommc_drop_item, 
     544}; 
     545 
     546static struct config_item_type gpiommc_ci_type = { 
     547        .ct_group_ops   = &gpiommc_ct_group_ops, 
     548        .ct_owner       = THIS_MODULE, 
     549}; 
     550 
     551static struct configfs_subsystem gpiommc_subsys = { 
     552        .su_group = { 
     553                .cg_item = { 
     554                        .ci_namebuf = GPIOMMC_PLATDEV_NAME, 
     555                        .ci_type = &gpiommc_ci_type, 
     556                }, 
     557        }, 
     558        .su_mutex = __MUTEX_INITIALIZER(gpiommc_subsys.su_mutex), 
     559}; 
     560 
     561#endif /* CONFIG_GPIOMMC_CONFIGFS */ 
     562 
     563static struct platform_driver gpiommc_plat_driver = { 
     564        .probe  = gpiommc_probe, 
     565        .remove = gpiommc_remove, 
     566        .driver = { 
     567                .name   = GPIOMMC_PLATDEV_NAME, 
     568                .owner  = THIS_MODULE, 
     569        }, 
     570}; 
     571 
     572int gpiommc_next_id(void) 
     573{ 
     574        static atomic_t counter = ATOMIC_INIT(-1); 
     575 
     576        return atomic_inc_return(&counter); 
     577} 
     578EXPORT_SYMBOL(gpiommc_next_id); 
     579 
     580static int __init gpiommc_modinit(void) 
     581{ 
     582        int err; 
     583 
     584        err = platform_driver_register(&gpiommc_plat_driver); 
     585        if (err) 
     586                return err; 
     587 
     588#ifdef CONFIG_GPIOMMC_CONFIGFS 
     589        config_group_init(&gpiommc_subsys.su_group); 
     590        err = configfs_register_subsystem(&gpiommc_subsys); 
     591        if (err) { 
     592                platform_driver_unregister(&gpiommc_plat_driver); 
     593                return err; 
     594        } 
     595#endif /* CONFIG_GPIOMMC_CONFIGFS */ 
     596 
     597        return 0; 
     598} 
     599module_init(gpiommc_modinit); 
     600 
     601static void __exit gpiommc_modexit(void) 
     602{ 
     603#ifdef CONFIG_GPIOMMC_CONFIGFS 
     604        configfs_unregister_subsystem(&gpiommc_subsys); 
     605#endif 
     606        platform_driver_unregister(&gpiommc_plat_driver); 
     607} 
     608module_exit(gpiommc_modexit); 
  • drivers/mmc/host/Kconfig

    a b config MMC_TMIO 
    370370          This provides support for the SD/MMC cell found in TC6393XB, 
    371371          T7L66XB and also HTC ASIC3 
    372372 
     373config GPIOMMC 
     374        tristate "MMC/SD over GPIO-based SPI" 
     375        depends on MMC && MMC_SPI && SPI_GPIO_OLD 
     376        help 
     377          This driver hooks up the mmc_spi and spi_gpio modules so that 
     378          MMC/SD cards can be used on a GPIO based bus by bitbanging 
     379          the SPI protocol in software. 
     380 
     381          This driver provides a configfs interface to dynamically create 
     382          and destroy GPIO-based MMC/SD card devices. It also provides 
     383          a platform device interface API. 
     384          See Documentation/gpiommc.txt for details. 
     385 
     386          The module will be called gpiommc. 
     387 
     388          If unsure, say N. 
     389 
     390config GPIOMMC_CONFIGFS 
     391        bool 
     392        depends on GPIOMMC && CONFIGFS_FS 
     393        default y 
     394        help 
     395          This option automatically enables configfs support for gpiommc 
     396          if configfs is available. 
     397 
    373398config MMC_CB710 
    374399        tristate "ENE CB710 MMC/SD Interface support" 
    375400        depends on PCI 
  • drivers/mmc/host/Makefile

    a b obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_ 
    3333obj-$(CONFIG_MMC_TMIO)          += tmio_mmc.o 
    3434obj-$(CONFIG_MMC_CB710) += cb710-mmc.o 
    3535obj-$(CONFIG_MMC_VIA_SDMMC)     += via-sdmmc.o 
     36obj-$(CONFIG_GPIOMMC)           += gpiommc.o 
    3637obj-$(CONFIG_SDH_BFIN)          += bfin_sdh.o 
    3738 
    3839obj-$(CONFIG_MMC_SDHCI_OF)      += sdhci-of.o 
  • new file include/linux/mmc/gpiommc.h

    - +  
     1/* 
     2 * Device driver for MMC/SD cards driven over a GPIO bus. 
     3 * 
     4 * Copyright (c) 2008 Michael Buesch 
     5 * 
     6 * Licensed under the GNU/GPL version 2. 
     7 */ 
     8#ifndef LINUX_GPIOMMC_H_ 
     9#define LINUX_GPIOMMC_H_ 
     10 
     11#include <linux/types.h> 
     12 
     13 
     14#define GPIOMMC_MAX_NAMELEN             15 
     15#define GPIOMMC_MAX_NAMELEN_STR         __stringify(GPIOMMC_MAX_NAMELEN) 
     16 
     17/** 
     18 * struct gpiommc_pins - Hardware pin assignments 
     19 * 
     20 * @gpio_di: The GPIO number of the DATA IN pin 
     21 * @gpio_do: The GPIO number of the DATA OUT pin 
     22 * @gpio_clk: The GPIO number of the CLOCK pin 
     23 * @gpio_cs: The GPIO number of the CHIPSELECT pin 
     24 * @cs_activelow: If true, the chip is considered selected if @gpio_cs is low. 
     25 */ 
     26struct gpiommc_pins { 
     27        unsigned int gpio_di; 
     28        unsigned int gpio_do; 
     29        unsigned int gpio_clk; 
     30        unsigned int gpio_cs; 
     31        bool cs_activelow; 
     32}; 
     33 
     34/** 
     35 * struct gpiommc_platform_data - Platform data for a MMC-over-SPI-GPIO device. 
     36 * 
     37 * @name: The unique name string of the device. 
     38 * @pins: The hardware pin assignments. 
     39 * @mode: The hardware mode. This is either SPI_MODE_0, 
     40 *        SPI_MODE_1, SPI_MODE_2 or SPI_MODE_3. See the SPI documentation. 
     41 * @no_spi_delay: Do not use delays in the lowlevel SPI bitbanging code. 
     42 *                This is not standards compliant, but may be required for some 
     43 *                embedded machines to gain reasonable speed. 
     44 * @max_bus_speed: The maximum speed of the SPI bus, in Hertz. 
     45 */ 
     46struct gpiommc_platform_data { 
     47        char name[GPIOMMC_MAX_NAMELEN + 1]; 
     48        struct gpiommc_pins pins; 
     49        u8 mode; 
     50        bool no_spi_delay; 
     51        unsigned int max_bus_speed; 
     52}; 
     53 
     54/** 
     55 * GPIOMMC_PLATDEV_NAME - The platform device name string. 
     56 * 
     57 * The name string that has to be used for platform_device_alloc 
     58 * when allocating a gpiommc device. 
     59 */ 
     60#define GPIOMMC_PLATDEV_NAME    "gpiommc" 
     61 
     62/** 
     63 * gpiommc_next_id - Get another platform device ID number. 
     64 * 
     65 * This returns the next platform device ID number that has to be used 
     66 * for platform_device_alloc. The ID is opaque and should not be used for 
     67 * anything else. 
     68 */ 
     69int gpiommc_next_id(void); 
     70 
     71#endif /* LINUX_GPIOMMC_H_ */ 
  • new file Documentation/gpiommc.txt

    - +  
     1GPIOMMC - Driver for an MMC/SD card on a bitbanging GPIO SPI bus 
     2================================================================ 
     3 
     4The gpiommc module hooks up the mmc_spi and spi_gpio modules for running an 
     5MMC or SD card on GPIO pins. 
     6 
     7Two interfaces for registering a new MMC/SD card device are provided: 
     8A static platform-device based mechanism and a dynamic configfs based interface. 
     9 
     10 
     11Registering devices via platform-device 
     12======================================= 
     13 
     14The platform-device interface is used for registering MMC/SD devices that are 
     15part of the hardware platform. This is most useful only for embedded machines 
     16with MMC/SD devices statically connected to the platform GPIO bus. 
     17 
     18The data structures are declared in <linux/mmc/gpiommc.h>. 
     19 
     20To register a new device, define an instance of struct gpiommc_platform_data. 
     21This structure holds any information about how the device is hooked up to the 
     22GPIO pins and what hardware modes the device supports. See the docbook-style 
     23documentation in the header file for more information on the struct fields. 
     24 
     25Then allocate a new instance of a platform device by doing: 
     26 
     27        pdev = platform_device_alloc(GPIOMMC_PLATDEV_NAME, gpiommc_next_id()); 
     28 
     29This will allocate the platform device data structures and hook it up to the 
     30gpiommc driver. 
     31Then add the gpiommc_platform_data to the platform device. 
     32 
     33        err = platform_device_add_data(pdev, pdata, sizeof(struct gpiommc_platform_data)); 
     34 
     35You may free the local instance of struct gpiommc_platform_data now. (So the 
     36struct may be allocated on the stack, too). 
     37Now simply register the platform device. 
     38 
     39        err = platform_device_add(pdev); 
     40 
     41Done. The gpiommc probe routine will be invoked now and you should see a kernel 
     42log message for the added device. 
     43 
     44 
     45Registering devices via configfs 
     46================================ 
     47 
     48MMC/SD cards connected via GPIO often are a pretty dynamic thing, as for example 
     49selfmade hacks for soldering an MMC/SD card to standard GPIO pins on embedded 
     50hardware are a common situation. 
     51So we provide a dynamic interface to conveniently handle adding and removing 
     52devices from userspace, without the need to recompile the kernel. 
     53 
     54The "gpiommc" subdirectory at the configfs mountpoint is used for handling 
     55the dynamic configuration. 
     56 
     57To create a new device, it must first be allocated with mkdir. 
     58The following command will allocate a device named "my_mmc": 
     59        mkdir /config/gpiommc/my_mmc 
     60 
     61There are several configuration files available in the new 
     62/config/gpiommc/my_mmc/ directory: 
     63 
     64gpio_data_in                    = The SPI data-IN GPIO pin number. 
     65gpio_data_out                   = The SPI data-OUT GPIO pin number. 
     66gpio_clock                      = The SPI Clock GPIO pin number. 
     67gpio_chipselect                 = The SPI Chipselect GPIO pin number. 
     68gpio_chipselect_activelow       = Boolean. If 0, Chipselect is active-HIGH. 
     69                                  If 1, Chipselect is active-LOW. 
     70spi_mode                        = The SPI data mode. Can be 0-3. 
     71spi_delay                       = Enable all delays in the lowlevel bitbanging. 
     72max_bus_speed                   = The maximum SPI bus speed. In Hertz. 
     73 
     74register                        = Not a configuration parameter. 
     75                                  Used to register the configured card 
     76                                  with the kernel. 
     77 
     78The device must first get configured and then registered by writing "1" to 
     79the "register" file. 
     80The configuration parameters "gpio_data_in", "gpio_data_out", "gpio_clock" 
     81and "gpio_chipselect" are essential and _must_ be configured before writing 
     82"1" to the "register" file. The registration will fail, otherwise. 
     83 
     84The default values for the other parameters are: 
     85gpio_chipselect_activelow       = 1             (CS active-LOW) 
     86spi_mode                        = 0             (SPI_MODE_0) 
     87spi_delay                       = 1             (enabled) 
     88max_bus_speed                   = 5000000       (5 Mhz) 
     89 
     90Configuration values can not be changed after registration. To unregister 
     91the device, write a "0" to the "register" file. The configuration can be 
     92changed again after unregistering. 
     93 
     94To completely remove the device, simply rmdir the directory 
     95(/config/gpiommc/my_mmc in this example). 
     96There's no need to first unregister the device before removing it. That will 
     97be done automatically. 
  • MAINTAINERS

    a b T: git git://git.kernel.org/pub/scm/linu 
    25402540S:      Maintained 
    25412541F:      drivers/media/video/gspca/ 
    25422542 
     2543GPIOMMC DRIVER 
     2544P:      Michael Buesch 
     2545M:      mb@bu3sch.de 
     2546S:      Maintained 
     2547 
    25432548HARDWARE MONITORING 
    25442549L:      lm-sensors@lm-sensors.org 
    25452550W:      http://www.lm-sensors.org/ 
Note: See TracBrowser for help on using the repository browser.