[package] add broadcom-sdhc - successor of broadcom-mmc (#6343)
[10.03/openwrt.git] / package / broadcom-mmc / src / mmc.c
1 #include <linux/delay.h>
2 #include <linux/timer.h>
3
4 #include <linux/module.h>
5 #include <linux/mm.h>
6 #include <linux/init.h>
7 #include <linux/fs.h>
8 #include <linux/blkpg.h>
9 #include <linux/hdreg.h>
10 #include <linux/major.h>
11 #include <asm/uaccess.h>
12 #include <asm/io.h>
13
14 #define DEVICE_NAME "mmc"
15 #define DEVICE_NR(device) (MINOR(device))
16 #define DEVICE_ON(device)
17 #define DEVICE_OFF(device)
18 #define MAJOR_NR 121
19
20 #include <linux/blk.h>
21
22 MODULE_AUTHOR("Madsuk/Rohde");
23 MODULE_DESCRIPTION("Driver MMC/SD-Cards");
24 MODULE_SUPPORTED_DEVICE("WRT54G");
25 MODULE_LICENSE("GPL");
26
27 #define SD_DI 0x20
28 #define SD_DO 0x10
29 #define SD_CLK 0x08
30 #define SD_CS 0x80
31
32 /* we have only one device */
33 static int hd_sizes[1<<6];
34 static int hd_blocksizes[1<<6];
35 static int hd_hardsectsizes[1<<6];
36 static int hd_maxsect[1<<6];
37 static struct hd_struct hd[1<<6];
38
39 static struct timer_list mmc_timer;
40 static int mmc_media_detect = 0;
41 static int mmc_media_changed = 1;
42
43 typedef unsigned int uint32;
44
45 static unsigned char port_state = 0x00;
46 static volatile uint32 *gpioaddr_input = (uint32 *)0xb8000060;
47 static volatile uint32 *gpioaddr_output = (uint32 *)0xb8000064;
48 static volatile uint32 *gpioaddr_enable = (uint32 *)0xb8000068;
49 static volatile uint32 *gpioaddr_control = (uint32 *)0xb800006c;
50
51 static void mmc_spi_cs_low(void)
52 {
53   port_state &= ~(SD_CS);
54   *gpioaddr_output = port_state;
55 }
56
57 static void mmc_spi_cs_high(void)
58 {
59   port_state |= SD_CS;
60   *gpioaddr_output = port_state;
61 }
62
63 static unsigned char mmc_spi_io(unsigned char data_out)
64 {
65   int i;
66   unsigned char result = 0, tmp_data = 0;
67   
68   for(i=0; i<8; i++) {
69     if(data_out & (0x01 << (7-i)))
70       port_state |= SD_DI;
71     else
72       port_state &= ~SD_DI;
73     
74     *gpioaddr_output = port_state;
75     port_state |= SD_CLK;
76     *gpioaddr_output = port_state;
77     
78     tmp_data = *gpioaddr_input;
79     
80     port_state &= ~SD_CLK;
81     *gpioaddr_output = port_state;
82     
83     result <<= 1;
84     
85     if(tmp_data & SD_DO)
86       result |= 1;
87   }
88   
89   return(result);
90 }
91
92 static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
93 {
94         unsigned int address;
95         unsigned char r = 0;
96         unsigned char ab0, ab1, ab2, ab3;
97         int i;
98
99         address = dest_addr;
100
101         ab3 = 0xff & (address >> 24);
102         ab2 = 0xff & (address >> 16);
103         ab1 = 0xff & (address >> 8);
104         ab0 = 0xff & address;
105         mmc_spi_cs_low();
106         for (i = 0; i < 4; i++) mmc_spi_io(0xff);
107         mmc_spi_io(0x58);
108         mmc_spi_io(ab3); /* msb */
109         mmc_spi_io(ab2);
110         mmc_spi_io(ab1);
111         mmc_spi_io(ab0); /* lsb */
112         mmc_spi_io(0xff);
113         for (i = 0; i < 8; i++)
114         {
115                 r = mmc_spi_io(0xff);
116                 if (r == 0x00) break;
117         }
118         if (r != 0x00)
119         {
120                 mmc_spi_cs_high();
121                 mmc_spi_io(0xff);
122                 return(1);
123         }
124
125         mmc_spi_io(0xfe);
126         for (i = 0; i < 512; i++) mmc_spi_io(data[i]);
127         for (i = 0; i < 2; i++) mmc_spi_io(0xff);
128
129         for (i = 0; i < 1000000; i++)
130         {
131                 r = mmc_spi_io(0xff);
132                 if (r == 0xff) break;
133         }
134         if (r != 0xff)
135         {
136                 mmc_spi_cs_high();
137                 mmc_spi_io(0xff);
138                 return(3);
139         }
140         mmc_spi_cs_high();
141         mmc_spi_io(0xff);
142         return(0);
143 }
144
145 static int mmc_read_block(unsigned char *data, unsigned int src_addr)
146 {
147         unsigned int address;
148         unsigned char r = 0;
149         unsigned char ab0, ab1, ab2, ab3;
150         int i;
151
152         address = src_addr;
153
154         ab3 = 0xff & (address >> 24);
155         ab2 = 0xff & (address >> 16);
156         ab1 = 0xff & (address >> 8);
157         ab0 = 0xff & address;
158
159         mmc_spi_cs_low();
160         for (i = 0; i < 4; i++) mmc_spi_io(0xff);
161         mmc_spi_io(0x51);
162         mmc_spi_io(ab3); /* msb */
163         mmc_spi_io(ab2);
164         mmc_spi_io(ab1);
165         mmc_spi_io(ab0); /* lsb */
166
167         mmc_spi_io(0xff);
168         for (i = 0; i < 8; i++)
169         {
170                 r = mmc_spi_io(0xff);
171                 if (r == 0x00) break;
172         }
173         if (r != 0x00)
174         {
175                 mmc_spi_cs_high();
176                 mmc_spi_io(0xff);
177                 return(1);
178         }
179         for (i = 0; i < 100000; i++)
180         {
181                 r = mmc_spi_io(0xff);
182                 if (r == 0xfe) break;
183         }
184         if (r != 0xfe)
185         {
186                 mmc_spi_cs_high();
187                 mmc_spi_io(0xff);
188                 return(2);
189         }
190         for (i = 0; i < 512; i++)
191         {
192                 r = mmc_spi_io(0xff);
193                 data[i] = r;
194         }
195         for (i = 0; i < 2; i++)
196         {
197                 r = mmc_spi_io(0xff);
198         }
199         mmc_spi_cs_high();
200         mmc_spi_io(0xff);
201
202         return(0);
203 }
204
205 static void mmc_request(request_queue_t *q)
206 {
207         unsigned int mmc_address;
208         unsigned char *buffer_address;
209         int nr_sectors;
210         int i;
211         int cmd;
212         int rc, code;
213         
214         (void)q;
215         while (1)
216         {
217                 code = 1; // Default is success
218                 INIT_REQUEST;
219                 mmc_address = (CURRENT->sector + hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
220                 buffer_address = CURRENT->buffer;
221                 nr_sectors = CURRENT->current_nr_sectors;
222                 cmd = CURRENT->cmd;
223                 if (((CURRENT->sector + CURRENT->current_nr_sectors + hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects) || (mmc_media_detect == 0))
224                 {
225                         code = 0;
226                 }
227                 else if (cmd == READ)
228                 {
229                         spin_unlock_irq(&io_request_lock);
230                         for (i = 0; i < nr_sectors; i++)
231                         {
232                                 rc = mmc_read_block(buffer_address, mmc_address);
233                                 if (rc != 0)
234                                 {
235                                         printk("mmc: error in mmc_read_block (%d)\n", rc);
236                                         code = 0;
237                                         break;
238                                 }
239                                 else
240                                 {
241                                         mmc_address += hd_hardsectsizes[0];
242                                         buffer_address += hd_hardsectsizes[0];
243                                 }
244                         }
245                         spin_lock_irq(&io_request_lock);
246                 }
247                 else if (cmd == WRITE)
248                 {
249                         spin_unlock_irq(&io_request_lock);
250                         for (i = 0; i < nr_sectors; i++)
251                         {
252                                 rc = mmc_write_block(mmc_address, buffer_address);
253                                 if (rc != 0)
254                                 {
255                                         printk("mmc: error in mmc_write_block (%d)\n", rc);
256                                         code = 0;
257                                         break;
258                                 }
259                                 else
260                                 {
261                                         mmc_address += hd_hardsectsizes[0];
262                                         buffer_address += hd_hardsectsizes[0];
263                                 }
264                         }
265                         spin_lock_irq(&io_request_lock);
266                 }
267                 else
268                 {
269                         code = 0;
270                 }
271                 end_request(code);
272         }
273 }
274
275
276 static int mmc_open(struct inode *inode, struct file *filp)
277 {
278         int device;
279         (void)filp;
280         
281         if (mmc_media_detect == 0) return -ENODEV;
282
283 #if defined(MODULE)
284         MOD_INC_USE_COUNT;
285 #endif
286         return 0;
287 }
288
289 static int mmc_release(struct inode *inode, struct file *filp)
290 {
291         (void)filp;
292         fsync_dev(inode->i_rdev);
293         invalidate_buffers(inode->i_rdev);
294
295 #if defined(MODULE)
296         MOD_DEC_USE_COUNT;
297 #endif
298         return 0;
299 }
300
301 extern struct gendisk hd_gendisk;
302 static int mmc_revalidate(kdev_t dev)
303 {
304         int target, max_p, start, i;
305         if (mmc_media_detect == 0) return -ENODEV;
306         
307         target = DEVICE_NR(dev);
308
309         max_p = hd_gendisk.max_p;
310         start = target << 6;
311         for (i = max_p - 1; i >= 0; i--) {
312                 int minor = start + i;
313                 invalidate_device(MKDEV(MAJOR_NR, minor), 1);
314                 hd_gendisk.part[minor].start_sect = 0;
315                 hd_gendisk.part[minor].nr_sects = 0;
316         }
317         
318         grok_partitions(&hd_gendisk, target, 1 << 6,
319                         hd_sizes[0] * 2);
320
321         return 0;
322 }
323
324 static int mmc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
325 {
326         if (!inode || !inode->i_rdev)
327                 return -EINVAL;
328
329         switch(cmd) {
330         case BLKGETSIZE:
331                 return put_user(hd[MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
332         case BLKGETSIZE64:
333                 return put_user((u64)hd[MINOR(inode->i_rdev)].
334                                 nr_sects, (u64 *) arg);
335         case BLKRRPART:
336                 if (!capable(CAP_SYS_ADMIN))
337                         return -EACCES;
338                         
339                 return mmc_revalidate(inode->i_rdev);
340         case HDIO_GETGEO:
341         {
342                 struct hd_geometry *loc, g;
343                 loc = (struct hd_geometry *) arg;
344                 if (!loc)
345                         return -EINVAL;
346                 g.heads = 4;
347                 g.sectors = 16;
348                 g.cylinders = hd[0].nr_sects / (4 * 16);
349                 g.start = hd[MINOR(inode->i_rdev)].start_sect;
350                 return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
351         }
352         default:
353                 return blk_ioctl(inode->i_rdev, cmd, arg);
354         }
355 }
356
357 static int mmc_card_init(void)
358 {
359         unsigned char r = 0;
360         short i, j;
361         unsigned long flags;
362
363         save_flags(flags);
364         cli();
365
366         printk("mmc Card init\n");
367         mmc_spi_cs_high();
368         for (i = 0; i < 20; i++) mmc_spi_io(0xff);
369
370         mmc_spi_cs_low();
371
372         mmc_spi_io(0x40);
373         for (i = 0; i < 4; i++) mmc_spi_io(0x00);
374         mmc_spi_io(0x95);
375         for (i = 0; i < 8; i++)
376         {
377                 r = mmc_spi_io(0xff);
378                 if (r == 0x01) break;
379         }
380         mmc_spi_cs_high();
381         mmc_spi_io(0xff);
382         if (r != 0x01)
383         {
384                 restore_flags(flags);
385                 return(1);
386         }
387
388         printk("mmc Card init *1*\n");
389         for (j = 0; j < 10000; j++)
390         {
391                 mmc_spi_cs_low();
392
393                 mmc_spi_io(0x41);
394                 for (i = 0; i < 4; i++) mmc_spi_io(0x00);
395                 mmc_spi_io(0xff);
396                 for (i = 0; i < 8; i++)
397                 {
398                         r = mmc_spi_io(0xff);
399                         if (r == 0x00) break;
400                 }
401                 mmc_spi_cs_high();
402                 mmc_spi_io(0xff);
403                 if (r == 0x00)
404                 {
405                         restore_flags(flags);
406                         printk("mmc Card init *2*\n");
407                         return(0);
408                 }
409         }
410         restore_flags(flags);
411
412         return(2);
413 }
414
415 static int mmc_card_config(void)
416 {
417         unsigned char r = 0;
418         short i;
419         unsigned char csd[32];
420         unsigned int c_size;
421         unsigned int c_size_mult;
422         unsigned int mult;
423         unsigned int read_bl_len;
424         unsigned int blocknr = 0;
425         unsigned int block_len = 0;
426         unsigned int size = 0;
427
428         mmc_spi_cs_low();
429         for (i = 0; i < 4; i++) mmc_spi_io(0xff);
430         mmc_spi_io(0x49);
431         for (i = 0; i < 4; i++) mmc_spi_io(0x00);
432         mmc_spi_io(0xff);
433         for (i = 0; i < 8; i++)
434         {
435                 r = mmc_spi_io(0xff);
436                 if (r == 0x00) break;
437         }
438         if (r != 0x00)
439         {
440                 mmc_spi_cs_high();
441                 mmc_spi_io(0xff);
442                 return(1);
443         }
444         for (i = 0; i < 8; i++)
445         {
446                 r = mmc_spi_io(0xff);
447                 if (r == 0xfe) break;
448         }
449         if (r != 0xfe)
450         {
451                 mmc_spi_cs_high();
452                 mmc_spi_io(0xff);
453                 return(2);
454         }
455         for (i = 0; i < 16; i++)
456         {
457                 r = mmc_spi_io(0xff);
458                 csd[i] = r;
459         }
460         for (i = 0; i < 2; i++)
461         {
462                 r = mmc_spi_io(0xff);
463         }
464         mmc_spi_cs_high();
465         mmc_spi_io(0xff);
466         if (r == 0x00) return(3);
467
468         c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
469         c_size >>= 6;
470         c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
471         c_size_mult >>= 7;
472         read_bl_len = csd[5] & 0x0f;
473         mult = 1;
474         mult <<= c_size_mult + 2;
475         blocknr = (c_size + 1) * mult;
476         block_len = 1;
477         block_len <<= read_bl_len;
478         size = block_len * blocknr;
479         size >>= 10;
480
481         for(i=0; i<(1<<6); i++) {
482           hd_blocksizes[i] = 1024;
483           hd_hardsectsizes[i] = block_len;
484           hd_maxsect[i] = 256;
485         }
486         hd_sizes[0] = size;
487         hd[0].nr_sects = blocknr;
488
489
490         printk("Size = %d, hardsectsize = %d, sectors = %d\n",
491                size, block_len, blocknr);
492
493         return 0;
494 }
495
496 static int mmc_hardware_init(void)
497 {
498   unsigned char gpio_outen;
499   
500   // Set inputs/outputs here
501   printk("mmc Hardware init\n");
502   gpio_outen = *gpioaddr_enable;
503   
504   gpio_outen = (gpio_outen | SD_DI | SD_CLK | SD_CS) & ~SD_DO;
505   *gpioaddr_enable = gpio_outen;
506   
507   port_state = *gpioaddr_input;
508   
509   // Clock low
510   port_state &= ~(SD_CLK | SD_DI | SD_CS);
511   *gpioaddr_output = port_state;
512
513   return 0;
514 }
515
516 static int mmc_check_media_change(kdev_t dev)
517 {
518         (void)dev;
519         if (mmc_media_changed == 1)
520         {
521                 mmc_media_changed = 0;
522                 return 1;
523         }
524         else return 0;
525 }
526
527 static struct block_device_operations mmc_bdops = 
528 {
529         open: mmc_open,
530         release: mmc_release,
531         ioctl: mmc_ioctl,
532 #if 0
533         check_media_change: mmc_check_media_change,
534         revalidate: mmc_revalidate,
535 #endif
536 };
537
538 static struct gendisk hd_gendisk = {
539         major:          MAJOR_NR,
540         major_name:     DEVICE_NAME,
541         minor_shift:    6,
542         max_p:          1 << 6,
543         part:           hd,
544         sizes:          hd_sizes,
545         fops:           &mmc_bdops,
546 };
547
548 static int mmc_init(void)
549 {
550         int rc;
551
552         rc = mmc_hardware_init(); 
553
554         if ( rc != 0)
555         {
556                 printk("mmc: error in mmc_hardware_init (%d)\n", rc);
557                 return -1;
558         }
559
560         rc = mmc_card_init(); 
561         if ( rc != 0)
562         {
563                 // Give it an extra shot
564                 rc = mmc_card_init(); 
565                 if ( rc != 0)
566                 {
567                         printk("mmc: error in mmc_card_init (%d)\n", rc);
568                         return -1;
569                 }
570         }
571
572         memset(hd_sizes, 0, sizeof(hd_sizes));
573         rc = mmc_card_config(); 
574         if ( rc != 0)
575         {
576                 printk("mmc: error in mmc_card_config (%d)\n", rc);
577                 return -1;
578         }
579         
580
581         blk_size[MAJOR_NR] = hd_sizes;
582
583         memset(hd, 0, sizeof(hd));
584         hd[0].nr_sects = hd_sizes[0]*2;
585
586         blksize_size[MAJOR_NR] = hd_blocksizes;
587         hardsect_size[MAJOR_NR] = hd_hardsectsizes;
588         max_sectors[MAJOR_NR] = hd_maxsect;
589
590         hd_gendisk.nr_real = 1;
591
592         register_disk(&hd_gendisk, MKDEV(MAJOR_NR,0), 1<<6,
593                       &mmc_bdops, hd_sizes[0]*2);
594
595         return 0;
596 }
597
598 static void mmc_exit(void)
599 {
600         blk_size[MAJOR_NR] = NULL;
601         blksize_size[MAJOR_NR] = NULL;
602         hardsect_size[MAJOR_NR] = NULL;
603         max_sectors[MAJOR_NR] = NULL;
604         hd[0].nr_sects = 0;
605 }
606
607 static void mmc_check_media(void)
608 {
609         int old_state;
610         int rc;
611         
612         old_state = mmc_media_detect; 
613
614         // TODO: Add card detection here
615         mmc_media_detect = 1;
616         if (old_state != mmc_media_detect) 
617         {
618                 mmc_media_changed = 1;
619                 if (mmc_media_detect == 1)
620                 {
621                         rc = mmc_init();
622                         if (rc != 0) printk("mmc: error in mmc_init (%d)\n", rc);
623                 }
624                 else 
625                 {
626                         mmc_exit();
627                 }
628         }
629
630         /* del_timer(&mmc_timer);
631         mmc_timer.expires = jiffies + 10*HZ;
632         add_timer(&mmc_timer); */
633 }
634
635 static int __init mmc_driver_init(void)
636 {
637         int rc;
638
639         rc = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
640         if (rc < 0)
641         {
642                 printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
643                 return rc;
644         }
645
646         blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);
647
648         read_ahead[MAJOR_NR] = 8;
649         add_gendisk(&hd_gendisk);
650
651         mmc_check_media();
652
653         /*init_timer(&mmc_timer);
654         mmc_timer.expires = jiffies + HZ;
655         mmc_timer.function = (void *)mmc_check_media;
656         add_timer(&mmc_timer);*/
657
658         return 0;
659 }
660
661 static void __exit mmc_driver_exit(void)
662 {
663         int i;
664         del_timer(&mmc_timer);
665
666         for (i = 0; i < (1 << 6); i++)
667                 fsync_dev(MKDEV(MAJOR_NR, i));
668
669         blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
670         del_gendisk(&hd_gendisk);
671         devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
672         mmc_exit();
673 }
674
675 module_init(mmc_driver_init);
676 module_exit(mmc_driver_exit);