mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			506 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
--- a/drivers/ssb/driver_chipcommon_pmu.c
 | 
						|
+++ b/drivers/ssb/driver_chipcommon_pmu.c
 | 
						|
@@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct 
 | 
						|
 	chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
 | 
						|
 }
 | 
						|
 
 | 
						|
+static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc,
 | 
						|
+				   u32 offset, u32 mask, u32 set)
 | 
						|
+{
 | 
						|
+	u32 value;
 | 
						|
+
 | 
						|
+	chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
 | 
						|
+	chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset);
 | 
						|
+	chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
 | 
						|
+	value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
 | 
						|
+	value &= mask;
 | 
						|
+	value |= set;
 | 
						|
+	chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value);
 | 
						|
+	chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
 | 
						|
+}
 | 
						|
+
 | 
						|
 struct pmu0_plltab_entry {
 | 
						|
 	u16 freq;	/* Crystal frequency in kHz.*/
 | 
						|
 	u8 xf;		/* Crystal frequency value for PMU control */
 | 
						|
@@ -506,3 +521,82 @@ void ssb_pmu_init(struct ssb_chipcommon 
 | 
						|
 	ssb_pmu_pll_init(cc);
 | 
						|
 	ssb_pmu_resources_init(cc);
 | 
						|
 }
 | 
						|
+
 | 
						|
+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
 | 
						|
+			     enum ssb_pmu_ldo_volt_id id, u32 voltage)
 | 
						|
+{
 | 
						|
+	struct ssb_bus *bus = cc->dev->bus;
 | 
						|
+	u32 addr, shift, mask;
 | 
						|
+
 | 
						|
+	switch (bus->chip_id) {
 | 
						|
+	case 0x4328:
 | 
						|
+	case 0x5354:
 | 
						|
+		switch (id) {
 | 
						|
+		case LDO_VOLT1:
 | 
						|
+			addr = 2;
 | 
						|
+			shift = 25;
 | 
						|
+			mask = 0xF;
 | 
						|
+			break;
 | 
						|
+		case LDO_VOLT2:
 | 
						|
+			addr = 3;
 | 
						|
+			shift = 1;
 | 
						|
+			mask = 0xF;
 | 
						|
+			break;
 | 
						|
+		case LDO_VOLT3:
 | 
						|
+			addr = 3;
 | 
						|
+			shift = 9;
 | 
						|
+			mask = 0xF;
 | 
						|
+			break;
 | 
						|
+		case LDO_PAREF:
 | 
						|
+			addr = 3;
 | 
						|
+			shift = 17;
 | 
						|
+			mask = 0x3F;
 | 
						|
+			break;
 | 
						|
+		default:
 | 
						|
+			SSB_WARN_ON(1);
 | 
						|
+			return;
 | 
						|
+		}
 | 
						|
+		break;
 | 
						|
+	case 0x4312:
 | 
						|
+		if (SSB_WARN_ON(id != LDO_PAREF))
 | 
						|
+			return;
 | 
						|
+		addr = 0;
 | 
						|
+		shift = 21;
 | 
						|
+		mask = 0x3F;
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift),
 | 
						|
+				  (voltage & mask) << shift);
 | 
						|
+}
 | 
						|
+
 | 
						|
+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
 | 
						|
+{
 | 
						|
+	struct ssb_bus *bus = cc->dev->bus;
 | 
						|
+	int ldo;
 | 
						|
+
 | 
						|
+	switch (bus->chip_id) {
 | 
						|
+	case 0x4312:
 | 
						|
+		ldo = SSB_PMURES_4312_PA_REF_LDO;
 | 
						|
+		break;
 | 
						|
+	case 0x4328:
 | 
						|
+		ldo = SSB_PMURES_4328_PA_REF_LDO;
 | 
						|
+		break;
 | 
						|
+	case 0x5354:
 | 
						|
+		ldo = SSB_PMURES_5354_PA_REF_LDO;
 | 
						|
+		break;
 | 
						|
+	default:
 | 
						|
+		return;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (on)
 | 
						|
+		chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo);
 | 
						|
+	else
 | 
						|
+		chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo));
 | 
						|
+	chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read?
 | 
						|
+}
 | 
						|
+
 | 
						|
+EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
 | 
						|
+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
 | 
						|
--- a/drivers/ssb/main.c
 | 
						|
