Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/module.h>
  3#include <linux/netdevice.h>
  4#include <linux/platform_device.h>
  5#include <linux/zorro.h>
  6#include <net/ax88796.h>
  7#include <asm/amigaints.h>
  8
  9#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100 \
 10		ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x64, 0)
 11
 12#define XS100_IRQSTATUS_BASE 0x40
 13#define XS100_8390_BASE 0x800
 14
 15/* Longword-access area. Translated to 2 16-bit access cycles by the
 16 * X-Surf 100 FPGA
 17 */
 18#define XS100_8390_DATA32_BASE 0x8000
 19#define XS100_8390_DATA32_SIZE 0x2000
 20/* Sub-Areas for fast data register access; addresses relative to area begin */
 21#define XS100_8390_DATA_READ32_BASE 0x0880
 22#define XS100_8390_DATA_WRITE32_BASE 0x0C80
 23#define XS100_8390_DATA_AREA_SIZE 0x80
 24
 25#define __NS8390_init ax_NS8390_init
 26
 27/* force unsigned long back to 'void __iomem *' */
 28#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
 29
 30#define ei_inb(_a) z_readb(ax_convert_addr(_a))
 31#define ei_outb(_v, _a) z_writeb(_v, ax_convert_addr(_a))
 32
 33#define ei_inw(_a) z_readw(ax_convert_addr(_a))
 34#define ei_outw(_v, _a) z_writew(_v, ax_convert_addr(_a))
 35
 36#define ei_inb_p(_a) ei_inb(_a)
 37#define ei_outb_p(_v, _a) ei_outb(_v, _a)
 38
 39/* define EI_SHIFT() to take into account our register offsets */
 40#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
 41
 42/* Ensure we have our RCR base value */
 43#define AX88796_PLATFORM
 44
 45static unsigned char version[] =
 46		"ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
 47
 48#include "lib8390.c"
 49
 50/* from ne.c */
 51#define NE_CMD		EI_SHIFT(0x00)
 52#define NE_RESET	EI_SHIFT(0x1f)
 53#define NE_DATAPORT	EI_SHIFT(0x10)
 54
 55struct xsurf100_ax_plat_data {
 56	struct ax_plat_data ax;
 57	void __iomem *base_regs;
 58	void __iomem *data_area;
 59};
 60
 61static int is_xsurf100_network_irq(struct platform_device *pdev)
 62{
 63	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
 64
 65	return (readw(xs100->base_regs + XS100_IRQSTATUS_BASE) & 0xaaaa) != 0;
 66}
 67
 68/* These functions guarantee that the iomem is accessed with 32 bit
 69 * cycles only. z_memcpy_fromio / z_memcpy_toio don't
 70 */
 71static void z_memcpy_fromio32(void *dst, const void __iomem *src, size_t bytes)
 72{
 73	while (bytes > 32) {
 74		asm __volatile__
 75		   ("movem.l (%0)+,%%d0-%%d7\n"
 76		    "movem.l %%d0-%%d7,(%1)\n"
 77		    "adda.l #32,%1" : "=a"(src), "=a"(dst)
 78		    : "0"(src), "1"(dst) : "d0", "d1", "d2", "d3", "d4",
 79					   "d5", "d6", "d7", "memory");
 80		bytes -= 32;
 81	}
 82	while (bytes) {
 83		*(uint32_t *)dst = z_readl(src);
 84		src += 4;
 85		dst += 4;
 86		bytes -= 4;
 87	}
 88}
 89
 90static void z_memcpy_toio32(void __iomem *dst, const void *src, size_t bytes)
 91{
 92	while (bytes) {
 93		z_writel(*(const uint32_t *)src, dst);
 94		src += 4;
 95		dst += 4;
 96		bytes -= 4;
 97	}
 98}
 99
