3 # Patch managed by http://www.holgerschurig.de/patcher.html
7 +++ linux-2.4.27/drivers/block/mmc.c
10 + * Copyright (c) Clément Ballabriga, 2005 - GPL
11 + * Copyright (c) Guylhem Aznar, 2005 - GPL
13 + * Please check http://externe.net/zaurus/simpad-bluetooth reference design first.
15 + * Based on Madsuk/Rohde work on a MMC driver for the WRT54G.
17 + * This is an ugly hack of a driver. I am surprised if it ever works!
18 + * So please use a real driver or contribute one to the 2.4/2.6 mmc framework
21 +#include <linux/stddef.h>
22 +#include <linux/delay.h>
23 +#include <linux/timer.h>
24 +#include <linux/module.h>
25 +#include <linux/mm.h>
26 +#include <linux/init.h>
27 +#include <linux/fs.h>
28 +#include <linux/blkpg.h>
29 +#include <linux/hdreg.h>
30 +#include <linux/major.h>
32 +#include <asm/hardware.h>
33 +#include <asm/uaccess.h>
37 + * *******************************************************************
39 + * This is the only configurable part.
41 + * *******************************************************************
47 +#define DEVICE_NAME "mmc"
48 +#define DEVICE_NR(device) (MINOR(device))
49 +#define DEVICE_ON(device)
50 +#define DEVICE_OFF(device)
53 +/* Let that include where it is or compilation fails on INIT_REQUEST/CURRENT */
55 +#include <linux/blk.h>
57 +MODULE_AUTHOR("Guylhem Aznar <mmc-driver @externe.net>");
58 +MODULE_DESCRIPTION("Driver for MMC/SD-Cards in SPI mode by GPIO");
59 +MODULE_SUPPORTED_DEVICE("Simpad");
60 +MODULE_LICENSE("GPL");
62 +/* Registers should be architecture independant - but it's not ! */
64 +#define MAP_START 0x90040000
65 +#define MAP_SIZE 0x00001000
77 + * If you are using different GPIOs in your hardware hack, you must
78 + * first make sure they are unused for other functions and then
79 + * configure them here.
81 + * On the simpad I use spare pins from the UART1 (internal serial port):
82 + * - DCD (in) : GPIO 23 : DO
83 + * - DTR (out) : GPIO 07 : CS
84 + * - RI (in) : GPIO 19 : CLK
85 + * - DSR (in) : GPIO 06 : DI
87 + * Don't worry about in/out original function - the GPIOs will be
91 +#define GPIO_SD_DO 23
93 +#define GPIO_SD_CLK 19
97 + * *******************************************************************
99 + * Do not change anything below !
101 + * *******************************************************************
116 +typedef unsigned int uint32;
117 +typedef unsigned long u32_t;
118 +typedef unsigned short u16_t;
119 +typedef unsigned char u8_t;
121 +/* we have only one device */
122 +static int hd_sizes[1 << 6];
123 +static int hd_blocksizes[1 << 6];
124 +static int hd_hardsectsizes[1 << 6];
125 +static int hd_maxsect[1 << 6];
126 +static struct hd_struct hd[1 << 6];
128 +static struct timer_list mmc_timer;
130 +/* start with no card */
131 +static int mmc_media_detect = 0;
132 +static int mmc_media_changed = 1;
134 +extern struct gendisk hd_gendisk;
136 +/* Use only one global device */
137 +typedef struct gpio_s gpio_t;
139 + volatile u32_t *base;
142 +static gpio_t gp = {
143 + (void *) io_p2v(MAP_START)
147 + * *******************************************************************
149 + * Begin GPIO hardware access functions.
151 + * *******************************************************************
155 +gpio_t *gpio_open(void)
158 + tmp.base = (void *) io_p2v(MAP_START);
162 +void gpio_setdir(gpio_t * g, int num, int dir)
165 + g->base[MY_GPDR] |= (1 << num);
167 + g->base[MY_GPDR] &= ~(1 << num);
172 +void gpio_setalt(gpio_t * g, int num, int alt)
175 + g->base[MY_GAFR] |= (1 << num);
177 + g->base[MY_GAFR] &= ~(1 << num);
181 +int gpio_getdir(gpio_t * g, int num)
183 + return ((g->base[MY_GPDR] & (1 << num)) ? 1 : 0);
186 +int gpio_getalt(gpio_t * g, int num)
188 + return ((g->base[MY_GAFR] & (1 << num)) ? 1 : 0);
191 +static int gpio_read(gpio_t * g, int num)
195 + what=(g->base[MY_GPLR] & (1 << num)) ? 1 : 0;
198 + if (num == GPIO_SD_DO) {
199 + printk ("GPIO_SD_DO read: %u\n", what);
205 +static int gpio_write(gpio_t * g, int num, int val)
212 + g->base[MY_GPSR] = 1 << num;
214 + g->base[MY_GPCR] = 1 << num;
217 + check=gpio_read(g,num);
220 + printk ("Error while write to %d: found %d after writing %d\n",num, check, val);
229 + * *******************************************************************
231 + * Begin SPI hardware access functions.
233 + * *******************************************************************
236 +static int mmc_spi_media_detect(void)
238 +// FIXME: add card detection/test by SPI
243 +static int mmc_spi_hardware_init(void)
245 + /*unsigned char gpio_outen;*/
247 + printk("mmc: GPIO init\n");
250 + * gp = gpio_open(); */
252 + /* Cut existing functions */
253 + gpio_setalt(&gp, GPIO_SD_CLK, 0);
254 + gpio_setalt(&gp, GPIO_SD_DI, 0);
255 + gpio_setalt(&gp, GPIO_SD_DO, 0);
256 + gpio_setalt(&gp, GPIO_SD_CS, 0);
258 + /* Remap directions */
259 + gpio_setdir(&gp, GPIO_SD_CLK, OUTPUT);
260 + gpio_setdir(&gp, GPIO_SD_DI, OUTPUT);
261 + gpio_setdir(&gp, GPIO_SD_DO, INPUT);
262 + gpio_setdir(&gp, GPIO_SD_CS, OUTPUT);
264 + printk("mmc: initialising MMC\n");
267 + gpio_write(&gp, GPIO_SD_CLK, LOW);
268 + gpio_write(&gp, GPIO_SD_DI, LOW);
269 + gpio_write(&gp, GPIO_SD_CS, LOW);
273 +/* return what has been read, write the parameter */
275 +static unsigned char mmc_spi_readwrite(unsigned char data_out)
278 + unsigned char result = 0/*, tmp_data = 0*/;
280 + for (i = 0; i < 8; i++) {
281 + if (data_out & (0x01 << (7 - i)))
282 + gpio_write(&gp, GPIO_SD_DI, HIGH);
284 + gpio_write(&gp, GPIO_SD_DI, LOW);
286 + gpio_write(&gp, GPIO_SD_CLK, HIGH);
290 + if (gpio_read(&gp, GPIO_SD_DO) == 1)
293 + gpio_write(&gp, GPIO_SD_CLK, LOW);
299 +static int mmc_spi_card_init(void)
301 + unsigned char result = 0;
303 + unsigned long flags;
308 + printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CS), gpio_getalt(&gp, GPIO_SD_CS));
309 + printk("GPIO_SD_DI dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DI), gpio_getalt(&gp, GPIO_SD_DI));
310 + printk("GPIO_SD_DO dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DO), gpio_getalt(&gp, GPIO_SD_DO));
311 + printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CLK), gpio_getalt(&gp, GPIO_SD_CLK));
313 + printk("mmc: card init 1/2\n");
314 + gpio_write(&gp, GPIO_SD_CS, HIGH);
315 + for (i = 0; i < 20; i++)
316 + mmc_spi_readwrite(0xff);
318 + gpio_write(&gp, GPIO_SD_CS, LOW);
320 + mmc_spi_readwrite(0x40);
321 + for (i = 0; i < 4; i++)
322 + mmc_spi_readwrite(0x00);
323 + mmc_spi_readwrite(0x95);
324 + for (i = 0; i < 8; i++) {
325 + result = mmc_spi_readwrite(0xff);
326 + if (result == 0x01)
329 + gpio_write(&gp, GPIO_SD_CS, HIGH);
330 + mmc_spi_readwrite(0xff);
331 + if (result != 0x01) {
332 + printk("mmc: card init %d error\n", result);
333 + restore_flags(flags);
337 + printk("mmc: card init 2/2\n");
338 + for (j = 0; j < 10000; j++) {
339 + gpio_write(&gp, GPIO_SD_CS, LOW);
341 + mmc_spi_readwrite(0x41);
342 + for (i = 0; i < 4; i++)
343 + mmc_spi_readwrite(0x00);
344 + mmc_spi_readwrite(0xff);
345 + for (i = 0; i < 8; i++) {
346 + result = mmc_spi_readwrite(0xff);
347 + if (result == 0x00)
350 + gpio_write(&gp, GPIO_SD_CS, HIGH);
351 + mmc_spi_readwrite(0xff);
352 + if (result == 0x00) {
353 + restore_flags(flags);
354 + printk("mmc: card init 3/3\n");
358 + restore_flags(flags);
364 +static int mmc_spi_card_config(void)
366 + unsigned char result = 0;
368 + unsigned char csd[32];
369 + unsigned int c_size;
370 + unsigned int c_size_mult;
372 + unsigned int read_bl_len;
373 + unsigned int blocknr = 0;
374 + unsigned int block_len = 0;
375 + unsigned int size = 0;
377 + gpio_write(&gp, GPIO_SD_CS, LOW);
378 + for (i = 0; i < 4; i++)
379 + mmc_spi_readwrite(0xff);
380 + mmc_spi_readwrite(0x49);
381 + for (i = 0; i < 4; i++)
382 + mmc_spi_readwrite(0x00);
383 + mmc_spi_readwrite(0xff);
384 + for (i = 0; i < 8; i++) {
385 + result = mmc_spi_readwrite(0xff);
386 + if (result == 0x00)
389 + if (result != 0x00) {
390 + gpio_write(&gp, GPIO_SD_CS, HIGH);
391 + mmc_spi_readwrite(0xff);
394 + for (i = 0; i < 8; i++) {
395 + result = mmc_spi_readwrite(0xff);
396 + if (result == 0xfe)
399 + if (result != 0xfe) {
400 + gpio_write(&gp, GPIO_SD_CS, HIGH);
401 + mmc_spi_readwrite(0xff);
404 + for (i = 0; i < 16; i++) {
405 + result = mmc_spi_readwrite(0xff);
408 + for (i = 0; i < 2; i++) {
409 + result = mmc_spi_readwrite(0xff);
411 + gpio_write(&gp, GPIO_SD_CS, HIGH);
412 + mmc_spi_readwrite(0xff);
413 + if (result == 0x00)
416 + c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
418 + c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
420 + read_bl_len = csd[5] & 0x0f;
422 + mult <<= c_size_mult + 2;
423 + blocknr = (c_size + 1) * mult;
425 + block_len <<= read_bl_len;
426 + size = block_len * blocknr;
429 + for (i = 0; i < (1 << 6); i++) {
430 + hd_blocksizes[i] = 1024;
431 + hd_hardsectsizes[i] = block_len;
432 + hd_maxsect[i] = 256;
434 + hd_sizes[0] = size;
435 + hd[0].nr_sects = blocknr;
438 + printk("Size = %d, hardsectsize = %d, sectors = %d\n",
439 + size, block_len, blocknr);
446 + * *******************************************************************
448 + * End of SPI hardware access functions.
450 + * *******************************************************************
454 +static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
456 + unsigned int address;
457 + unsigned char result = 0;
458 + unsigned char ab0, ab1, ab2, ab3;
461 + address = dest_addr;
463 + ab3 = 0xff & (address >> 24);
464 + ab2 = 0xff & (address >> 16);
465 + ab1 = 0xff & (address >> 8);
466 + ab0 = 0xff & address;
467 + gpio_write(&gp, GPIO_SD_CS, LOW);
468 + for (i = 0; i < 4; i++)
469 + mmc_spi_readwrite(0xff);
470 + mmc_spi_readwrite(0x58);
471 + mmc_spi_readwrite(ab3); /* msb */
472 + mmc_spi_readwrite(ab2);
473 + mmc_spi_readwrite(ab1);
474 + mmc_spi_readwrite(ab0); /* lsb */
475 + mmc_spi_readwrite(0xff);
476 + for (i = 0; i < 8; i++) {
477 + result = mmc_spi_readwrite(0xff);
478 + if (result == 0x00)
481 + if (result != 0x00) {
482 + gpio_write(&gp, GPIO_SD_CS, HIGH);
483 + mmc_spi_readwrite(0xff);
487 + mmc_spi_readwrite(0xfe);
488 + for (i = 0; i < 512; i++)
489 + mmc_spi_readwrite(data[i]);
490 + for (i = 0; i < 2; i++)
491 + mmc_spi_readwrite(0xff);
493 + for (i = 0; i < 1000000; i++) {
494 + result = mmc_spi_readwrite(0xff);
495 + if (result == 0xff)
498 + if (result != 0xff) {
499 + gpio_write(&gp, GPIO_SD_CS, HIGH);
500 + mmc_spi_readwrite(0xff);
503 + gpio_write(&gp, GPIO_SD_CS, HIGH);
504 + mmc_spi_readwrite(0xff);
508 +static int mmc_read_block(unsigned char *data, unsigned int src_addr)
510 + unsigned int address;
511 + unsigned char result = 0;
512 + unsigned char ab0, ab1, ab2, ab3;
515 + address = src_addr;
517 + ab3 = 0xff & (address >> 24);
518 + ab2 = 0xff & (address >> 16);
519 + ab1 = 0xff & (address >> 8);
520 + ab0 = 0xff & address;
522 + gpio_write(&gp, GPIO_SD_CS, LOW);
523 + for (i = 0; i < 4; i++)
524 + mmc_spi_readwrite(0xff);
525 + mmc_spi_readwrite(0x51);
526 + mmc_spi_readwrite(ab3); /* msb */
527 + mmc_spi_readwrite(ab2);
528 + mmc_spi_readwrite(ab1);
529 + mmc_spi_readwrite(ab0); /* lsb */
531 + mmc_spi_readwrite(0xff);
532 + for (i = 0; i < 8; i++) {
533 + result = mmc_spi_readwrite(0xff);
534 + if (result == 0x00)
537 + if (result != 0x00) {
538 + gpio_write(&gp, GPIO_SD_CS, HIGH);
539 + mmc_spi_readwrite(0xff);
542 + for (i = 0; i < 100000; i++) {
543 + result = mmc_spi_readwrite(0xff);
544 + if (result == 0xfe)
547 + if (result != 0xfe) {
548 + gpio_write(&gp, GPIO_SD_CS, HIGH);
549 + mmc_spi_readwrite(0xff);
552 + for (i = 0; i < 512; i++) {
553 + result = mmc_spi_readwrite(0xff);
556 + for (i = 0; i < 2; i++) {
557 + result = mmc_spi_readwrite(0xff);
559 + gpio_write(&gp, GPIO_SD_CS, HIGH);
560 + mmc_spi_readwrite(0xff);
565 +static void mmc_request(request_queue_t * q)
567 + unsigned int mmc_address;
568 + unsigned char *buffer_address;
576 + code = 1; // Default is success
580 + hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
581 + buffer_address = CURRENT->buffer;
582 + nr_sectors = CURRENT->current_nr_sectors;
583 + cmd = CURRENT->cmd;
584 + if (((CURRENT->sector + CURRENT->current_nr_sectors +
585 + hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects)
586 + || (mmc_media_detect == 0)) {
588 + } else if (cmd == READ) {
589 + spin_unlock_irq(&io_request_lock);
590 + for (i = 0; i < nr_sectors; i++) {
591 + result = mmc_read_block(buffer_address, mmc_address);
593 + printk("mmc: error %d in mmc_read_block\n", result);
597 + mmc_address += hd_hardsectsizes[0];
598 + buffer_address += hd_hardsectsizes[0];
601 + spin_lock_irq(&io_request_lock);
602 + } else if (cmd == WRITE) {
603 + spin_unlock_irq(&io_request_lock);
604 + for (i = 0; i < nr_sectors; i++) {
605 + result = mmc_write_block(mmc_address, buffer_address);
607 + printk("mmc: error %d in mmc_write_block\n", result);
611 + mmc_address += hd_hardsectsizes[0];
612 + buffer_address += hd_hardsectsizes[0];
615 + spin_lock_irq(&io_request_lock);
624 +static int mmc_open(struct inode *inode, struct file *filp)
628 + mmc_media_detect = mmc_spi_media_detect();
630 + if (mmc_media_detect == 0)
639 +static int mmc_release(struct inode *inode, struct file *filp)
642 + fsync_dev(inode->i_rdev);
643 + invalidate_buffers(inode->i_rdev);
651 +static int mmc_revalidate(kdev_t dev)
653 + int target, max_p, start, i;
655 + mmc_media_detect = mmc_spi_media_detect();
657 + if (mmc_media_detect == 0)
660 + target = DEVICE_NR(dev);
662 + max_p = hd_gendisk.max_p;
663 + start = target << 6;
664 + for (i = max_p - 1; i >= 0; i--) {
665 + int minor = start + i;
666 + invalidate_device(MKDEV(MAJOR_NR, minor), 1);
667 + hd_gendisk.part[minor].start_sect = 0;
668 + hd_gendisk.part[minor].nr_sects = 0;
671 + grok_partitions(&hd_gendisk, target, 1 << 6, hd_sizes[0] * 2);
676 +static int mmc_ioctl(struct inode *inode, struct file *filp,
677 + unsigned int cmd, unsigned long arg)
679 + if (!inode || !inode->i_rdev)
684 + return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
685 + (unsigned long *) arg);
687 + return put_user((u64) hd[MINOR(inode->i_rdev)].
688 + nr_sects, (u64 *) arg);
690 + if (!capable(CAP_SYS_ADMIN))
693 + return mmc_revalidate(inode->i_rdev);
696 + struct hd_geometry *loc, g;
697 + loc = (struct hd_geometry *) arg;
702 + g.cylinders = hd[0].nr_sects / (4 * 16);
703 + g.start = hd[MINOR(inode->i_rdev)].start_sect;
704 + return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
707 + return blk_ioctl(inode->i_rdev, cmd, arg);
713 +static int mmc_check_media_change(kdev_t dev)
716 + if (mmc_media_changed == 1) {
717 + mmc_media_changed = 0;
724 +static struct block_device_operations mmc_bdops = {
726 + release:mmc_release,
728 +/* FIXME: add media change support
729 + * check_media_change: mmc_check_media_change,
730 + * revalidate: mmc_revalidate,
734 +static struct gendisk hd_gendisk = {
736 + major_name:DEVICE_NAME,
744 +static int mmc_init(void)
748 + result = mmc_spi_hardware_init();
751 + printk("mmc: error %d in mmc_spi_hardware_init\n", result);
755 + result = mmc_spi_card_init();
757 + // Give it an extra shot
758 + result = mmc_spi_card_init();
760 + printk("mmc: error %d in mmc_card_init\n", result);
765 + memset(hd_sizes, 0, sizeof(hd_sizes));
766 + result = mmc_spi_card_config();
768 + printk("mmc: error %d in mmc_card_config\n", result);
773 + blk_size[MAJOR_NR] = hd_sizes;
775 + memset(hd, 0, sizeof(hd));
776 + hd[0].nr_sects = hd_sizes[0] * 2;
778 + blksize_size[MAJOR_NR] = hd_blocksizes;
779 + hardsect_size[MAJOR_NR] = hd_hardsectsizes;
780 + max_sectors[MAJOR_NR] = hd_maxsect;
782 + hd_gendisk.nr_real = 1;
784 + register_disk(&hd_gendisk, MKDEV(MAJOR_NR, 0), 1 << 6,
785 + &mmc_bdops, hd_sizes[0] * 2);
790 +static void mmc_exit(void)
792 + blk_size[MAJOR_NR] = NULL;
793 + blksize_size[MAJOR_NR] = NULL;
794 + hardsect_size[MAJOR_NR] = NULL;
795 + max_sectors[MAJOR_NR] = NULL;
796 + hd[0].nr_sects = 0;
799 +static void mmc_check_media(void)
801 + int old_state, new_state;
804 + old_state = mmc_media_detect;
805 + new_state = mmc_spi_media_detect();
807 + if (old_state != new_state) {
808 + mmc_media_changed = 1;
809 + if (new_state == PRESENT) {
810 + result = mmc_init();
812 + printk("mmc: error %d in mmc_init\n", result);
818 + /* del_timer(&mmc_timer);
819 + mmc_timer.expires = jiffies + 10*HZ;
820 + add_timer(&mmc_timer); */
823 +static int __init mmc_driver_init(void)
827 + result = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
829 + printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
833 + blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);
837 + /*init_timer(&mmc_timer);
838 + mmc_timer.expires = jiffies + HZ;
839 + mmc_timer.function = (void *)mmc_check_media;
840 + add_timer(&mmc_timer); */
843 + read_ahead[MAJOR_NR] = 8;
844 + add_gendisk(&hd_gendisk);
850 +static void __exit mmc_driver_exit(void)
853 + del_timer(&mmc_timer);
855 + for (i = 0; i < (1 << 6); i++)
856 + fsync_dev(MKDEV(MAJOR_NR, i));
858 + blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
859 + del_gendisk(&hd_gendisk);
860 + devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
864 +module_init(mmc_driver_init);
865 +module_exit(mmc_driver_exit);
866 --- linux-2.4.27/drivers/block/Config.in~mmc-spi
867 +++ linux-2.4.27/drivers/block/Config.in
869 mainmenu_option next_comment
870 comment 'Block devices'
872 +tristate 'MMC SPI driver' CONFIG_BLK_DEV_MMC
873 tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
874 if [ "$CONFIG_AMIGA" = "y" ]; then
875 tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY
876 --- linux-2.4.27/drivers/block/Makefile~mmc-spi
877 +++ linux-2.4.27/drivers/block/Makefile
879 obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o
881 obj-$(CONFIG_MAC_FLOPPY) += swim3.o
882 +obj-$(CONFIG_BLK_DEV_MMC) += mmc.o
883 obj-$(CONFIG_BLK_DEV_FD) += floppy.o
884 obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
885 obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o