+++ b/drivers/ssb/main.c
 | 
						|
@@ -469,6 +469,8 @@ static int ssb_devices_register(struct s
 | 
						|
 			dev->parent = &bus->host_pcmcia->dev;
 | 
						|
 #endif
 | 
						|
 			break;
 | 
						|
+		case SSB_BUSTYPE_SDIO:
 | 
						|
+			break;
 | 
						|
 		case SSB_BUSTYPE_SSB:
 | 
						|
 			dev->dma_mask = &dev->coherent_dma_mask;
 | 
						|
 			break;
 | 
						|
@@ -1358,8 +1360,10 @@ static int __init ssb_modinit(void)
 | 
						|
 	ssb_buses_lock();
 | 
						|
 	err = ssb_attach_queued_buses();
 | 
						|
 	ssb_buses_unlock();
 | 
						|
-	if (err)
 | 
						|
+	if (err) {
 | 
						|
 		bus_unregister(&ssb_bustype);
 | 
						|
+		goto out;
 | 
						|
+	}
 | 
						|
 
 | 
						|
 	err = b43_pci_ssb_bridge_init();
 | 
						|
 	if (err) {
 | 
						|
@@ -1375,7 +1379,7 @@ static int __init ssb_modinit(void)
 | 
						|
 		/* don't fail SSB init because of this */
 | 
						|
 		err = 0;
 | 
						|
 	}
 | 
						|
-
 | 
						|
+out:
 | 
						|
 	return err;
 | 
						|
 }
 | 
						|
 /* ssb must be initialized after PCI but before the ssb drivers.
 | 
						|
--- a/drivers/ssb/pci.c
 | 
						|
+++ b/drivers/ssb/pci.c
 | 
						|
@@ -169,8 +169,14 @@ err_pci:
 | 
						|
 /* Get the word-offset for a SSB_SPROM_XXX define. */
 | 
						|
 #define SPOFF(offset)	(((offset) - SSB_SPROM_BASE) / sizeof(u16))
 | 
						|
 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
 | 
						|
-#define SPEX(_outvar, _offset, _mask, _shift)	\
 | 
						|
+#define SPEX16(_outvar, _offset, _mask, _shift)	\
 | 
						|
 	out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
 | 
						|
+#define SPEX32(_outvar, _offset, _mask, _shift)	\
 | 
						|
+	out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
 | 
						|
+			   in[SPOFF(_offset)]) & (_mask)) >> (_shift))
 | 
						|
+#define SPEX(_outvar, _offset, _mask, _shift) \
 | 
						|
+	SPEX16(_outvar, _offset, _mask, _shift)
 | 
						|
+
 | 
						|
 
 | 
						|
 static inline u8 ssb_crc8(u8 crc, u8 data)
 | 
						|
 {
 | 
						|
@@ -474,12 +480,14 @@ static void sprom_extract_r8(struct ssb_
 | 
						|
 
 | 
						|
 	/* extract the MAC address */
 | 
						|
 	for (i = 0; i < 3; i++) {
 | 
						|
-		v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
 | 
						|
+		v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
 | 
						|
 		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
 | 
						|
 	}
 | 
						|
 	SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
 | 
						|
 	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
 | 
						|
 	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
 | 
						|
+	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
 | 
						|
+	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
 | 
						|
 	SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
 | 
						|
 	     SSB_SPROM8_ANTAVAIL_A_SHIFT);
 | 
						|
 	SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
 | 
						|
@@ -490,12 +498,55 @@ static void sprom_extract_r8(struct ssb_
 | 
						|
 	SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
 | 
						|
 	SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
 | 
						|
 	     SSB_SPROM8_ITSSI_A_SHIFT);
 | 
						|
+	SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
 | 
						|
+	SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
 | 
						|
+	     SSB_SPROM8_MAXP_AL_SHIFT);
 | 
						|
 	SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
 | 
						|
 	SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
 | 
						|
 	     SSB_SPROM8_GPIOA_P1_SHIFT);
 | 
						|
 	SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
 | 
						|
 	SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
 | 
						|
 	     SSB_SPROM8_GPIOB_P3_SHIFT);
 | 
						|
+	SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
 | 
						|
+	SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
 | 
						|
+	     SSB_SPROM8_TRI5G_SHIFT);
 | 
						|
+	SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
 | 
						|
+	SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
 | 
						|
+	     SSB_SPROM8_TRI5GH_SHIFT);
 | 
						|