100static void xs100_write(struct net_device *dev, const void *src,
101			unsigned int count)
102{
103	struct ei_device *ei_local = netdev_priv(dev);
104	struct platform_device *pdev = to_platform_device(dev->dev.parent);
105	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
106
107	/* copy whole blocks */
108	while (count > XS100_8390_DATA_AREA_SIZE) {
109		z_memcpy_toio32(xs100->data_area +
110				XS100_8390_DATA_WRITE32_BASE, src,
111				XS100_8390_DATA_AREA_SIZE);
112		src += XS100_8390_DATA_AREA_SIZE;
113		count -= XS100_8390_DATA_AREA_SIZE;
114	}
115	/* copy whole dwords */
116	z_memcpy_toio32(xs100->data_area + XS100_8390_DATA_WRITE32_BASE,
117			src, count & ~3);
118	src += count & ~3;
119	if (count & 2) {
120		ei_outw(*(uint16_t *)src, ei_local->mem + NE_DATAPORT);
121		src += 2;
122	}
123	if (count & 1)
124		ei_outb(*(uint8_t *)src, ei_local->mem + NE_DATAPORT);
125}
126
127static void xs100_read(struct net_device *dev, void *dst, unsigned int count)
128{
129	struct ei_device *ei_local = netdev_priv(dev);
130	struct platform_device *pdev = to_platform_device(dev->dev.parent);
131	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
132
133	/* copy whole blocks */
134	while (count > XS100_8390_DATA_AREA_SIZE) {
135		z_memcpy_fromio32(dst, xs100->data_area +
136				  XS100_8390_DATA_READ32_BASE,
137				  XS100_8390_DATA_AREA_SIZE);
138		dst += XS100_8390_DATA_AREA_SIZE;
139		count -= XS100_8390_DATA_AREA_SIZE;
140	}
141	/* copy whole dwords */
142	z_memcpy_fromio32(dst, xs100->data_area + XS100_8390_DATA_READ32_BASE,
143			  count & ~3);
144	dst += count & ~3;
145	if (count & 2) {
146		*(uint16_t *)dst = ei_inw(ei_local->mem + NE_DATAPORT);
147		dst += 2;
148	}
149	if (count & 1)
150		*(uint8_t *)dst = ei_inb(ei_local->mem + NE_DATAPORT);
151}
152
153/* Block input and output, similar to the Crynwr packet driver. If
154 * you are porting to a new ethercard, look at the packet driver
155 * source for hints. The NEx000 doesn't share the on-board packet
156 * memory -- you have to put the packet out through the "remote DMA"
157 * dataport using ei_outb.
158 */
159static void xs100_block_input(struct net_device *dev, int count,
160			      struct sk_buff *skb, int ring_offset)
161{
162	struct ei_device *ei_local = netdev_priv(dev);
163	void __iomem *nic_base = ei_local->mem;
164	char *buf = skb->data;
165
166	if (ei_local->dmaing) {
167		netdev_err(dev,
168			   "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
169			   __func__,
170			   ei_local->dmaing, ei_local->irqlock);
171		return;
172	}
173
174	ei_local->dmaing |= 0x01;
175
176	ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
177	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
178	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
179	ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
180	ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
181	ei_outb(E8390_RREAD + E8390_START, nic_base + NE_CMD);
182
183	xs100_read(dev, buf, count);
184
185	ei_local->dmaing &= ~1;
186}
187
188static void xs100_block_output(struct net_device *dev, int count,
189			       const unsigned char *buf, const int start_page)
190{
191	struct ei_device *ei_local = netdev_priv(dev);
192	void __iomem *nic_base = ei_local->mem;
193	unsigned long dma_start;
194
195	/* Round the count up for word writes. Do we need to do this?
196	 * What effect will an odd byte count have on the 8390?  I
197	 * should check someday.
198	 */
199	if (ei_local->word16 && (count & 0x01))
200		count++;
201
202	/* This *shouldn't* happen. If it does, it's the last thing
203	 * you'll see
204	 */
205	if (ei_local->dmaing) {
206		netdev_err(dev,
207			   "DMAing conflict in %s [DMAstat:%d][irqlock:%d]\n",
208			   __func__,
209			   ei_local->dmaing, ei_local->irqlock);
210		return;
211	}
212
213	ei_local->dmaing |= 0x01;
214	/* We should already be in page 0, but to be safe... */
215	ei_outb(E8390_PAGE0 + E8390_START + E8390_NODMA, nic_base + NE_CMD);
216
217	ei_outb(ENISR_RDC, nic_base + EN0_ISR);
218
219	/* Now the normal output. */
220	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
221	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
222	ei_outb(0x00, nic_base + EN0_RSARLO);
223	ei_outb(start_page, nic_base + EN0_RSARHI);
224
225	ei_outb(E8390_RWRITE + E8390_START, nic_base + NE_CMD);
226
227	xs100_write(dev, buf, count);
228
229	dma_start = jiffies;
230
231	while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
232		if (jiffies - dma_start > 2 * HZ / 100) {	/* 20ms */
233			netdev_warn(dev, "timeout waiting for Tx RDC.\n");
234			ei_local->reset_8390(dev);
235			ax_NS8390_init(dev, 1);
236			break;
237		}
238	}
239
240	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
241	ei_local->dmaing &= ~0x01;
242}
243
244static int xsurf100_probe(struct zorro_dev *zdev,
245			  const struct zorro_device_id *ent)
246{
247	struct platform_device *pdev;
248	struct xsurf100_ax_plat_data ax88796_data;
249	struct resource res[2] = {
250		DEFINE_RES_NAMED(IRQ_AMIGA_PORTS, 1, NULL,
251				 IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE),
252		DEFINE_RES_MEM(zdev->resource.start + XS100_8390_BASE,
253			       4 * 0x20)
254	};
255	int reg;
256	/* This table is referenced in the device structure, so it must
257	 * outlive the scope of xsurf100_probe.
258	 */
259	static u32 reg_offsets[32];
260	int ret = 0;
261
262	/* X-Surf 100 control and 32 bit ring buffer data access areas.
263	 * These resources are not used by the ax88796 driver, so must
264	 * be requested here and passed via platform data.
265	 */
266
267	if (!request_mem_region(zdev->resource.start, 0x100, zdev->name)) {
268		dev_err(&zdev->dev, "cannot reserve X-Surf 100 control registers\n");
269		return -ENXIO;
270	}
271
272	if (!request_mem_region(zdev->resource.start +
273				XS100_8390_DATA32_BASE,
274				XS100_8390_DATA32_SIZE,
275				"X-Surf 100 32-bit data access")) {
276		dev_err(&zdev->dev, "cannot reserve 32-bit area\n");
277		ret = -ENXIO;
278		goto exit_req;
279	}
280
281	for (reg = 0; reg < 0x20; reg++)
282		reg_offsets[reg] = 4 * reg;
283
284	memset(&ax88796_data, 0, sizeof(ax88796_data));
285	ax88796_data.ax.flags = AXFLG_HAS_EEPROM;
286	ax88796_data.ax.wordlength = 2;
287	ax88796_data.ax.dcr_val = 0x48;
288	ax88796_data.ax.rcr_val = 0x40;
289	ax88796_data.ax.reg_offsets = reg_offsets;
290	ax88796_data.ax.check_irq = is_xsurf100_network_irq;
291	ax88796_data.base_regs = ioremap(zdev->resource.start, 0x100);
292
293	/* error handling for ioremap regs */
294	if (!ax88796_data.base_regs) {
295		dev_err(&zdev->dev, "Cannot ioremap area %pR (registers)\n",
296			&zdev->resource);
297
298		ret = -ENXIO;
299		goto exit_req2;
300	}
301
302	ax88796_data.data_area = ioremap(zdev->resource.start +
303			XS100_8390_DATA32_BASE, XS100_8390_DATA32_SIZE);
304
305	/* error handling for ioremap data */
306	if (!ax88796_data.data_area) {
307		dev_err(&zdev->dev,
308			"Cannot ioremap area %pR offset %x (32-bit access)\n",
309			&zdev->resource,  XS100_8390_DATA32_BASE);
310
311		ret = -ENXIO;
312		goto exit_mem;
313	}
314
315	ax88796_data.ax.block_output = xs100_block_output;
316	ax88796_data.ax.block_input = xs100_block_input;
317
318	pdev = platform_device_register_resndata(&zdev->dev, "ax88796",
319						 zdev->slotaddr, res, 2,
320						 &ax88796_data,
321						 sizeof(ax88796_data));
322
323	if (IS_ERR(pdev)) {
324		dev_err(&zdev->dev, "cannot register platform device\n");
325		ret = -ENXIO;
326		goto exit_mem2;
327	}
328
329	zorro_set_drvdata(zdev, pdev);
330
331	if (!ret)
332		return 0;
333
334 exit_mem2:
335	iounmap(ax88796_data.data_area);
336
337 exit_mem:
338	iounmap(ax88796_data.base_regs);
339
340 exit_req2:
341	release_mem_region(zdev->resource.start + XS100_8390_DATA32_BASE,
342			   XS100_8390_DATA32_SIZE);
343
344 exit_req:
345	release_mem_region(zdev->resource.start, 0x100);
346
347	return ret;
348}
349
350static void xsurf100_remove(struct zorro_dev *zdev)
351{
352	struct platform_device *pdev = zorro_get_drvdata(zdev);
353	struct xsurf100_ax_plat_data *xs100 = dev_get_platdata(&pdev->dev);
354
355	platform_device_unregister(pdev);
356
357	iounmap(xs100->base_regs);
358	release_mem_region(zdev->resource.start, 0x100);
359	iounmap(xs100->data_area);
360	release_mem_region(zdev->resource.start + XS100_8390_DATA32_BASE,
361			   XS100_8390_DATA32_SIZE);
362}
363
364static const struct zorro_device_id xsurf100_zorro_tbl[] = {
365	{ ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF100, },
366	{ 0 }
367};
368
369MODULE_DEVICE_TABLE(zorro, xsurf100_zorro_tbl);
370
371static struct zorro_driver xsurf100_driver = {
372	.name           = "xsurf100",
373	.id_table       = xsurf100_zorro_tbl,
374	.probe          = xsurf100_probe,
375	.remove         = xsurf100_remove,
376};
377
378module_driver(xsurf100_driver, zorro_register_driver, zorro_unregister_driver);
379
380MODULE_DESCRIPTION("X-Surf 100 driver");
381MODULE_AUTHOR("Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de>");
382MODULE_LICENSE("GPL v2");