2 * Driver for driving an MMC card over a bitbanging GPIO SPI bus.
4 * Copyright 2008 Michael Buesch <mb@bu3sch.de>
6 * Licensed under the GNU/GPL. See COPYING for details.
9 #include <linux/platform_device.h>
10 #include <linux/list.h>
11 #include <linux/mutex.h>
12 #include <linux/spi/spi_gpio.h>
15 /* This is the maximum speed in Hz */
16 #define GPIOMMC_MAXSPEED 5000000 /* Hz */
19 #define DRIVER_NAME "spi-gpio-mmc"
20 #define PFX DRIVER_NAME ": "
23 #define GPIOMMC_MAX_NAMELEN 15
24 #define GPIOMMC_MAX_NAMELEN_STR __stringify(GPIOMMC_MAX_NAMELEN)
27 unsigned int gpio_di
; /* Card DI pin */
28 unsigned int gpio_do
; /* Card DO pin */
29 unsigned int gpio_clk
; /* Card CLK pin */
30 unsigned int gpio_cs
; /* Card CS pin */
33 struct gpiommc_device
{
34 char name
[GPIOMMC_MAX_NAMELEN
+ 1];
35 struct platform_device
*pdev
;
36 struct platform_device
*spi_pdev
;
37 struct gpiommc_pins pins
;
38 u8 mode
; /* SPI_MODE_X */
39 struct spi_board_info boardinfo
;
41 struct list_head list
;
45 static LIST_HEAD(gpiommc_devices_list
);
46 static DEFINE_MUTEX(gpiommc_mutex
);
49 MODULE_DESCRIPTION("SPI-GPIO based MMC driver");
50 MODULE_AUTHOR("Michael Buesch");
51 MODULE_LICENSE("GPL");
54 static int gpiommc_boardinfo_setup(struct spi_board_info
*bi
,
55 struct spi_master
*master
,
58 struct gpiommc_device
*d
= data
;
60 /* Bind the SPI master to the MMC-SPI host driver. */
61 strlcpy(bi
->modalias
, "mmc_spi", sizeof(bi
->modalias
));
63 bi
->max_speed_hz
= GPIOMMC_MAXSPEED
;
64 bi
->bus_num
= master
->bus_num
;
70 static int gpiommc_probe(struct platform_device
*pdev
)
73 struct gpiommc_device
*d
= platform_get_drvdata(pdev
);
74 struct spi_gpio_platform_data pdata
;
77 d
->spi_pdev
= platform_device_alloc("spi-gpio", instance
++);
81 memset(&pdata
, 0, sizeof(pdata
));
82 pdata
.pin_clk
= d
->pins
.gpio_clk
;
83 pdata
.pin_miso
= d
->pins
.gpio_do
;
84 pdata
.pin_mosi
= d
->pins
.gpio_di
;
85 pdata
.pin_cs
= d
->pins
.gpio_cs
;
86 pdata
.cs_activelow
= 1;
87 pdata
.no_spi_delay
= 1;
88 pdata
.boardinfo_setup
= gpiommc_boardinfo_setup
;
89 pdata
.boardinfo_setup_data
= d
;
91 err
= platform_device_add_data(d
->spi_pdev
, &pdata
, sizeof(pdata
));
94 err
= platform_device_register(d
->spi_pdev
);
98 printk(KERN_INFO PFX
"MMC-Card \"%s\" "
99 "attached to GPIO pins %u,%u,%u,%u\n",
100 d
->name
, d
->pins
.gpio_di
, d
->pins
.gpio_do
,
101 d
->pins
.gpio_clk
, d
->pins
.gpio_cs
);
106 kfree(d
->spi_pdev
->dev
.platform_data
);
107 d
->spi_pdev
->dev
.platform_data
= NULL
;
109 platform_device_put(d
->spi_pdev
);
113 static int gpiommc_remove(struct platform_device
*pdev
)
115 struct gpiommc_device
*d
= platform_get_drvdata(pdev
);
117 platform_device_unregister(d
->spi_pdev
);
118 printk(KERN_INFO PFX
"MMC-Card \"%s\" removed\n", d
->name
);
123 static void gpiommc_free(struct gpiommc_device
*d
)
128 static struct gpiommc_device
* gpiommc_alloc(struct platform_device
*pdev
,
130 const struct gpiommc_pins
*pins
,
133 struct gpiommc_device
*d
;
135 d
= kmalloc(sizeof(*d
), GFP_KERNEL
);
139 strcpy(d
->name
, name
);
140 memcpy(&d
->pins
, pins
, sizeof(d
->pins
));
142 INIT_LIST_HEAD(&d
->list
);
147 /* List must be locked. */
148 static struct gpiommc_device
* gpiommc_find_device(const char *name
)
150 struct gpiommc_device
*d
;
152 list_for_each_entry(d
, &gpiommc_devices_list
, list
) {
153 if (strcmp(d
->name
, name
) == 0)
160 static void gpiommc_do_destroy_device(struct gpiommc_device
*d
)
163 platform_device_unregister(d
->pdev
);
167 static int gpiommc_destroy_device(const char *name
)
169 struct gpiommc_device
*d
;
172 mutex_lock(&gpiommc_mutex
);
173 d
= gpiommc_find_device(name
);
176 gpiommc_do_destroy_device(d
);
179 mutex_unlock(&gpiommc_mutex
);
184 static int gpiommc_create_device(const char *name
,
185 const struct gpiommc_pins
*pins
,
189 struct platform_device
*pdev
;
190 struct gpiommc_device
*d
;
193 mutex_lock(&gpiommc_mutex
);
195 if (gpiommc_find_device(name
))
198 pdev
= platform_device_alloc(DRIVER_NAME
, instance
++);
201 d
= gpiommc_alloc(pdev
, name
, pins
, mode
);
204 platform_set_drvdata(pdev
, d
);
206 err
= platform_device_register(pdev
);
209 list_add(&d
->list
, &gpiommc_devices_list
);
213 mutex_unlock(&gpiommc_mutex
);
220 platform_device_put(pdev
);
224 static ssize_t
gpiommc_add_show(struct device_driver
*drv
,
227 return snprintf(buf
, PAGE_SIZE
, "NAME DI_pin,DO_pin,CLK_pin,CS_pin [MODE]\n");
230 static ssize_t
gpiommc_add_store(struct device_driver
*drv
,
231 const char *buf
, size_t count
)
234 char name
[GPIOMMC_MAX_NAMELEN
+ 1];
235 struct gpiommc_pins pins
;
238 res
= sscanf(buf
, "%" GPIOMMC_MAX_NAMELEN_STR
"s %u,%u,%u,%u %u",
239 name
, &pins
.gpio_di
, &pins
.gpio_do
,
240 &pins
.gpio_clk
, &pins
.gpio_cs
, &mode
);
261 err
= gpiommc_create_device(name
, &pins
, mode
);
263 return err
? err
: count
;
266 static ssize_t
gpiommc_remove_show(struct device_driver
*drv
,
269 return snprintf(buf
, PAGE_SIZE
, "write device-name to remove the device\n");
272 static ssize_t
gpiommc_remove_store(struct device_driver
*drv
,
273 const char *buf
, size_t count
)
277 err
= gpiommc_destroy_device(buf
);
279 return err
? err
: count
;
282 static DRIVER_ATTR(add
, 0600,
283 gpiommc_add_show
, gpiommc_add_store
);
284 static DRIVER_ATTR(remove
, 0600,
285 gpiommc_remove_show
, gpiommc_remove_store
);
287 static struct platform_driver gpiommc_plat_driver
= {
288 .probe
= gpiommc_probe
,
289 .remove
= gpiommc_remove
,
292 .owner
= THIS_MODULE
,
296 static int __init
gpiommc_modinit(void)
300 err
= platform_driver_register(&gpiommc_plat_driver
);
303 err
= driver_create_file(&gpiommc_plat_driver
.driver
,
307 err
= driver_create_file(&gpiommc_plat_driver
.driver
,
308 &driver_attr_remove
);
315 driver_remove_file(&gpiommc_plat_driver
.driver
,
318 platform_driver_unregister(&gpiommc_plat_driver
);
321 module_init(gpiommc_modinit
);
323 static void __exit
gpiommc_modexit(void)
325 struct gpiommc_device
*d
, *tmp
;
327 driver_remove_file(&gpiommc_plat_driver
.driver
,
328 &driver_attr_remove
);
329 driver_remove_file(&gpiommc_plat_driver
.driver
,
332 mutex_lock(&gpiommc_mutex
);
333 list_for_each_entry_safe(d
, tmp
, &gpiommc_devices_list
, list
)
334 gpiommc_do_destroy_device(d
);
335 mutex_unlock(&gpiommc_mutex
);
337 platform_driver_unregister(&gpiommc_plat_driver
);
339 module_exit(gpiommc_modexit
);