+	SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
 | 
						|
+	SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
 | 
						|
+	     SSB_SPROM8_RXPO5G_SHIFT);
 | 
						|
+	SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
 | 
						|
+	SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
 | 
						|
+	     SSB_SPROM8_RSSISMC2G_SHIFT);
 | 
						|
+	SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
 | 
						|
+	     SSB_SPROM8_RSSISAV2G_SHIFT);
 | 
						|
+	SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
 | 
						|
+	     SSB_SPROM8_BXA2G_SHIFT);
 | 
						|
+	SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
 | 
						|
+	SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
 | 
						|
+	     SSB_SPROM8_RSSISMC5G_SHIFT);
 | 
						|
+	SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
 | 
						|
+	     SSB_SPROM8_RSSISAV5G_SHIFT);
 | 
						|
+	SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
 | 
						|
+	     SSB_SPROM8_BXA5G_SHIFT);
 | 
						|
+	SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
 | 
						|
+	SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
 | 
						|
+	SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
 | 
						|
+	SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
 | 
						|
+	SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
 | 
						|
+	SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
 | 
						|
+	SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
 | 
						|
+	SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
 | 
						|
+	SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
 | 
						|
 
 | 
						|
 	/* Extract the antenna gain values. */
 | 
						|
 	SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
 | 
						|
@@ -549,6 +600,7 @@ static int sprom_extract(struct ssb_bus 
 | 
						|
 			ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
 | 
						|
 				   "  revision %d detected. Will extract"
 | 
						|
 				   " v1\n", out->revision);
 | 
						|
+			out->revision = 1;
 | 
						|
 			sprom_extract_r123(out, in);
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
--- a/drivers/ssb/scan.c
 | 
						|
+++ b/drivers/ssb/scan.c
 | 
						|
@@ -175,6 +175,8 @@ static u32 scan_read32(struct ssb_bus *b
 | 
						|
 		} else
 | 
						|
 			ssb_pcmcia_switch_segment(bus, 0);
 | 
						|
 		break;
 | 
						|
+	case SSB_BUSTYPE_SDIO:
 | 
						|
+		break;
 | 
						|
 	}
 | 
						|
 	return readl(bus->mmio + offset);
 | 
						|
 }
 | 
						|
@@ -188,6 +190,8 @@ static int scan_switchcore(struct ssb_bu
 | 
						|
 		return ssb_pci_switch_coreidx(bus, coreidx);
 | 
						|
 	case SSB_BUSTYPE_PCMCIA:
 | 
						|
 		return ssb_pcmcia_switch_coreidx(bus, coreidx);
 | 
						|
+	case SSB_BUSTYPE_SDIO:
 | 
						|
+		break;
 | 
						|
 	}
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
@@ -206,6 +210,8 @@ void ssb_iounmap(struct ssb_bus *bus)
 | 
						|
 		SSB_BUG_ON(1); /* Can't reach this code. */
 | 
						|
 #endif
 | 
						|
 		break;
 | 
						|
+	case SSB_BUSTYPE_SDIO:
 | 
						|
+		break;
 | 
						|
 	}
 | 
						|
 	bus->mmio = NULL;
 | 
						|
 	bus->mapped_device = NULL;
 | 
						|
