linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* MMC/SD, SPI and IXP4XX
@ 2008-08-08  9:11 Miguel Ángel Álvarez
       [not found] ` <55147.216.207.242.34.1218196029.squirrel@www.texascellnet.com>
  0 siblings, 1 reply; 2+ messages in thread
From: Miguel Ángel Álvarez @ 2008-08-08  9:11 UTC (permalink / raw)
  To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 886 bytes --]

Hi.

Some days ago I have sent a mail about using an SD card through SPI in an
IXP4XX system.

Let me ask again for some help.
- I have seen pxa2xx_spi driver, and as it seems quite interesting for me, I
have beginned to port it to my platform. I attach the preliminary patch,
just in case it is useful for somebody... It is not tested yet, however.
- To test it I am trying to read information about using an SD card, but I
am quite confussed by now... It seems there is some kind of mmc_spi driver
in latest kernels, but I do not know how all the pieces oz the puzzle mach
together. Any help would be appreciated.

In my case I am using kernel 2.6.18 (trying to migrate to newer releases,
but not quite successfull yet), but if the help comes "explaining the
concept" in 2.6.24 or other kernels, it will also be quite useful.

Thanks a lot.

Miguel Ángel Álvarez

[-- Attachment #1.2: Type: text/html, Size: 943 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 90105-spi.patch --]
[-- Type: text/x-diff; name=90105-spi.patch, Size: 26266 bytes --]

diff -urP linux-2.6.18.3/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-2.6.18.3_spi3/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux-2.6.18.3/arch/arm/mach-ixp4xx/ixdp425-setup.c	2006-11-19 04:28:22.000000000 +0100
+++ linux-2.6.18.3_spi3/arch/arm/mach-ixp4xx/ixdp425-setup.c	2008-08-08 09:46:23.000000000 +0200
@@ -101,10 +101,40 @@
 	.resource		= ixdp425_uart_resources
 };
 
+static struct resource ixdp425_spi_resources[] = {
+	{
+		.start		= IXP4XX_SSP_BASE_PHYS,
+		.end		= IXP4XX_SSP_BASE_PHYS + 0x14,
+		.flags		= IORESOURCE_MEM
+	},
+	{
+		.start		= IRQ_IXP4XX_SSP,
+		.end		= IRQ_IXP4XX_SSP,
+		.flags		= IORESOURCE_IRQ
+	}
+};
+
+static struct pxa2xx_spi_master ixdp425_master_info = {
+	.ssp_type = PXA25x_SSP,
+	.num_chipselect = 1,
+	.enable_dma = 0,
+};
+
+static struct platform_device ixdp425_spi = {
+	.name = "pxa2xx-spi",
+	.id = 1,
+	.resource = ixdp425_spi_resources,
+	.num_resources = ARRAY_SIZE(ixdp425_spi_resources),
+	.dev = {
+		.platform_data = &ixdp425_master_info,
+	},
+};
+
 static struct platform_device *ixdp425_devices[] __initdata = {
 	&ixdp425_i2c_controller,
 	&ixdp425_flash,
-	&ixdp425_uart
+	&ixdp425_uart,
+	&ixdp425_spi
 };
 
 static void __init ixdp425_init(void)
diff -urP linux-2.6.18.3/drivers/spi/Kconfig linux-2.6.18.3_spi3/drivers/spi/Kconfig
--- linux-2.6.18.3/drivers/spi/Kconfig	2006-11-19 04:28:22.000000000 +0100
+++ linux-2.6.18.3_spi3/drivers/spi/Kconfig	2008-08-08 09:47:46.000000000 +0200
@@ -89,7 +89,7 @@
 
 config SPI_PXA2XX
 	tristate "PXA2xx SSP SPI master"
-	depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
+	depends on SPI_MASTER && (ARCH_PXA || ARCH_IXP4XX) && EXPERIMENTAL
 	help
 	  This enables using a PXA2xx SSP port as a SPI master controller.
 	  The driver can be configured to use any SSP port and additional
diff -urP linux-2.6.18.3/drivers/spi/pxa2xx_spi.c linux-2.6.18.3_spi3/drivers/spi/pxa2xx_spi.c
--- linux-2.6.18.3/drivers/spi/pxa2xx_spi.c	2006-11-19 04:28:22.000000000 +0100
+++ linux-2.6.18.3_spi3/drivers/spi/pxa2xx_spi.c	2008-08-08 09:47:46.000000000 +0200
@@ -23,7 +23,9 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#ifdef CONFIG_ARCH_PXA
 #include <linux/dma-mapping.h>
+#endif
 #include <linux/spi/spi.h>
 #include <linux/workqueue.h>
 #include <linux/errno.h>
@@ -33,11 +35,18 @@
 #include <asm/irq.h>
 #include <asm/hardware.h>
 #include <asm/delay.h>
+#ifdef CONFIG_ARCH_PXA
 #include <asm/dma.h>
+#endif
 
 #include <asm/arch/hardware.h>
+#ifdef CONFIG_ARCH_PXA
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/pxa2xx_spi.h>
+#endif
+#ifdef CONFIG_ARCH_IXP4XX
+#include <asm/arch/ixp4xx-regs.h>
+#endif
 
 MODULE_AUTHOR("Stephen Street");
 MODULE_DESCRIPTION("PXA2xx SSP SPI Contoller");
@@ -45,9 +54,11 @@
 
 #define MAX_BUSES 3
 
+#ifdef CONFIG_ARCH_PXA
 #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
 #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
 #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
+#endif
 
 #define DEFINE_SSP_REG(reg, off) \
 static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \
@@ -83,14 +94,18 @@
 	/* DMA setup stuff */
 	int rx_channel;
 	int tx_channel;
+#ifdef CONFIG_ARCH_PXA
 	u32 *null_dma_buf;
+#endif
 
 	/* SSP register addresses */
 	void *ioaddr;
 	u32 ssdr_physical;
 
 	/* SSP masks*/
+#ifdef CONFIG_ARCH_PXA
 	u32 dma_cr1;
+#endif
 	u32 int_cr1;
 	u32 clear_sr;
 	u32 mask_sr;
@@ -115,13 +130,17 @@
 	void *tx_end;
 	void *rx;
 	void *rx_end;
+#ifdef CONFIG_ARCH_PXA
 	int dma_mapped;
 	dma_addr_t rx_dma;
 	dma_addr_t tx_dma;
+#endif
 	size_t rx_map_len;
 	size_t tx_map_len;
 	u8 n_bytes;
+#ifdef CONFIG_ARCH_PXA
 	u32 dma_width;
+#endif
 	int cs_change;
 	void (*write)(struct driver_data *drv_data);
 	void (*read)(struct driver_data *drv_data);
@@ -136,11 +155,15 @@
 	u32 psp;
 	u32 timeout;
 	u8 n_bytes;
+#ifdef CONFIG_ARCH_PXA
 	u32 dma_width;
 	u32 dma_burst_size;
+#endif
 	u32 threshold;
+#ifdef CONFIG_ARCH_PXA
 	u32 dma_threshold;
 	u8 enable_dma;
+#endif
 	u8 bits_per_word;
 	u32 speed_hz;
 	void (*write)(struct driver_data *drv_data);
@@ -292,6 +315,7 @@
 		return DONE_STATE;
 }
 
+#ifdef CONFIG_ARCH_PXA
 static int map_dma_buffers(struct driver_data *drv_data)
 {
 	struct spi_message *msg = drv_data->cur_msg;
@@ -343,7 +367,9 @@
 
 	return 1;
 }
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 static void unmap_dma_buffers(struct driver_data *drv_data)
 {
 	struct device *dev;
@@ -361,6 +387,7 @@
 
 	drv_data->dma_mapped = 0;
 }
+#endif
 
 /* caller already set message->status; dma and pio irqs are blocked */
 static void giveback(struct driver_data *drv_data)
@@ -399,6 +426,7 @@
 	return limit;
 }
 
+#ifdef CONFIG_ARCH_PXA
 static int wait_dma_channel_stop(int channel)
 {
 	unsigned long limit = loops_per_jiffy << 1;
@@ -408,7 +436,9 @@
 
 	return limit;
 }
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 static void dma_handler(int channel, void *data, struct pt_regs *regs)
 {
 	struct driver_data *drv_data = data;
@@ -492,7 +522,9 @@
 		tasklet_schedule(&drv_data->pump_transfers);
 	}
 }
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 static irqreturn_t dma_transfer(struct driver_data *drv_data)
 {
 	u32 irq_status;
@@ -576,6 +608,7 @@
 	/* Opps problem detected */
 	return IRQ_NONE;
 }
+#endif
 
 static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 {
@@ -613,9 +646,11 @@
 		}
 
 		/* Look for false positive timeout */
+#ifdef CONFIG_ARCH_PXA
 		if ((irq_status & SSSR_TINT)
 				&& (drv_data->rx < drv_data->rx_end))
 			write_SSSR(SSSR_TINT, reg);
+#endif
 
 		/* Pump data */
 		drv_data->read(drv_data);
@@ -638,8 +673,11 @@
 			}
 		}
 
-		if ((irq_status & SSSR_TINT)
-				|| (drv_data->rx == drv_data->rx_end)) {
+		if (
+#ifdef CONFIG_ARCH_PXA
+			(irq_status & SSSR_TINT) ||
+#endif
+			(drv_data->rx == drv_data->rx_end)) {
 
 			/* Clear timeout */
 			write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
@@ -739,14 +777,18 @@
 		return;
 	}
 	drv_data->n_bytes = chip->n_bytes;
+#ifdef CONFIG_ARCH_PXA
 	drv_data->dma_width = chip->dma_width;
+#endif
 	drv_data->cs_control = chip->cs_control;
 	drv_data->tx = (void *)transfer->tx_buf;
 	drv_data->tx_end = drv_data->tx + transfer->len;
 	drv_data->rx = transfer->rx_buf;
 	drv_data->rx_end = drv_data->rx + transfer->len;
+#ifdef CONFIG_ARCH_PXA
 	drv_data->rx_dma = transfer->rx_dma;
 	drv_data->tx_dma = transfer->tx_dma;
+#endif
 	drv_data->len = transfer->len;
 	drv_data->write = drv_data->tx ? chip->write : null_writer;
 	drv_data->read = drv_data->rx ? chip->read : null_reader;
@@ -769,28 +811,36 @@
 
 		if (reg == SSP1_VIRT)
 			clk_div = SSP1_SerClkDiv(speed);
+#ifdef CONFIG_ARCH_PXA
 		else if (reg == SSP2_VIRT)
 			clk_div = SSP2_SerClkDiv(speed);
 		else if (reg == SSP3_VIRT)
 			clk_div = SSP3_SerClkDiv(speed);
+#endif
 
 		if (bits <= 8) {
 			drv_data->n_bytes = 1;
+#ifdef CONFIG_ARCH_PXA
 			drv_data->dma_width = DCMD_WIDTH1;
+#endif
 			drv_data->read = drv_data->read != null_reader ?
 						u8_reader : null_reader;
 			drv_data->write = drv_data->write != null_writer ?
 						u8_writer : null_writer;
 		} else if (bits <= 16) {
 			drv_data->n_bytes = 2;
+#ifdef CONFIG_ARCH_PXA
 			drv_data->dma_width = DCMD_WIDTH2;
+#endif
 			drv_data->read = drv_data->read != null_reader ?
 						u16_reader : null_reader;
 			drv_data->write = drv_data->write != null_writer ?
 						u16_writer : null_writer;
 		} else if (bits <= 32) {
 			drv_data->n_bytes = 4;
+#ifdef CONFIG_ARCH_PXA
 			drv_data->dma_width = DCMD_WIDTH4;
+#endif
 			drv_data->read = drv_data->read != null_reader ?
 						u32_reader : null_reader;
 			drv_data->write = drv_data->write != null_writer ?
@@ -809,6 +859,7 @@
 
 	message->state = RUNNING_STATE;
 
+#ifdef CONFIG_ARCH_PXA
 	/* Try to map dma buffer and do a dma transfer if successful */
 	if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
 
@@ -866,7 +917,9 @@
 				| chip->dma_threshold
 				| drv_data->dma_cr1,
 				reg);
-	} else {
+	} else 
+#endif
+	{
 		/* Ensure we have the correct interrupt handler	*/
 		drv_data->transfer_handler = interrupt_transfer;
 
@@ -975,11 +1028,15 @@
 			return -ENOMEM;
 
 		chip->cs_control = null_cs_control;
+#ifdef CONFIG_ARCH_PXA
 		chip->enable_dma = 0;
+#endif
 		chip->timeout = SSP_TIMEOUT(1000);
 		chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
+#ifdef CONFIG_ARCH_PXA
 		chip->dma_burst_size = drv_data->master_info->enable_dma ?
 					DCMD_BURST8 : 0;
+#endif
 
 		chip_info = spi->controller_data;
 	}
@@ -994,6 +1051,7 @@
 		chip->threshold = SSCR1_RxTresh(chip_info->rx_threshold)
 					| SSCR1_TxTresh(chip_info->tx_threshold);
 
+#ifdef CONFIG_ARCH_PXA
 		chip->enable_dma = chip_info->dma_burst_size != 0
 					&& drv_data->master_info->enable_dma;
 		chip->dma_threshold = 0;
@@ -1013,6 +1071,7 @@
 				chip->dma_burst_size = DCMD_BURST32;
 			}
 		}
+#endif
 
 
 		if (chip_info->enable_loopback)
@@ -1021,10 +1080,12 @@
 
 	if (drv_data->ioaddr == SSP1_VIRT)
 		clk_div = SSP1_SerClkDiv(spi->max_speed_hz);
+#ifdef CONFIG_ARCH_PXA
 	else if (drv_data->ioaddr == SSP2_VIRT)
 		clk_div = SSP2_SerClkDiv(spi->max_speed_hz);
 	else if (drv_data->ioaddr == SSP3_VIRT)
 		clk_div = SSP3_SerClkDiv(spi->max_speed_hz);
+#endif
 	else
 		return -ENODEV;
 	chip->speed_hz = spi->max_speed_hz;
@@ -1054,18 +1115,24 @@
 
 	if (spi->bits_per_word <= 8) {
 		chip->n_bytes = 1;
+#ifdef CONFIG_ARCH_PXA
 		chip->dma_width = DCMD_WIDTH1;
+#endif
 		chip->read = u8_reader;
 		chip->write = u8_writer;
 	} else if (spi->bits_per_word <= 16) {
 		chip->n_bytes = 2;
+#ifdef CONFIG_ARCH_PXA
 		chip->dma_width = DCMD_WIDTH2;
+#endif
 		chip->read = u16_reader;
 		chip->write = u16_writer;
 	} else if (spi->bits_per_word <= 32) {
 		chip->cr0 |= SSCR0_EDSS;
 		chip->n_bytes = 4;
+#ifdef CONFIG_ARCH_PXA
 		chip->dma_width = DCMD_WIDTH4;
+#endif
 		chip->read = u32_reader;
 		chip->write = u32_writer;
 	} else {
@@ -1179,6 +1246,8 @@
 	int irq;
 	int status = 0;
 
+	printk("pxa2xx-spi: probe\n");
+
 	platform_info = dev->platform_data;
 
 	if (platform_info->ssp_type == SSP_UNDEFINED) {
@@ -1204,8 +1273,10 @@
 	master->transfer = transfer;
 
 	drv_data->ssp_type = platform_info->ssp_type;
+#ifdef CONFIG_ARCH_PXA
 	drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data +
 						sizeof(struct driver_data)), 8);
+#endif
 
 	/* Setup register addresses */
 	memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1219,15 +1290,21 @@
 	drv_data->ssdr_physical = memory_resource->start + 0x00000010;
 	if (platform_info->ssp_type == PXA25x_SSP) {
 		drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
+#ifdef CONFIG_ARCH_PXA
 		drv_data->dma_cr1 = 0;
+#endif
 		drv_data->clear_sr = SSSR_ROR;
 		drv_data->mask_sr = SSSR_RFS | SSSR_TFS | SSSR_ROR;
-	} else {
+	}
+#ifdef CONFIG_ARCH_PXA
+	else {
 		drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE;
+
 		drv_data->dma_cr1 = SSCR1_TSRE | SSCR1_RSRE | SSCR1_TINTE;
 		drv_data->clear_sr = SSSR_ROR | SSSR_TINT;
 		drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
 	}
+#endif
 
 	/* Attach to IRQ */
 	irq = platform_get_irq(pdev, 0);
@@ -1243,6 +1320,9 @@
 		goto out_error_master_alloc;
 	}
 
+	printk("pxa2xx-spi: mem %08x irq %d\n", drv_data->ioaddr, irq);
+
+#ifdef CONFIG_ARCH_PXA
 	/* Setup DMA if requested */
 	drv_data->tx_channel = -1;
 	drv_data->rx_channel = -1;
@@ -1290,9 +1370,12 @@
 			goto out_error_dma_alloc;
 		}
 	}
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 	/* Enable SOC clock */
 	pxa_set_cken(platform_info->clock_enable, 1);
+#endif
 
 	/* Load default SSP configuration */
 	write_SSCR0(0, drv_data->ioaddr);
@@ -1325,22 +1408,30 @@
 		goto out_error_queue_alloc;
 	}
 
+	printk("pxa2xx-spi: probe finished with status %d\n", status);
+
 	return status;
 
 out_error_queue_alloc:
 	destroy_queue(drv_data);
 
 out_error_clock_enabled:
+#ifdef CONFIG_ARCH_PXA
 	pxa_set_cken(platform_info->clock_enable, 0);
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 out_error_dma_alloc:
 	if (drv_data->tx_channel != -1)
 		pxa_free_dma(drv_data->tx_channel);
 	if (drv_data->rx_channel != -1)
 		pxa_free_dma(drv_data->rx_channel);
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 out_error_irq_alloc:
 	free_irq(irq, drv_data);
+#endif
 
 out_error_master_alloc:
 	spi_master_put(master);
@@ -1363,8 +1454,11 @@
 
 	/* Disable the SSP at the peripheral and SOC level */
 	write_SSCR0(0, drv_data->ioaddr);
+#ifdef CONFIG_ARCH_PXA
 	pxa_set_cken(drv_data->master_info->clock_enable, 0);
+#endif
 
+#ifdef CONFIG_ARCH_PXA
 	/* Release DMA */
 	if (drv_data->master_info->enable_dma) {
 		if (drv_data->ioaddr == SSP1_VIRT) {
@@ -1380,6 +1474,7 @@
 		pxa_free_dma(drv_data->tx_channel);
 		pxa_free_dma(drv_data->rx_channel);
 	}
+#endif
 
 	/* Release IRQ */
 	irq = platform_get_irq(pdev, 0);
@@ -1441,8 +1536,10 @@
 	struct driver_data *drv_data = platform_get_drvdata(pdev);
 	int status = 0;
 
+#ifdef CONFIG_ARCH_PXA
 	/* Enable the SSP clock */
 	pxa_set_cken(drv_data->master_info->clock_enable, 1);
+#endif
 
 	/* Start the queue running */
 	status = start_queue(drv_data);
diff -urP linux-2.6.18.3/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h linux-2.6.18.3_spi3/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
--- linux-2.6.18.3/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h	2006-11-19 04:28:22.000000000 +0100
+++ linux-2.6.18.3_spi3/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h	2008-08-08 09:48:09.000000000 +0200
@@ -69,6 +69,7 @@
 #define IXP4XX_PERIPHERAL_BASE_PHYS	(0xC8000000)
 #define IXP4XX_PERIPHERAL_BASE_VIRT	(0xFFBEB000)
 #define IXP4XX_PERIPHERAL_REGION_SIZE	(0x00013000)
+#define io_p2v(x) (IXP4XX_PERIPHERAL_BASE_VIRT - IXP4XX_PERIPHERAL_BASE_PHYS + x)
 
 /*
  * Debug UART
@@ -622,4 +623,170 @@
 }
 #endif
 
+/*
+ * SSP Serial Port Registers
+ * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different.
+ * PXA255, PXA26x and PXA27x have extra ports, registers and bits.
+ * Modify for IXP4XX
+ */
+
+ /* Common bits first */
+#define SSCR0_DSS	(0x0000000f)	/* Data Size Select (mask) */
+#define SSCR0_DataSize(x)  ((x) - 1)	/* Data Size Select [4..16] */
+#define SSCR0_FRF	(0x00000030)	/* FRame Format (mask) */
+#define SSCR0_Motorola	(0x0 << 4)	/* Motorola's Serial Peripheral Interface (SPI) */
+#define SSCR0_TI	(0x1 << 4)	/* Texas Instruments' Synchronous Serial Protocol (SSP) */
+#define SSCR0_National	(0x2 << 4)	/* National Microwire */
+#define SSCR0_ECS	(1 << 6)	/* External clock select */
+#define SSCR0_SSE	(1 << 7)	/* Synchronous Serial Port Enable */
+#if defined CONFIG_PXA25x || defined CONFIG_ARCH_IXP4XX
+#define SSCR0_SCR	(0x0000ff00)	/* Serial Clock Rate (mask) */
+#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
+#elif defined(CONFIG_PXA27x)
+#define SSCR0_SCR	(0x000fff00)	/* Serial Clock Rate (mask) */
+#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
+#define SSCR0_EDSS	(1 << 20)	/* Extended data size select */
+#define SSCR0_NCS	(1 << 21)	/* Network clock select */
+#define SSCR0_RIM	(1 << 22)	/* Receive FIFO overrrun interrupt mask */
+#define SSCR0_TUM	(1 << 23)	/* Transmit FIFO underrun interrupt mask */
+#define SSCR0_FRDC	(0x07000000)	/* Frame rate divider control (mask) */
+#define SSCR0_SlotsPerFrm(x) ((x) - 1)	/* Time slots per frame [1..8] */
+#define SSCR0_ADC	(1 << 30)	/* Audio clock select */
+#define SSCR0_MOD	(1 << 31)	/* Mode (normal or network) */
+#endif
+
+#define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */
+#define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */
+#define SSCR1_LBM	(1 << 2)	/* Loop-Back Mode */
+#define SSCR1_SPO	(1 << 3)	/* Motorola SPI SSPSCLK polarity setting */
+#define SSCR1_SPH	(1 << 4)	/* Motorola SPI SSPSCLK phase setting */
+#define SSCR1_MWDS	(1 << 5)	/* Microwire Transmit Data Size */
+#define SSCR1_TFT	(0x000003c0)	/* Transmit FIFO Threshold (mask) */
+#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
+#define SSCR1_RFT	(0x00003c00)	/* Receive FIFO Threshold (mask) */
+#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
+
+#define SSSR_TNF	(1 << 2)	/* Transmit FIFO Not Full */
+#define SSSR_RNE	(1 << 3)	/* Receive FIFO Not Empty */
+#define SSSR_BSY	(1 << 4)	/* SSP Busy */
+#define SSSR_TFS	(1 << 5)	/* Transmit FIFO Service Request */
+#define SSSR_RFS	(1 << 6)	/* Receive FIFO Service Request */
+#define SSSR_ROR	(1 << 7)	/* Receive FIFO Overrun */
+
+#define SSCR0_TIM		(1 << 23)	/* Transmit FIFO Under Run Interrupt Mask */
+#define SSCR0_RIM		(1 << 22)	/* Receive FIFO Over Run interrupt Mask */
+#define SSCR0_NCS		(1 << 21)	/* Network Clock Select */
+#define SSCR0_EDSS		(1 << 20)	/* Extended Data Size Select */
+
+/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
+#if defined (CONFIG_ARCH_PXA)
+#define SSCR0_PSP		(3 << 4)	/* PSP - Programmable Serial Protocol */
+#define SSCR1_TTELP		(1 << 31)	/* TXD Tristate Enable Last Phase */
+#define SSCR1_TTE		(1 << 30)	/* TXD Tristate Enable */
+#define SSCR1_EBCEI		(1 << 29)	/* Enable Bit Count Error interrupt */
+#define SSCR1_SCFR		(1 << 28)	/* Slave Clock free Running */
+#define SSCR1_ECRA		(1 << 27)	/* Enable Clock Request A */
+#define SSCR1_ECRB		(1 << 26)	/* Enable Clock request B */
+#define SSCR1_SCLKDIR	(1 << 25)	/* Serial Bit Rate Clock Direction */
+#define SSCR1_SFRMDIR	(1 << 24)	/* Frame Direction */
+#define SSCR1_RWOT		(1 << 23)	/* Receive Without Transmit */
+#define SSCR1_TRAIL		(1 << 22)	/* Trailing Byte */
+#define SSCR1_TSRE		(1 << 21)	/* Transmit Service Request Enable */
+#define SSCR1_RSRE		(1 << 20)	/* Receive Service Request Enable */
+#define SSCR1_TINTE		(1 << 19)	/* Receiver Time-out Interrupt enable */
+#define SSCR1_PINTE		(1 << 18)	/* Peripheral Trailing Byte Interupt Enable */
+#define SSCR1_STRF		(1 << 15)	/* Select FIFO or EFWR */
+#define SSCR1_EFWR		(1 << 14)	/* Enable FIFO Write/Read */
+
+#define SSSR_BCE		(1 << 23)	/* Bit Count Error */
+#define SSSR_CSS		(1 << 22)	/* Clock Synchronisation Status */
+#define SSSR_TUR		(1 << 21)	/* Transmit FIFO Under Run */
+#define SSSR_EOC		(1 << 20)	/* End Of Chain */
+#define SSSR_TINT		(1 << 19)	/* Receiver Time-out Interrupt */
+#define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */
+
+#define SSPSP_DMYSTOP(x)	(x << 23)	/* Dummy Stop */
+#define SSPSP_SFRMWDTH(x)	(x << 16)	/* Serial Frame Width */
+#define SSPSP_SFRMDLY(x)	(x << 9)	/* Serial Frame Delay */
+#define SSPSP_DMYSTRT(x)	(x << 7)	/* Dummy Start */
+#define SSPSP_STRTDLY(x)	(x << 4)	/* Start Delay */
+#define SSPSP_ETDS			(1 << 3)	/* End of Transfer data State */
+#define SSPSP_SFRMP			(1 << 2)	/* Serial Frame Polarity */
+#define SSPSP_SCMODE(x)		(x << 0)	/* Serial Bit Rate Clock Mode */
+
+#define SSCR0_P1	__REG(0x41000000)  /* SSP Port 1 Control Register 0 */
+#define SSCR1_P1	__REG(0x41000004)  /* SSP Port 1 Control Register 1 */
+#define SSSR_P1		__REG(0x41000008)  /* SSP Port 1 Status Register */
+#define SSITR_P1	__REG(0x4100000C)  /* SSP Port 1 Interrupt Test Register */
+#define SSDR_P1		__REG(0x41000010)  /* (Write / Read) SSP Port 1 Data Write Register/SSP Data Read Register */
+#endif
+
+/* Support existing drivers */
+#define SSCR0		SSCR0_P1  /* SSP Control Register 0 */
+#define SSCR1		SSCR1_P1  /* SSP Control Register 1 */
+#define SSSR		SSSR_P1	  /* SSP Status Register */
+#define SSITR		SSITR_P1  /* SSP Interrupt Test Register */
+#define SSDR		SSDR_P1	  /* (Write / Read) SSP Data Write Register/SSP Data Read Register */
+
+/* PXA27x ports */
+#if defined (CONFIG_PXA27x)
+#define SSTO_P1		__REG(0x41000028)  /* SSP Port 1 Time Out Register */
+#define SSPSP_P1	__REG(0x4100002C)  /* SSP Port 1 Programmable Serial Protocol */
+#define SSTSA_P1	__REG(0x41000030)  /* SSP Port 1 Tx Timeslot Active */
+#define SSRSA_P1	__REG(0x41000034)  /* SSP Port 1 Rx Timeslot Active */
+#define SSTSS_P1	__REG(0x41000038)  /* SSP Port 1 Timeslot Status */
+#define SSACD_P1	__REG(0x4100003C)  /* SSP Port 1 Audio Clock Divider */
+#define SSCR0_P2	__REG(0x41700000)  /* SSP Port 2 Control Register 0 */
+#define SSCR1_P2	__REG(0x41700004)  /* SSP Port 2 Control Register 1 */
+#define SSSR_P2		__REG(0x41700008)  /* SSP Port 2 Status Register */
+#define SSITR_P2	__REG(0x4170000C)  /* SSP Port 2 Interrupt Test Register */
+#define SSDR_P2		__REG(0x41700010)  /* (Write / Read) SSP Port 2 Data Write Register/SSP Data Read Register */
+#define SSTO_P2		__REG(0x41700028)  /* SSP Port 2 Time Out Register */
+#define SSPSP_P2	__REG(0x4170002C)  /* SSP Port 2 Programmable Serial Protocol */
+#define SSTSA_P2	__REG(0x41700030)  /* SSP Port 2 Tx Timeslot Active */
+#define SSRSA_P2	__REG(0x41700034)  /* SSP Port 2 Rx Timeslot Active */
+#define SSTSS_P2	__REG(0x41700038)  /* SSP Port 2 Timeslot Status */
+#define SSACD_P2	__REG(0x4170003C)  /* SSP Port 2 Audio Clock Divider */
+#define SSCR0_P3	__REG(0x41900000)  /* SSP Port 3 Control Register 0 */
+#define SSCR1_P3	__REG(0x41900004)  /* SSP Port 3 Control Register 1 */
+#define SSSR_P3		__REG(0x41900008)  /* SSP Port 3 Status Register */
+#define SSITR_P3	__REG(0x4190000C)  /* SSP Port 3 Interrupt Test Register */
+#define SSDR_P3		__REG(0x41900010)  /* (Write / Read) SSP Port 3 Data Write Register/SSP Data Read Register */
+#define SSTO_P3		__REG(0x41900028)  /* SSP Port 3 Time Out Register */
+#define SSPSP_P3	__REG(0x4190002C)  /* SSP Port 3 Programmable Serial Protocol */
+#define SSTSA_P3	__REG(0x41900030)  /* SSP Port 3 Tx Timeslot Active */
+#define SSRSA_P3	__REG(0x41900034)  /* SSP Port 3 Rx Timeslot Active */
+#define SSTSS_P3	__REG(0x41900038)  /* SSP Port 3 Timeslot Status */
+#define SSACD_P3	__REG(0x4190003C)  /* SSP Port 3 Audio Clock Divider */
+#else /* PXA255 (only port 2) and PXA26x ports*/
+#define SSTO_P1		__REG(0x41000028)  /* SSP Port 1 Time Out Register */
+#define SSPSP_P1	__REG(0x4100002C)  /* SSP Port 1 Programmable Serial Protocol */
+#define SSCR0_P2	__REG(0x41400000)  /* SSP Port 2 Control Register 0 */
+#define SSCR1_P2	__REG(0x41400004)  /* SSP Port 2 Control Register 1 */
+#define SSSR_P2		__REG(0x41400008)  /* SSP Port 2 Status Register */
+#define SSITR_P2	__REG(0x4140000C)  /* SSP Port 2 Interrupt Test Register */
+#define SSDR_P2		__REG(0x41400010)  /* (Write / Read) SSP Port 2 Data Write Register/SSP Data Read Register */
+#define SSTO_P2		__REG(0x41400028)  /* SSP Port 2 Time Out Register */
+#define SSPSP_P2	__REG(0x4140002C)  /* SSP Port 2 Programmable Serial Protocol */
+#define SSCR0_P3	__REG(0x41500000)  /* SSP Port 3 Control Register 0 */
+#define SSCR1_P3	__REG(0x41500004)  /* SSP Port 3 Control Register 1 */
+#define SSSR_P3		__REG(0x41500008)  /* SSP Port 3 Status Register */
+#define SSITR_P3	__REG(0x4150000C)  /* SSP Port 3 Interrupt Test Register */
+#define SSDR_P3		__REG(0x41500010)  /* (Write / Read) SSP Port 3 Data Write Register/SSP Data Read Register */
+#define SSTO_P3		__REG(0x41500028)  /* SSP Port 3 Time Out Register */
+#define SSPSP_P3	__REG(0x4150002C)  /* SSP Port 3 Programmable Serial Protocol */
+#endif
+
+#define SSCR0_P(x) (*(((x) == 1) ? &SSCR0_P1 : ((x) == 2) ? &SSCR0_P2 : ((x) == 3) ? &SSCR0_P3 : NULL))
+#define SSCR1_P(x) (*(((x) == 1) ? &SSCR1_P1 : ((x) == 2) ? &SSCR1_P2 : ((x) == 3) ? &SSCR1_P3 : NULL))
+#define SSSR_P(x) (*(((x) == 1) ? &SSSR_P1 : ((x) == 2) ? &SSSR_P2 : ((x) == 3) ? &SSSR_P3 : NULL))
+#define SSITR_P(x) (*(((x) == 1) ? &SSITR_P1 : ((x) == 2) ? &SSITR_P2 : ((x) == 3) ? &SSITR_P3 : NULL))
+#define SSDR_P(x) (*(((x) == 1) ? &SSDR_P1 : ((x) == 2) ? &SSDR_P2 : ((x) == 3) ? &SSDR_P3 : NULL))
+#define SSTO_P(x) (*(((x) == 1) ? &SSTO_P1 : ((x) == 2) ? &SSTO_P2 : ((x) == 3) ? &SSTO_P3 : NULL))
+#define SSPSP_P(x) (*(((x) == 1) ? &SSPSP_P1 : ((x) == 2) ? &SSPSP_P2 : ((x) == 3) ? &SSPSP_P3 : NULL))
+#define SSTSA_P(x) (*(((x) == 1) ? &SSTSA_P1 : ((x) == 2) ? &SSTSA_P2 : ((x) == 3) ? &SSTSA_P3 : NULL))
+#define SSRSA_P(x) (*(((x) == 1) ? &SSRSA_P1 : ((x) == 2) ? &SSRSA_P2 : ((x) == 3) ? &SSRSA_P3 : NULL))
+#define SSTSS_P(x) (*(((x) == 1) ? &SSTSS_P1 : ((x) == 2) ? &SSTSS_P2 : ((x) == 3) ? &SSTSS_P3 : NULL))
+#define SSACD_P(x) (*(((x) == 1) ? &SSACD_P1 : ((x) == 2) ? &SSACD_P2 : ((x) == 3) ? &SSACD_P3 : NULL))
+
 #endif
diff -urP linux-2.6.18.3/include/asm-arm/arch-ixp4xx/platform.h linux-2.6.18.3_spi3/include/asm-arm/arch-ixp4xx/platform.h
--- linux-2.6.18.3/include/asm-arm/arch-ixp4xx/platform.h	2006-11-19 04:28:22.000000000 +0100
+++ linux-2.6.18.3_spi3/include/asm-arm/arch-ixp4xx/platform.h	2008-08-08 09:48:09.000000000 +0200
@@ -140,5 +140,64 @@
 	    *IXP4XX_GPIO_GPOUTR &= ~(1 << line);
 }
 
+#define PXA2XX_CS_ASSERT (0x01)
+#define PXA2XX_CS_DEASSERT (0x02)
+
+#if defined(CONFIG_PXA25x)
+#define CLOCK_SPEED_HZ 3686400
+#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/2/(x+1))<<8)&0x0000ff00)
+#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP_TIMEOUT_SCALE (2712)
+#elif defined(CONFIG_PXA27x)
+#define CLOCK_SPEED_HZ 13000000
+#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP_TIMEOUT_SCALE (769)
+#elif defined(CONFIG_ARCH_IXP4XX)
+#define CLOCK_SPEED_HZ 3686400
+#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/2/(x+1))<<8)&0x0000ff00)
+#define SSP_TIMEOUT_SCALE (2712)
+#endif
+
+#define SSP_TIMEOUT(x) ((x*10000)/SSP_TIMEOUT_SCALE)
+
+#ifdef CONFIG_ARCH_PXA
+#define SSP1_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(1)))))
+#define SSP2_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(2)))))
+#define SSP3_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(3)))))
+#endif
+#ifdef CONFIG_ARCH_IXP4XX
+#define SSP1_VIRT (void*)IXP4XX_SSP_BASE_VIRT
+#endif
+
+enum pxa_ssp_type {
+	SSP_UNDEFINED = 0,
+	PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
+	PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
+	PXA27x_SSP,
+};
+
+/* device.platform_data for SSP controller devices */
+struct pxa2xx_spi_master {
+	enum pxa_ssp_type ssp_type;
+	u32 clock_enable;
+	u16 num_chipselect;
+	u8 enable_dma;
+};
+
+/* spi_board_info.controller_data for SPI slave devices,
+ * copied to spi_device.platform_data ... mostly for dma tuning
+ */
+struct pxa2xx_spi_chip {
+	u8 tx_threshold;
+	u8 rx_threshold;
+	u8 dma_burst_size;
+	u32 timeout_microsecs;
+	u8 enable_loopback;
+	void (*cs_control)(u32 command);
+};
+
 #endif // __ASSEMBLY__
 


[-- Attachment #3: Type: text/plain, Size: 363 bytes --]

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

[-- Attachment #4: Type: text/plain, Size: 210 bytes --]

_______________________________________________
spi-devel-general mailing list
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: MMC/SD, SPI and IXP4XX
       [not found]           ` <16987.216.207.242.34.1218206865.squirrel-9hn5j+WQJqK63hpG0/mJ51aTQe2KTcn/@public.gmane.org>
