]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/ssb/pcmcia.c
Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
[mv-sheeva.git] / drivers / ssb / pcmcia.c
1 /*
2  * Sonics Silicon Backplane
3  * PCMCIA-Hostbus related functions
4  *
5  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6  * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
7  *
8  * Licensed under the GNU/GPL. See COPYING for details.
9  */
10
11 #include <linux/ssb/ssb.h>
12 #include <linux/delay.h>
13 #include <linux/io.h>
14 #include <linux/etherdevice.h>
15
16 #include <pcmcia/cistpl.h>
17 #include <pcmcia/ciscode.h>
18 #include <pcmcia/ds.h>
19 #include <pcmcia/cisreg.h>
20
21 #include "ssb_private.h"
22
23
24 /* Define the following to 1 to enable a printk on each coreswitch. */
25 #define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG              0
26
27
28 /* PCMCIA configuration registers */
29 #define SSB_PCMCIA_ADDRESS0             0x2E
30 #define SSB_PCMCIA_ADDRESS1             0x30
31 #define SSB_PCMCIA_ADDRESS2             0x32
32 #define SSB_PCMCIA_MEMSEG               0x34
33 #define SSB_PCMCIA_SPROMCTL             0x36
34 #define  SSB_PCMCIA_SPROMCTL_IDLE       0
35 #define  SSB_PCMCIA_SPROMCTL_WRITE      1
36 #define  SSB_PCMCIA_SPROMCTL_READ       2
37 #define  SSB_PCMCIA_SPROMCTL_WRITEEN    4
38 #define  SSB_PCMCIA_SPROMCTL_WRITEDIS   7
39 #define  SSB_PCMCIA_SPROMCTL_DONE       8
40 #define SSB_PCMCIA_SPROM_DATALO         0x38
41 #define SSB_PCMCIA_SPROM_DATAHI         0x3A
42 #define SSB_PCMCIA_SPROM_ADDRLO         0x3C
43 #define SSB_PCMCIA_SPROM_ADDRHI         0x3E
44
45 /* Hardware invariants CIS tuples */
46 #define SSB_PCMCIA_CIS                  0x80
47 #define  SSB_PCMCIA_CIS_ID              0x01
48 #define  SSB_PCMCIA_CIS_BOARDREV        0x02
49 #define  SSB_PCMCIA_CIS_PA              0x03
50 #define   SSB_PCMCIA_CIS_PA_PA0B0_LO    0
51 #define   SSB_PCMCIA_CIS_PA_PA0B0_HI    1
52 #define   SSB_PCMCIA_CIS_PA_PA0B1_LO    2
53 #define   SSB_PCMCIA_CIS_PA_PA0B1_HI    3
54 #define   SSB_PCMCIA_CIS_PA_PA0B2_LO    4
55 #define   SSB_PCMCIA_CIS_PA_PA0B2_HI    5
56 #define   SSB_PCMCIA_CIS_PA_ITSSI       6
57 #define   SSB_PCMCIA_CIS_PA_MAXPOW      7
58 #define  SSB_PCMCIA_CIS_OEMNAME         0x04
59 #define  SSB_PCMCIA_CIS_CCODE           0x05
60 #define  SSB_PCMCIA_CIS_ANTENNA         0x06
61 #define  SSB_PCMCIA_CIS_ANTGAIN         0x07
62 #define  SSB_PCMCIA_CIS_BFLAGS          0x08
63 #define  SSB_PCMCIA_CIS_LEDS            0x09
64
65 /* PCMCIA SPROM size. */
66 #define SSB_PCMCIA_SPROM_SIZE           256
67 #define SSB_PCMCIA_SPROM_SIZE_BYTES     (SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
68
69
70 /* Write to a PCMCIA configuration register. */
71 static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
72 {
73         int res;
74
75         res = pcmcia_write_config_byte(bus->host_pcmcia, offset, value);
76         if (unlikely(res != 0))
77                 return -EBUSY;
78
79         return 0;
80 }
81
82 /* Read from a PCMCIA configuration register. */
83 static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
84 {
85         int res;
86
87         res = pcmcia_read_config_byte(bus->host_pcmcia, offset, value);
88         if (unlikely(res != 0))
89                 return -EBUSY;
90
91         return 0;
92 }
93
94 int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
95                               u8 coreidx)
96 {
97         int err;
98         int attempts = 0;
99         u32 cur_core;
100         u32 addr;
101         u32 read_addr;
102         u8 val;
103
104         addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
105         while (1) {
106                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0,
107                                            (addr & 0x0000F000) >> 12);
108                 if (err)
109                         goto error;
110                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1,
111                                            (addr & 0x00FF0000) >> 16);
112                 if (err)
113                         goto error;
114                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2,
115                                            (addr & 0xFF000000) >> 24);
116                 if (err)
117                         goto error;
118
119                 read_addr = 0;
120
121                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val);
122                 if (err)
123                         goto error;
124                 read_addr |= ((u32)(val & 0x0F)) << 12;
125                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val);
126                 if (err)
127                         goto error;
128                 read_addr |= ((u32)val) << 16;
129                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val);
130                 if (err)
131                         goto error;
132                 read_addr |= ((u32)val) << 24;
133
134                 cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
135                 if (cur_core == coreidx)
136                         break;
137
138                 err = -ETIMEDOUT;
139                 if (attempts++ > SSB_BAR0_MAX_RETRIES)
140                         goto error;
141                 udelay(10);
142         }
143
144         return 0;
145 error:
146         ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
147         return err;
148 }
149
150 int ssb_pcmcia_switch_core(struct ssb_bus *bus,
151                            struct ssb_device *dev)
152 {
153         int err;
154
155 #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
156         ssb_printk(KERN_INFO PFX
157                    "Switching to %s core, index %d\n",
158                    ssb_core_name(dev->id.coreid),
159                    dev->core_index);
160 #endif
161
162         err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
163         if (!err)
164                 bus->mapped_device = dev;
165
166         return err;
167 }
168
169 int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
170 {
171         int attempts = 0;
172         int err;
173         u8 val;
174
175         SSB_WARN_ON((seg != 0) && (seg != 1));
176         while (1) {
177                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg);
178                 if (err)
179                         goto error;
180                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val);
181                 if (err)
182                         goto error;
183                 if (val == seg)
184                         break;
185
186                 err = -ETIMEDOUT;
187                 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
188                         goto error;
189                 udelay(10);
190         }
191         bus->mapped_pcmcia_seg = seg;
192
193         return 0;
194 error:
195         ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
196         return err;
197 }
198
199 static int select_core_and_segment(struct ssb_device *dev,
200                                    u16 *offset)
201 {
202         struct ssb_bus *bus = dev->bus;
203         int err;
204         u8 need_segment;
205
206         if (*offset >= 0x800) {
207                 *offset -= 0x800;
208                 need_segment = 1;
209         } else
210                 need_segment = 0;
211
212         if (unlikely(dev != bus->mapped_device)) {
213                 err = ssb_pcmcia_switch_core(bus, dev);
214                 if (unlikely(err))
215                         return err;
216         }
217         if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
218                 err = ssb_pcmcia_switch_segment(bus, need_segment);
219                 if (unlikely(err))
220                         return err;
221         }
222
223         return 0;
224 }
225
226 static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
227 {
228         struct ssb_bus *bus = dev->bus;
229         unsigned long flags;
230         int err;
231         u8 value = 0xFF;
232
233         spin_lock_irqsave(&bus->bar_lock, flags);
234         err = select_core_and_segment(dev, &offset);
235         if (likely(!err))
236                 value = readb(bus->mmio + offset);
237         spin_unlock_irqrestore(&bus->bar_lock, flags);
238
239         return value;
240 }
241
242 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
243 {
244         struct ssb_bus *bus = dev->bus;
245         unsigned long flags;
246         int err;
247         u16 value = 0xFFFF;
248
249         spin_lock_irqsave(&bus->bar_lock, flags);
250         err = select_core_and_segment(dev, &offset);
251         if (likely(!err))
252                 value = readw(bus->mmio + offset);
253         spin_unlock_irqrestore(&bus->bar_lock, flags);
254
255         return value;
256 }
257
258 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
259 {
260         struct ssb_bus *bus = dev->bus;
261         unsigned long flags;
262         int err;
263         u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
264
265         spin_lock_irqsave(&bus->bar_lock, flags);
266         err = select_core_and_segment(dev, &offset);
267         if (likely(!err)) {
268                 lo = readw(bus->mmio + offset);
269                 hi = readw(bus->mmio + offset + 2);
270         }
271         spin_unlock_irqrestore(&bus->bar_lock, flags);
272
273         return (lo | (hi << 16));
274 }
275
276 #ifdef CONFIG_SSB_BLOCKIO
277 static void ssb_pcmcia_block_read(struct ssb_device *dev, void *buffer,
278                                   size_t count, u16 offset, u8 reg_width)
279 {
280         struct ssb_bus *bus = dev->bus;
281         unsigned long flags;
282         void __iomem *addr = bus->mmio + offset;
283         int err;
284
285         spin_lock_irqsave(&bus->bar_lock, flags);
286         err = select_core_and_segment(dev, &offset);
287         if (unlikely(err)) {
288                 memset(buffer, 0xFF, count);
289                 goto unlock;
290         }
291         switch (reg_width) {
292         case sizeof(u8): {
293                 u8 *buf = buffer;
294
295                 while (count) {
296                         *buf = __raw_readb(addr);
297                         buf++;
298                         count--;
299                 }
300                 break;
301         }
302         case sizeof(u16): {
303                 __le16 *buf = buffer;
304
305                 SSB_WARN_ON(count & 1);
306                 while (count) {
307                         *buf = (__force __le16)__raw_readw(addr);
308                         buf++;
309                         count -= 2;
310                 }
311                 break;
312         }
313         case sizeof(u32): {
314                 __le16 *buf = buffer;
315
316                 SSB_WARN_ON(count & 3);
317                 while (count) {
318                         *buf = (__force __le16)__raw_readw(addr);
319                         buf++;
320                         *buf = (__force __le16)__raw_readw(addr + 2);
321                         buf++;
322                         count -= 4;
323                 }
324                 break;
325         }
326         default:
327                 SSB_WARN_ON(1);
328         }
329 unlock:
330         spin_unlock_irqrestore(&bus->bar_lock, flags);
331 }
332 #endif /* CONFIG_SSB_BLOCKIO */
333
334 static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
335 {
336         struct ssb_bus *bus = dev->bus;
337         unsigned long flags;
338         int err;
339
340         spin_lock_irqsave(&bus->bar_lock, flags);
341         err = select_core_and_segment(dev, &offset);
342         if (likely(!err))
343                 writeb(value, bus->mmio + offset);
344         mmiowb();
345         spin_unlock_irqrestore(&bus->bar_lock, flags);
346 }
347
348 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
349 {
350         struct ssb_bus *bus = dev->bus;
351         unsigned long flags;
352         int err;
353
354         spin_lock_irqsave(&bus->bar_lock, flags);
355         err = select_core_and_segment(dev, &offset);
356         if (likely(!err))
357                 writew(value, bus->mmio + offset);
358         mmiowb();
359         spin_unlock_irqrestore(&bus->bar_lock, flags);
360 }
361
362 static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
363 {
364         struct ssb_bus *bus = dev->bus;
365         unsigned long flags;
366         int err;
367
368         spin_lock_irqsave(&bus->bar_lock, flags);
369         err = select_core_and_segment(dev, &offset);
370         if (likely(!err)) {
371                 writew((value & 0x0000FFFF), bus->mmio + offset);
372                 writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
373         }
374         mmiowb();
375         spin_unlock_irqrestore(&bus->bar_lock, flags);
376 }
377
378 #ifdef CONFIG_SSB_BLOCKIO
379 static void ssb_pcmcia_block_write(struct ssb_device *dev, const void *buffer,
380                                    size_t count, u16 offset, u8 reg_width)
381 {
382         struct ssb_bus *bus = dev->bus;
383         unsigned long flags;
384         void __iomem *addr = bus->mmio + offset;
385         int err;
386
387         spin_lock_irqsave(&bus->bar_lock, flags);
388         err = select_core_and_segment(dev, &offset);
389         if (unlikely(err))
390                 goto unlock;
391         switch (reg_width) {
392         case sizeof(u8): {
393                 const u8 *buf = buffer;
394
395                 while (count) {
396                         __raw_writeb(*buf, addr);
397                         buf++;
398                         count--;
399                 }
400                 break;
401         }
402         case sizeof(u16): {
403                 const __le16 *buf = buffer;
404
405                 SSB_WARN_ON(count & 1);
406                 while (count) {
407                         __raw_writew((__force u16)(*buf), addr);
408                         buf++;
409                         count -= 2;
410                 }
411                 break;
412         }
413         case sizeof(u32): {
414                 const __le16 *buf = buffer;
415
416                 SSB_WARN_ON(count & 3);
417                 while (count) {
418                         __raw_writew((__force u16)(*buf), addr);
419                         buf++;
420                         __raw_writew((__force u16)(*buf), addr + 2);
421                         buf++;
422                         count -= 4;
423                 }
424                 break;
425         }
426         default:
427                 SSB_WARN_ON(1);
428         }
429 unlock:
430         mmiowb();
431         spin_unlock_irqrestore(&bus->bar_lock, flags);
432 }
433 #endif /* CONFIG_SSB_BLOCKIO */
434
435 /* Not "static", as it's used in main.c */
436 const struct ssb_bus_ops ssb_pcmcia_ops = {
437         .read8          = ssb_pcmcia_read8,
438         .read16         = ssb_pcmcia_read16,
439         .read32         = ssb_pcmcia_read32,
440         .write8         = ssb_pcmcia_write8,
441         .write16        = ssb_pcmcia_write16,
442         .write32        = ssb_pcmcia_write32,
443 #ifdef CONFIG_SSB_BLOCKIO
444         .block_read     = ssb_pcmcia_block_read,
445         .block_write    = ssb_pcmcia_block_write,
446 #endif
447 };
448
449 static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command)
450 {
451         unsigned int i;
452         int err;
453         u8 value;
454
455         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command);
456         if (err)
457                 return err;
458         for (i = 0; i < 1000; i++) {
459                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value);
460                 if (err)
461                         return err;
462                 if (value & SSB_PCMCIA_SPROMCTL_DONE)
463                         return 0;
464                 udelay(10);
465         }
466
467         return -ETIMEDOUT;
468 }
469
470 /* offset is the 16bit word offset */
471 static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value)
472 {
473         int err;
474         u8 lo, hi;
475
476         offset *= 2; /* Make byte offset */
477
478         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
479                                    (offset & 0x00FF));
480         if (err)
481                 return err;
482         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
483                                    (offset & 0xFF00) >> 8);
484         if (err)
485                 return err;
486         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ);
487         if (err)
488                 return err;
489         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo);
490         if (err)
491                 return err;
492         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi);
493         if (err)
494                 return err;
495         *value = (lo | (((u16)hi) << 8));
496
497         return 0;
498 }
499
500 /* offset is the 16bit word offset */
501 static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
502 {
503         int err;
504
505         offset *= 2; /* Make byte offset */
506
507         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
508                                    (offset & 0x00FF));
509         if (err)
510                 return err;
511         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
512                                    (offset & 0xFF00) >> 8);
513         if (err)
514                 return err;
515         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO,
516                                    (value & 0x00FF));
517         if (err)
518                 return err;
519         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI,
520                                    (value & 0xFF00) >> 8);
521         if (err)
522                 return err;
523         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE);
524         if (err)
525                 return err;
526         msleep(20);
527
528         return 0;
529 }
530
531 /* Read the SPROM image. bufsize is in 16bit words. */
532 static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom)
533 {
534         int err, i;
535
536         for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) {
537                 err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]);
538                 if (err)
539                         return err;
540         }
541
542         return 0;
543 }
544
545 /* Write the SPROM image. size is in 16bit words. */
546 static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
547 {
548         int i, err;
549         bool failed = 0;
550         size_t size = SSB_PCMCIA_SPROM_SIZE;
551
552         ssb_printk(KERN_NOTICE PFX
553                    "Writing SPROM. Do NOT turn off the power! "
554                    "Please stand by...\n");
555         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
556         if (err) {
557                 ssb_printk(KERN_NOTICE PFX
558                            "Could not enable SPROM write access.\n");
559                 return -EBUSY;
560         }
561         ssb_printk(KERN_NOTICE PFX "[ 0%%");
562         msleep(500);
563         for (i = 0; i < size; i++) {
564                 if (i == size / 4)
565                         ssb_printk("25%%");
566                 else if (i == size / 2)
567                         ssb_printk("50%%");
568                 else if (i == (size * 3) / 4)
569                         ssb_printk("75%%");
570                 else if (i % 2)
571                         ssb_printk(".");
572                 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
573                 if (err) {
574                         ssb_printk(KERN_NOTICE PFX
575                                    "Failed to write to SPROM.\n");
576                         failed = 1;
577                         break;
578                 }
579         }
580         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
581         if (err) {
582                 ssb_printk(KERN_NOTICE PFX
583                            "Could not disable SPROM write access.\n");
584                 failed = 1;
585         }
586         msleep(500);
587         if (!failed) {
588                 ssb_printk("100%% ]\n");
589                 ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
590         }
591
592         return failed ? -EBUSY : 0;
593 }
594
595 static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
596 {
597         //TODO
598         return 0;
599 }
600
601 #define GOTO_ERROR_ON(condition, description) do {      \
602         if (unlikely(condition)) {                      \
603                 error_description = description;        \
604                 goto error;                             \
605         }                                               \
606   } while (0)
607
608 static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
609                         tuple_t *tuple,
610                         void *priv)
611 {
612         struct ssb_sprom *sprom = priv;
613
614         if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
615                 return -EINVAL;
616         if (tuple->TupleDataLen != ETH_ALEN + 2)
617                 return -EINVAL;
618         if (tuple->TupleData[1] != ETH_ALEN)
619                 return -EINVAL;
620         memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
621         return 0;
622 };
623
624 static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
625                                         tuple_t *tuple,
626                                         void *priv)
627 {
628         struct ssb_init_invariants *iv = priv;
629         struct ssb_sprom *sprom = &iv->sprom;
630         struct ssb_boardinfo *bi = &iv->boardinfo;
631         const char *error_description;
632
633         GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
634         switch (tuple->TupleData[0]) {
635         case SSB_PCMCIA_CIS_ID:
636                 GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
637                               (tuple->TupleDataLen != 7),
638                               "id tpl size");
639                 bi->vendor = tuple->TupleData[1] |
640                         ((u16)tuple->TupleData[2] << 8);
641                 break;
642         case SSB_PCMCIA_CIS_BOARDREV:
643                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
644                         "boardrev tpl size");
645                 sprom->board_rev = tuple->TupleData[1];
646                 break;
647         case SSB_PCMCIA_CIS_PA:
648                 GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
649                         (tuple->TupleDataLen != 10),
650                         "pa tpl size");
651                 sprom->pa0b0 = tuple->TupleData[1] |
652                         ((u16)tuple->TupleData[2] << 8);
653                 sprom->pa0b1 = tuple->TupleData[3] |
654                         ((u16)tuple->TupleData[4] << 8);
655                 sprom->pa0b2 = tuple->TupleData[5] |
656                         ((u16)tuple->TupleData[6] << 8);
657                 sprom->itssi_a = tuple->TupleData[7];
658                 sprom->itssi_bg = tuple->TupleData[7];
659                 sprom->maxpwr_a = tuple->TupleData[8];
660                 sprom->maxpwr_bg = tuple->TupleData[8];
661                 break;
662         case SSB_PCMCIA_CIS_OEMNAME:
663                 /* We ignore this. */
664                 break;
665         case SSB_PCMCIA_CIS_CCODE:
666                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
667                         "ccode tpl size");
668                 sprom->country_code = tuple->TupleData[1];
669                 break;
670         case SSB_PCMCIA_CIS_ANTENNA:
671                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
672                         "ant tpl size");
673                 sprom->ant_available_a = tuple->TupleData[1];
674                 sprom->ant_available_bg = tuple->TupleData[1];
675                 break;
676         case SSB_PCMCIA_CIS_ANTGAIN:
677                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
678                         "antg tpl size");
679                 sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
680                 sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
681                 sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
682                 sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
683                 sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
684                 sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
685                 sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
686                 sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
687                 break;
688         case SSB_PCMCIA_CIS_BFLAGS:
689                 GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
690                         (tuple->TupleDataLen != 5),
691                         "bfl tpl size");
692                 sprom->boardflags_lo = tuple->TupleData[1] |
693                         ((u16)tuple->TupleData[2] << 8);
694                 break;
695         case SSB_PCMCIA_CIS_LEDS:
696                 GOTO_ERROR_ON(tuple->TupleDataLen != 5,
697                         "leds tpl size");
698                 sprom->gpio0 = tuple->TupleData[1];
699                 sprom->gpio1 = tuple->TupleData[2];
700                 sprom->gpio2 = tuple->TupleData[3];
701                 sprom->gpio3 = tuple->TupleData[4];
702                 break;
703         }
704         return -ENOSPC; /* continue with next entry */
705
706 error:
707         ssb_printk(KERN_ERR PFX
708                    "PCMCIA: Failed to fetch device invariants: %s\n",
709                    error_description);
710         return -ENODEV;
711 }
712
713
714 int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
715                               struct ssb_init_invariants *iv)
716 {
717         struct ssb_sprom *sprom = &iv->sprom;
718         int res;
719
720         memset(sprom, 0xFF, sizeof(*sprom));
721         sprom->revision = 1;
722         sprom->boardflags_lo = 0;
723         sprom->boardflags_hi = 0;
724
725         /* First fetch the MAC address. */
726         res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
727                                 ssb_pcmcia_get_mac, sprom);
728         if (res != 0) {
729                 ssb_printk(KERN_ERR PFX
730                         "PCMCIA: Failed to fetch MAC address\n");
731                 return -ENODEV;
732         }
733
734         /* Fetch the vendor specific tuples. */
735         res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
736                                 ssb_pcmcia_do_get_invariants, sprom);
737         if ((res == 0) || (res == -ENOSPC))
738                 return 0;
739
740         ssb_printk(KERN_ERR PFX
741                         "PCMCIA: Failed to fetch device invariants\n");
742         return -ENODEV;
743 }
744
745 static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
746                                           struct device_attribute *attr,
747                                           char *buf)
748 {
749         struct pcmcia_device *pdev =
750                 container_of(pcmciadev, struct pcmcia_device, dev);
751         struct ssb_bus *bus;
752
753         bus = ssb_pcmcia_dev_to_bus(pdev);
754         if (!bus)
755                 return -ENODEV;
756
757         return ssb_attr_sprom_show(bus, buf,
758                                    ssb_pcmcia_sprom_read_all);
759 }
760
761 static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev,
762                                            struct device_attribute *attr,
763                                            const char *buf, size_t count)
764 {
765         struct pcmcia_device *pdev =
766                 container_of(pcmciadev, struct pcmcia_device, dev);
767         struct ssb_bus *bus;
768
769         bus = ssb_pcmcia_dev_to_bus(pdev);
770         if (!bus)
771                 return -ENODEV;
772
773         return ssb_attr_sprom_store(bus, buf, count,
774                                     ssb_pcmcia_sprom_check_crc,
775                                     ssb_pcmcia_sprom_write_all);
776 }
777
778 static DEVICE_ATTR(ssb_sprom, 0600,
779                    ssb_pcmcia_attr_sprom_show,
780                    ssb_pcmcia_attr_sprom_store);
781
782 static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor)
783 {
784         u8 val;
785         int err;
786
787         err = ssb_pcmcia_cfg_read(bus, cor, &val);
788         if (err)
789                 return err;
790         val &= ~COR_SOFT_RESET;
791         val |= COR_FUNC_ENA | COR_IREQ_ENA | COR_LEVEL_REQ;
792         err = ssb_pcmcia_cfg_write(bus, cor, val);
793         if (err)
794                 return err;
795         msleep(40);
796
797         return 0;
798 }
799
800 /* Initialize the PCMCIA hardware. This is called on Init and Resume. */
801 int ssb_pcmcia_hardware_setup(struct ssb_bus *bus)
802 {
803         int err;
804
805         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
806                 return 0;
807
808         /* Switch segment to a known state and sync
809          * bus->mapped_pcmcia_seg with hardware state. */
810         ssb_pcmcia_switch_segment(bus, 0);
811         /* Init the COR register. */
812         err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
813         if (err)
814                 return err;
815         /* Some cards also need this register to get poked. */
816         err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80);
817         if (err)
818                 return err;
819
820         return 0;
821 }
822
823 void ssb_pcmcia_exit(struct ssb_bus *bus)
824 {
825         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
826                 return;
827
828         device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
829 }
830
831 int ssb_pcmcia_init(struct ssb_bus *bus)
832 {
833         int err;
834
835         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
836                 return 0;
837
838         err = ssb_pcmcia_hardware_setup(bus);
839         if (err)
840                 goto error;
841
842         bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
843         mutex_init(&bus->sprom_mutex);
844         err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
845         if (err)
846                 goto error;
847
848         return 0;
849 error:
850         ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n");
851         return err;
852 }