@@ -230,6 +236,8 @@ static void __iomem *ssb_ioremap(struct 
 | 
						|
 		SSB_BUG_ON(1); /* Can't reach this code. */
 | 
						|
 #endif
 | 
						|
 		break;
 | 
						|
+	case SSB_BUSTYPE_SDIO:
 | 
						|
+		break;
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	return mmio;
 | 
						|
--- a/include/linux/ssb/ssb.h
 | 
						|
+++ b/include/linux/ssb/ssb.h
 | 
						|
@@ -27,24 +27,54 @@ struct ssb_sprom {
 | 
						|
 	u8 et1mdcport;		/* MDIO for enet1 */
 | 
						|
 	u8 board_rev;		/* Board revision number from SPROM. */
 | 
						|
 	u8 country_code;	/* Country Code */
 | 
						|
-	u8 ant_available_a;	/* A-PHY antenna available bits (up to 4) */
 | 
						|
-	u8 ant_available_bg;	/* B/G-PHY antenna available bits (up to 4) */
 | 
						|
+	u8 ant_available_a;	/* 2GHz antenna available bits (up to 4) */
 | 
						|
+	u8 ant_available_bg;	/* 5GHz antenna available bits (up to 4) */
 | 
						|
 	u16 pa0b0;
 | 
						|
 	u16 pa0b1;
 | 
						|
 	u16 pa0b2;
 | 
						|
 	u16 pa1b0;
 | 
						|
 	u16 pa1b1;
 | 
						|
 	u16 pa1b2;
 | 
						|
+	u16 pa1lob0;
 | 
						|
+	u16 pa1lob1;
 | 
						|
+	u16 pa1lob2;
 | 
						|
+	u16 pa1hib0;
 | 
						|
+	u16 pa1hib1;
 | 
						|
+	u16 pa1hib2;
 | 
						|
 	u8 gpio0;		/* GPIO pin 0 */
 | 
						|
 	u8 gpio1;		/* GPIO pin 1 */
 | 
						|
 	u8 gpio2;		/* GPIO pin 2 */
 | 
						|
 	u8 gpio3;		/* GPIO pin 3 */
 | 
						|
-	u16 maxpwr_a;		/* A-PHY Amplifier Max Power (in dBm Q5.2) */
 | 
						|
-	u16 maxpwr_bg;		/* B/G-PHY Amplifier Max Power (in dBm Q5.2) */
 | 
						|
+	u16 maxpwr_bg;		/* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
 | 
						|
+	u16 maxpwr_al;		/* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
 | 
						|
+	u16 maxpwr_a;		/* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
 | 
						|
+	u16 maxpwr_ah;		/* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
 | 
						|
 	u8 itssi_a;		/* Idle TSSI Target for A-PHY */
 | 
						|
 	u8 itssi_bg;		/* Idle TSSI Target for B/G-PHY */
 | 
						|
-	u16 boardflags_lo;	/* Boardflags (low 16 bits) */
 | 
						|
-	u16 boardflags_hi;	/* Boardflags (high 16 bits) */
 | 
						|
+	u8 tri2g;		/* 2.4GHz TX isolation */
 | 
						|
+	u8 tri5gl;		/* 5.2GHz TX isolation */
 | 
						|
+	u8 tri5g;		/* 5.3GHz TX isolation */
 | 
						|
+	u8 tri5gh;		/* 5.8GHz TX isolation */
 | 
						|
+	u8 rxpo2g;		/* 2GHz RX power offset */
 | 
						|
+	u8 rxpo5g;		/* 5GHz RX power offset */
 | 
						|
+	u8 rssisav2g;		/* 2GHz RSSI params */
 | 
						|
+	u8 rssismc2g;
 | 
						|
+	u8 rssismf2g;
 | 
						|
+	u8 bxa2g;		/* 2GHz BX arch */
 | 
						|
+	u8 rssisav5g;		/* 5GHz RSSI params */
 | 
						|
+	u8 rssismc5g;
 | 
						|
+	u8 rssismf5g;
 | 
						|
+	u8 bxa5g;		/* 5GHz BX arch */
 | 
						|
+	u16 cck2gpo;		/* CCK power offset */
 | 
						|
+	u32 ofdm2gpo;		/* 2.4GHz OFDM power offset */
 | 
						|
+	u32 ofdm5glpo;		/* 5.2GHz OFDM power offset */
 | 
						|
+	u32 ofdm5gpo;		/* 5.3GHz OFDM power offset */
 | 
						|
+	u32 ofdm5ghpo;		/* 5.8GHz OFDM power offset */
 | 
						|
+	u16 boardflags_lo;	/* Board flags (bits 0-15) */
 | 
						|
+	u16 boardflags_hi;	/* Board flags (bits 16-31) */
 | 
						|
+	u16 boardflags2_lo;	/* Board flags (bits 32-47) */
 | 
						|
+	u16 boardflags2_hi;	/* Board flags (bits 48-63) */
 | 
						|
+	/* TODO store board flags in a single u64 */
 | 
						|
 
 | 
						|
 	/* Antenna gain values for up to 4 antennas
 | 
						|
 	 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
 | 
						|
@@ -58,7 +88,7 @@ struct ssb_sprom {
 | 
						|
 		} ghz5;		/* 5GHz band */
 | 
						|
 	} antenna_gain;
 | 
						|
 
 | 
						|
-	/* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */
 | 
						|
+	/* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
 | 
						|
 };
 | 
						|
 
 | 
						|
 /* Information about the PCB the circuitry is soldered on. */
 | 
						|
@@ -208,6 +238,7 @@ enum ssb_bustype {
 | 
						|
 	SSB_BUSTYPE_SSB,	/* This SSB bus is the system bus */
 | 
						|
 	SSB_BUSTYPE_PCI,	/* SSB is connected to PCI bus */
 | 
						|
 	SSB_BUSTYPE_PCMCIA,	/* SSB is connected to PCMCIA bus */
 | 
						|
+	SSB_BUSTYPE_SDIO,	/* SSB is connected to SDIO bus */
 | 
						|
 };
 | 
						|
 
 | 
						|
 /* board_vendor */
 | 
						|
@@ -240,8 +271,12 @@ struct ssb_bus {
 | 
						|
 
 | 
						|
 	/* The core in the basic address register window. (PCI bus only) */
 | 
						|
 	struct ssb_device *mapped_device;
 | 
						|
-	/* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
 | 
						|
-	u8 mapped_pcmcia_seg;
 | 
						|
+	union {
 | 
						|
+		/* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
 | 
						|
+		u8 mapped_pcmcia_seg;
 | 
						|
+		/* Current SSB base address window for SDIO. */
 | 
						|
+		u32 sdio_sbaddr;
 | 
						|
+	};
 | 
						|
 	/* Lock for core and segment switching.
 | 
						|
 	 * On PCMCIA-host busses this is used to protect the whole MMIO access. */
 | 
						|
 	spinlock_t bar_lock;
 | 
						|
@@ -252,6 +287,11 @@ struct ssb_bus {
 | 
						|
 	struct pci_dev *host_pci;
 | 
						|
 	/* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
 | 
						|
 	struct pcmcia_device *host_pcmcia;
 | 
						|
+	/* Pointer to the SDIO device (only if bustype == SSB_BUSTYPE_SDIO). */
 | 
						|
+	struct sdio_func *host_sdio;
 | 
						|
+
 | 
						|
+	/* See enum ssb_quirks */
 | 
						|
+	unsigned int quirks;
 | 
						|
 
 | 
						|
 #ifdef CONFIG_SSB_SPROM
 | 
						|
 	/* Mutex to protect the SPROM writing. */
 | 
						|
@@ -306,6 +346,11 @@ struct ssb_bus {
 | 
						|
 #endif /* DEBUG */
 | 
						|
 };
 | 
						|
 
 | 
						|
+enum ssb_quirks {
 | 
						|
+	/* SDIO connected card requires performing a read after writing a 32-bit value */
 | 
						|
+	SSB_QUIRK_SDIO_READ_AFTER_WRITE32	= (1 << 0),
 | 
						|
+};
 | 
						|
+
 | 
						|
 /* The initialization-invariants. */
 | 
						|
 struct ssb_init_invariants {
 | 
						|
 	/* Versioning information about the PCB. */
 | 
						|
--- a/include/linux/ssb/ssb_driver_chipcommon.h
 | 
						|
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
 | 
						|
@@ -629,5 +629,15 @@ extern int ssb_chipco_serial_init(struct
 | 
						|
 /* PMU support */
 | 
						|
 extern void ssb_pmu_init(struct ssb_chipcommon *cc);
 | 
						|
 
 | 
						|
+enum ssb_pmu_ldo_volt_id {
 | 
						|
+	LDO_PAREF = 0,
 | 
						|
+	LDO_VOLT1,
 | 
						|
+	LDO_VOLT2,
 | 
						|
+	LDO_VOLT3,
 | 
						|
+};
 | 
						|
+
 | 
						|
+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
 | 
						|
+			     enum ssb_pmu_ldo_volt_id id, u32 voltage);
 | 
						|
+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
 | 
						|
 
 | 
						|
 #endif /* LINUX_SSB_CHIPCO_H_ */
 | 
						|
--- a/include/linux/ssb/ssb_regs.h
 | 
						|
+++ b/include/linux/ssb/ssb_regs.h
 | 
						|
@@ -162,7 +162,7 @@
 | 
						|
 
 | 
						|
 /* SPROM shadow area. If not otherwise noted, fields are
 | 
						|
  * two bytes wide. Note that the SPROM can _only_ be read
 | 
						|
- * in two-byte quantinies.
 | 
						|
+ * in two-byte quantities.
 | 
						|
  */
 | 
						|
 #define SSB_SPROMSIZE_WORDS		64
 | 
						|
 #define SSB_SPROMSIZE_BYTES		(SSB_SPROMSIZE_WORDS * sizeof(u16))
 | 
						|
@@ -327,8 +327,11 @@
 | 
						|
 #define  SSB_SPROM5_GPIOB_P3_SHIFT	8
 | 
						|
 
 | 
						|
 /* SPROM Revision 8 */
 | 
						|
-#define SSB_SPROM8_BFLLO		0x1084	/* Boardflags (low 16 bits) */
 | 
						|
-#define SSB_SPROM8_BFLHI		0x1086	/* Boardflags Hi */
 | 
						|
+#define SSB_SPROM8_BOARDREV		0x1082	/* Board revision */
 | 
						|
+#define SSB_SPROM8_BFLLO		0x1084	/* Board flags (bits 0-15) */
 | 
						|
+#define SSB_SPROM8_BFLHI		0x1086	/* Board flags (bits 16-31) */
 | 
						|
+#define SSB_SPROM8_BFL2LO		0x1088	/* Board flags (bits 32-47) */
 | 
						|
+#define SSB_SPROM8_BFL2HI		0x108A	/* Board flags (bits 48-63) */
 | 
						|
 #define SSB_SPROM8_IL0MAC		0x108C	/* 6 byte MAC address */
 | 
						|
 #define SSB_SPROM8_CCODE		0x1092	/* 2 byte country code */
 | 
						|
 #define SSB_SPROM8_ANTAVAIL		0x109C  /* Antenna available bitfields*/
 | 
						|
@@ -354,14 +357,63 @@
 | 
						|
 #define  SSB_SPROM8_GPIOB_P2		0x00FF	/* Pin 2 */
 | 
						|
 #define  SSB_SPROM8_GPIOB_P3		0xFF00	/* Pin 3 */
 | 
						|
 #define  SSB_SPROM8_GPIOB_P3_SHIFT	8
 | 
						|
-#define SSB_SPROM8_MAXP_BG		0x10C0  /* Max Power BG in path 1 */
 | 
						|
-#define  SSB_SPROM8_MAXP_BG_MASK	0x00FF  /* Mask for Max Power BG */
 | 
						|
+#define SSB_SPROM8_RSSIPARM2G		0x10A4	/* RSSI params for 2GHz */
 | 
						|
+#define  SSB_SPROM8_RSSISMF2G		0x000F
 | 
						|
+#define  SSB_SPROM8_RSSISMC2G		0x00F0
 | 
						|
+#define  SSB_SPROM8_RSSISMC2G_SHIFT	4
 | 
						|
+#define  SSB_SPROM8_RSSISAV2G		0x0700
 | 
						|
+#define  SSB_SPROM8_RSSISAV2G_SHIFT	8
 | 
						|
+#define  SSB_SPROM8_BXA2G		0x1800
 | 
						|
+#define  SSB_SPROM8_BXA2G_SHIFT		11
 | 
						|
+#define SSB_SPROM8_RSSIPARM5G		0x10A6	/* RSSI params for 5GHz */
 | 
						|
+#define  SSB_SPROM8_RSSISMF5G		0x000F
 | 
						|
+#define  SSB_SPROM8_RSSISMC5G		0x00F0
 | 
						|
+#define  SSB_SPROM8_RSSISMC5G_SHIFT	4
 | 
						|
+#define  SSB_SPROM8_RSSISAV5G		0x0700
 | 
						|
+#define  SSB_SPROM8_RSSISAV5G_SHIFT	8
 | 
						|
+#define  SSB_SPROM8_BXA5G		0x1800
 | 
						|
+#define  SSB_SPROM8_BXA5G_SHIFT		11
 | 
						|
+#define SSB_SPROM8_TRI25G		0x10A8	/* TX isolation 2.4&5.3GHz */
 | 
						|
+#define  SSB_SPROM8_TRI2G		0x00FF	/* TX isolation 2.4GHz */
 | 
						|
+#define  SSB_SPROM8_TRI5G		0xFF00	/* TX isolation 5.3GHz */
 | 
						|
+#define  SSB_SPROM8_TRI5G_SHIFT		8
 | 
						|
+#define SSB_SPROM8_TRI5GHL		0x10AA	/* TX isolation 5.2/5.8GHz */
 | 
						|
+#define  SSB_SPROM8_TRI5GL		0x00FF	/* TX isolation 5.2GHz */
 | 
						|
+#define  SSB_SPROM8_TRI5GH		0xFF00	/* TX isolation 5.8GHz */
 | 
						|
+#define  SSB_SPROM8_TRI5GH_SHIFT	8
 | 
						|
+#define SSB_SPROM8_RXPO			0x10AC  /* RX power offsets */
 | 
						|
+#define  SSB_SPROM8_RXPO2G		0x00FF	/* 2GHz RX power offset */
 | 
						|
+#define  SSB_SPROM8_RXPO5G		0xFF00	/* 5GHz RX power offset */
 | 
						|
+#define  SSB_SPROM8_RXPO5G_SHIFT	8
 | 
						|
+#define SSB_SPROM8_MAXP_BG		0x10C0  /* Max Power 2GHz in path 1 */
 | 
						|
+#define  SSB_SPROM8_MAXP_BG_MASK	0x00FF  /* Mask for Max Power 2GHz */
 | 
						|
 #define  SSB_SPROM8_ITSSI_BG		0xFF00	/* Mask for path 1 itssi_bg */
 | 
						|
 #define  SSB_SPROM8_ITSSI_BG_SHIFT	8
 | 
						|
-#define SSB_SPROM8_MAXP_A		0x10C8  /* Max Power A in path 1 */
 | 
						|
-#define  SSB_SPROM8_MAXP_A_MASK		0x00FF  /* Mask for Max Power A */
 | 
						|
+#define SSB_SPROM8_PA0B0		0x10C2	/* 2GHz power amp settings */
 | 
						|
+#define SSB_SPROM8_PA0B1		0x10C4
 | 
						|
+#define SSB_SPROM8_PA0B2		0x10C6
 | 
						|
+#define SSB_SPROM8_MAXP_A		0x10C8  /* Max Power 5.3GHz */
 | 
						|
+#define  SSB_SPROM8_MAXP_A_MASK		0x00FF  /* Mask for Max Power 5.3GHz */
 | 
						|
 #define  SSB_SPROM8_ITSSI_A		0xFF00	/* Mask for path 1 itssi_a */
 | 
						|
 #define  SSB_SPROM8_ITSSI_A_SHIFT	8
 | 
						|
+#define SSB_SPROM8_MAXP_AHL		0x10CA  /* Max Power 5.2/5.8GHz */
 | 
						|
+#define  SSB_SPROM8_MAXP_AH_MASK	0x00FF  /* Mask for Max Power 5.8GHz */
 | 
						|
+#define  SSB_SPROM8_MAXP_AL_MASK	0xFF00  /* Mask for Max Power 5.2GHz */
 | 
						|
+#define  SSB_SPROM8_MAXP_AL_SHIFT	8
 | 
						|
+#define SSB_SPROM8_PA1B0		0x10CC	/* 5.3GHz power amp settings */
 | 
						|
+#define SSB_SPROM8_PA1B1		0x10CE
 | 
						|
+#define SSB_SPROM8_PA1B2		0x10D0
 | 
						|
+#define SSB_SPROM8_PA1LOB0		0x10D2	/* 5.2GHz power amp settings */
 | 
						|
+#define SSB_SPROM8_PA1LOB1		0x10D4
 | 
						|
+#define SSB_SPROM8_PA1LOB2		0x10D6
 | 
						|
+#define SSB_SPROM8_PA1HIB0		0x10D8	/* 5.8GHz power amp settings */
 | 
						|
+#define SSB_SPROM8_PA1HIB1		0x10DA
 | 
						|
+#define SSB_SPROM8_PA1HIB2		0x10DC
 | 
						|
+#define SSB_SPROM8_CCK2GPO		0x1140	/* CCK power offset */
 | 
						|
+#define SSB_SPROM8_OFDM2GPO		0x1142	/* 2.4GHz OFDM power offset */
 | 
						|
+#define SSB_SPROM8_OFDM5GPO		0x1146	/* 5.3GHz OFDM power offset */
 | 
						|
+#define SSB_SPROM8_OFDM5GLPO		0x114A	/* 5.2GHz OFDM power offset */
 | 
						|
+#define SSB_SPROM8_OFDM5GHPO		0x114E	/* 5.8GHz OFDM power offset */
 | 
						|
 
 | 
						|
 /* Values for SSB_SPROM1_BINF_CCODE */
 | 
						|
 enum {
 |