@ 2008-08-08 15:20             ` Miguel Ángel Álvarez
  0 siblings, 0 replies; 2+ messages in thread
From: Miguel Ángel Álvarez @ 2008-08-08 15:20 UTC (permalink / raw)
  To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f


[-- Attachment #1.1: Type: text/plain, Size: 4930 bytes --]

Oooppps... It seems that I have been replying to Kbb instead of the list.
Let me send this mail with previous ones attached so that it can be useful
to anyone in my situation.

Hi Kbb

Perhaps I am not explaining myself correctly due to my English. My default
platform setup (which is arc/arm/mach-ixp4xx/ixdp425-setup.c), does not seem
to register a platform driver for SSP (not even in 2.6.26). That is why I
suppose that:

- No one has ever work in Linux with an IXP4XX and SSP.
- The work has not been submitted to the kernel.

As it seems there is not a platform driver for SSP in IXP4XX, I am trying to
figure how to build one (and of course, connect it to mmc_spi as you have
suggested me). I could have tried to build it from scratch, but I found that
pxa2xx_spi was quite similar to what I tried to do, and that is why I am
asking this mailing list if this is the correct way to do this.

Thanks again for your answer and time.

Miguel Ángel


On Fri, Aug 8, 2008 at 4:47 PM, <kbb-DU79CLUmun8xNU+NZBVoVw@public.gmane.org> wrote:

> No I am not familiar with the ixp465.  Look in the init file discussed
> earlier and look for the platform driver with SSP use.  Verify the resource
> addresses.
>
> open the mmc_spi and make sure it can connect to the last step.  and then
> go from there.
>
> Good luck.
>
> Kbb
>
>
> > Hi
> >
> > I see... Ok... I will have to figure if I can backport mmc_spi to
> 2.6.18.
> > So
> > mmc_spi is somekind of "protocol driver"?
> >
> > Thanks for your answers... Are you familiar with ixp4xx? I cannot see an
> > driver for the host SPI so I am trying to port the one of pxa2xx. Do you
> > know if this is the best alternative?
> >
> > Things start to be more clear (or more dark, because it seems there is
> > quite
> > a lot of code to rewrite...)
> >
> > Miguel Ángel
> >
> >
> > On Fri, Aug 8, 2008 at 3:39 PM, <kbb-DU79CLUmun8xNU+NZBVoVw@public.gmane.org> wrote:
> >
> >> You are right it does not support direct MMC.
> >>
> >> First enable the mmc_spi choice and the spi in the config file.
> >>
> >> I then had to go into the init file "/arch/arm/mach-???/????" that your
> >> system is using and fix the platform driver so that it recognizes the
> >> hardware attached. This then should give you the use of the mmc_spi
> >> driver.
> >>
> >> Kbb
> >>
> >>
> >> > Hi Kbb
> >> >
> >> > Thanks for your answer.
> >> >
> >> > As far as I know, IXP465 has not an MMC/SD port. That is why I think I
> >> > must
> >> > use the SPI port.
> >> >
> >> > Am I wrong?
> >> >
> >> > Miguel Ángel
> >> >
> >> > On Fri, Aug 8, 2008 at 1:47 PM, <kbb-DU79CLUmun8xNU+NZBVoVw@public.gmane.org> wrote:
> >> >
> >> >> How is your hardware attached? Is it only through the MMC/SD port?
> >> >>
> >> >> If so then you do not really need the MMC over SPI, just the pxamci
> >> >> driver.
> >> >>
> >> >> Kbb
> >> >>
> >> >>
> >> >>
> >> >> > Hi.
> >> >> >
> >> >> > Some days ago I have sent a mail about using an SD card through SPI
> >> in
> >> >> an
> >> >> > IXP4XX system.
> >> >> >
> >> >> > Let me ask again for some help.
> >> >> > - I have seen pxa2xx_spi driver, and as it seems quite interesting
> >> for
> >> >> me,
> >> >> > I
> >> >> > have beginned to port it to my platform. I attach the preliminary
> >> >> patch,
> >> >> > just in case it is useful for somebody... It is not tested yet,
> >> >> however.
> >> >> > - To test it I am trying to read information about using an SD
> >> card,
> >> >> but
> >> >> I
> >> >> > am quite confussed by now... It seems there is some kind of mmc_spi
> >> >> driver
> >> >> > in latest kernels, but I do not know how all the pieces oz the
> >> puzzle
> >> >> mach
> >> >> > together. Any help would be appreciated.
> >> >> >
> >> >> > In my case I am using kernel 2.6.18 (trying to migrate to newer
> >> >> releases,
> >> >> > but not quite successfull yet), but if the help comes "explaining
> >> the
> >> >> > concept" in 2.6.24 or other kernels, it will also be quite useful.
> >> >> >
> >> >> > Thanks a lot.
> >> >> >
> >> >> > Miguel Ángel Álvarez
> >> >> >
> >>
> -------------------------------------------------------------------------
> >> >> > This SF.Net email is sponsored by the Moblin Your Move Developer's
> >> >> > challenge
> >> >> > Build the coolest Linux based applications with Moblin SDK & win
> >> great
> >> >> > prizes
> >> >> > Grand prize is a trip for two to an Open Source event anywhere in
> >> the
> >> >> > world
> >> >> >
> >> >>
> >>
> http://moblin-contest.org/redirect.php?banner_id=100&url=/_______________________________________________
> >> >> > spi-devel-general mailing list
> >> >> > spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> >> >> > https://lists.sourceforge.net/lists/listinfo/spi-devel-general
> >> >> >
> >> >
> >>
> >
>

[-- Attachment #1.2: Type: text/html, Size: 7000 bytes --]

[-- Attachment #2: Type: text/plain, Size: 363 bytes --]

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

[-- Attachment #3: Type: text/plain, Size: 210 bytes --]

_______________________________________________
spi-devel-general mailing list
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-08-08 15:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-08  9:11 MMC/SD, SPI and IXP4XX Miguel Ángel Álvarez
     [not found] ` <55147.216.207.242.34.1218196029.squirrel@www.texascellnet.com>
     [not found]   ` <df996e0c0808080614g27b4eafaha073eb714b7f344a@mail.gmail.com>
     [not found]     ` <6927.216.207.242.34.1218202757.squirrel@www.texascellnet.com>
     [not found]       ` <df996e0c0808080737i22cf6a8dx7085457aed02e449@mail.gmail.com>
     [not found]         ` <16987.216.207.242.34.1218206865.squirrel@www.texascellnet.com>
     [not found]           ` <16987.216.207.242.34.1218206865.squirrel-9hn5j+WQJqK63hpG0/mJ51aTQe2KTcn/@public.gmane.org>
2008-08-08 15:20             ` Miguel Ángel Álvarez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).