162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci *  Copyright (C) 2007-2009 Geert Uytterhoeven
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
562306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
662306a36Sopenharmony_ci * for more details.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/err.h>
1062306a36Sopenharmony_ci#include <linux/init.h>
1162306a36Sopenharmony_ci#include <linux/platform_device.h>
1262306a36Sopenharmony_ci#include <linux/zorro.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <asm/amigahw.h>
1562306a36Sopenharmony_ci#include <asm/amigayle.h>
1662306a36Sopenharmony_ci#include <asm/byteorder.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifdef CONFIG_ZORRO
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic const struct resource zorro_resources[] __initconst = {
2262306a36Sopenharmony_ci	/* Zorro II regions (on Zorro II/III) */
2362306a36Sopenharmony_ci	{
2462306a36Sopenharmony_ci		.name	= "Zorro II exp",
2562306a36Sopenharmony_ci		.start	= 0x00e80000,
2662306a36Sopenharmony_ci		.end	= 0x00efffff,
2762306a36Sopenharmony_ci		.flags	= IORESOURCE_MEM,
2862306a36Sopenharmony_ci	}, {
2962306a36Sopenharmony_ci		.name	= "Zorro II mem",
3062306a36Sopenharmony_ci		.start	= 0x00200000,
3162306a36Sopenharmony_ci		.end	= 0x009fffff,
3262306a36Sopenharmony_ci		.flags	= IORESOURCE_MEM,
3362306a36Sopenharmony_ci	},
3462306a36Sopenharmony_ci	/* Zorro III regions (on Zorro III only) */
3562306a36Sopenharmony_ci	{
3662306a36Sopenharmony_ci		.name	= "Zorro III exp",
3762306a36Sopenharmony_ci		.start	= 0xff000000,
3862306a36Sopenharmony_ci		.end	= 0xffffffff,
3962306a36Sopenharmony_ci		.flags	= IORESOURCE_MEM,
4062306a36Sopenharmony_ci	}, {
4162306a36Sopenharmony_ci		.name	= "Zorro III cfg",
4262306a36Sopenharmony_ci		.start	= 0x40000000,
4362306a36Sopenharmony_ci		.end	= 0x7fffffff,
4462306a36Sopenharmony_ci		.flags	= IORESOURCE_MEM,
4562306a36Sopenharmony_ci	}
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic int __init amiga_init_bus(void)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	struct platform_device *pdev;
5262306a36Sopenharmony_ci	unsigned int n;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
5562306a36Sopenharmony_ci		return -ENODEV;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
5862306a36Sopenharmony_ci	pdev = platform_device_register_simple("amiga-zorro", -1,
5962306a36Sopenharmony_ci					       zorro_resources, n);
6062306a36Sopenharmony_ci	return PTR_ERR_OR_ZERO(pdev);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cisubsys_initcall(amiga_init_bus);
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic int __init z_dev_present(zorro_id id)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	unsigned int i;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	for (i = 0; i < zorro_num_autocon; i++) {
7162306a36Sopenharmony_ci		const struct ExpansionRom *rom = &zorro_autocon_init[i].rom;
7262306a36Sopenharmony_ci		if (be16_to_cpu(rom->er_Manufacturer) == ZORRO_MANUF(id) &&
7362306a36Sopenharmony_ci		    rom->er_Product == ZORRO_PROD(id))
7462306a36Sopenharmony_ci			return 1;
7562306a36Sopenharmony_ci	}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	return 0;
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#else /* !CONFIG_ZORRO */
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic inline int z_dev_present(zorro_id id) { return 0; }
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#endif /* !CONFIG_ZORRO */
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic const struct resource a3000_scsi_resource __initconst = {
8862306a36Sopenharmony_ci	.start	= 0xdd0000,
8962306a36Sopenharmony_ci	.end	= 0xdd00ff,
9062306a36Sopenharmony_ci	.flags	= IORESOURCE_MEM,
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistatic const struct resource a4000t_scsi_resource __initconst = {
9562306a36Sopenharmony_ci	.start	= 0xdd0000,
9662306a36Sopenharmony_ci	.end	= 0xdd0fff,
9762306a36Sopenharmony_ci	.flags	= IORESOURCE_MEM,
9862306a36Sopenharmony_ci};
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistatic const struct resource a1200_ide_resource __initconst = {
10262306a36Sopenharmony_ci	.start	= 0xda0000,
10362306a36Sopenharmony_ci	.end	= 0xda1fff,
10462306a36Sopenharmony_ci	.flags	= IORESOURCE_MEM,
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic const struct gayle_ide_platform_data a1200_ide_pdata __initconst = {
10862306a36Sopenharmony_ci	.base		= 0xda0000,
10962306a36Sopenharmony_ci	.irqport	= 0xda9000,
11062306a36Sopenharmony_ci	.explicit_ack	= 1,
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic const struct resource a4000_ide_resource __initconst = {
11562306a36Sopenharmony_ci	.start	= 0xdd2000,
11662306a36Sopenharmony_ci	.end	= 0xdd3fff,
11762306a36Sopenharmony_ci	.flags	= IORESOURCE_MEM,
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic const struct gayle_ide_platform_data a4000_ide_pdata __initconst = {
12162306a36Sopenharmony_ci	.base		= 0xdd2020,
12262306a36Sopenharmony_ci	.irqport	= 0xdd3020,
12362306a36Sopenharmony_ci	.explicit_ack	= 0,
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistatic const struct resource amiga_rtc_resource __initconst = {
12862306a36Sopenharmony_ci	.start	= 0x00dc0000,
12962306a36Sopenharmony_ci	.end	= 0x00dcffff,
13062306a36Sopenharmony_ci	.flags	= IORESOURCE_MEM,
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic int __init amiga_init_devices(void)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	struct platform_device *pdev;
13762306a36Sopenharmony_ci	int error;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	if (!MACH_IS_AMIGA)
14062306a36Sopenharmony_ci		return -ENODEV;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	/* video hardware */
14362306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_VIDEO)) {
14462306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-video", -1, NULL,
14562306a36Sopenharmony_ci						       0);
14662306a36Sopenharmony_ci		if (IS_ERR(pdev))
14762306a36Sopenharmony_ci			return PTR_ERR(pdev);
14862306a36Sopenharmony_ci	}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	/* sound hardware */
15262306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_AUDIO)) {
15362306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-audio", -1, NULL,
15462306a36Sopenharmony_ci						       0);
15562306a36Sopenharmony_ci		if (IS_ERR(pdev))
15662306a36Sopenharmony_ci			return PTR_ERR(pdev);
15762306a36Sopenharmony_ci	}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	/* storage interfaces */
16162306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_FLOPPY)) {
16262306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-floppy", -1,
16362306a36Sopenharmony_ci						       NULL, 0);
16462306a36Sopenharmony_ci		if (IS_ERR(pdev))
16562306a36Sopenharmony_ci			return PTR_ERR(pdev);
16662306a36Sopenharmony_ci	}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(A3000_SCSI)) {
16962306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-a3000-scsi", -1,
17062306a36Sopenharmony_ci						       &a3000_scsi_resource, 1);
17162306a36Sopenharmony_ci		if (IS_ERR(pdev))
17262306a36Sopenharmony_ci			return PTR_ERR(pdev);
17362306a36Sopenharmony_ci	}
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(A4000_SCSI)) {
17662306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-a4000t-scsi", -1,
17762306a36Sopenharmony_ci						       &a4000t_scsi_resource,
17862306a36Sopenharmony_ci						       1);
17962306a36Sopenharmony_ci		if (IS_ERR(pdev))
18062306a36Sopenharmony_ci			return PTR_ERR(pdev);
18162306a36Sopenharmony_ci	}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(A1200_IDE) ||
18462306a36Sopenharmony_ci	    z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) {
18562306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-gayle-ide", -1,
18662306a36Sopenharmony_ci						       &a1200_ide_resource, 1);
18762306a36Sopenharmony_ci		if (IS_ERR(pdev))
18862306a36Sopenharmony_ci			return PTR_ERR(pdev);
18962306a36Sopenharmony_ci		error = platform_device_add_data(pdev, &a1200_ide_pdata,
19062306a36Sopenharmony_ci						 sizeof(a1200_ide_pdata));
19162306a36Sopenharmony_ci		if (error)
19262306a36Sopenharmony_ci			return error;
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(A4000_IDE)) {
19662306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-gayle-ide", -1,
19762306a36Sopenharmony_ci						       &a4000_ide_resource, 1);
19862306a36Sopenharmony_ci		if (IS_ERR(pdev))
19962306a36Sopenharmony_ci			return PTR_ERR(pdev);
20062306a36Sopenharmony_ci		error = platform_device_add_data(pdev, &a4000_ide_pdata,
20162306a36Sopenharmony_ci						 sizeof(a4000_ide_pdata));
20262306a36Sopenharmony_ci		if (error)
20362306a36Sopenharmony_ci			return error;
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	/* other I/O hardware */
20862306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_KEYBOARD)) {
20962306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-keyboard", -1,
21062306a36Sopenharmony_ci						       NULL, 0);
21162306a36Sopenharmony_ci		if (IS_ERR(pdev))
21262306a36Sopenharmony_ci			return PTR_ERR(pdev);
21362306a36Sopenharmony_ci	}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_MOUSE)) {
21662306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-mouse", -1, NULL,
21762306a36Sopenharmony_ci						       0);
21862306a36Sopenharmony_ci		if (IS_ERR(pdev))
21962306a36Sopenharmony_ci			return PTR_ERR(pdev);
22062306a36Sopenharmony_ci	}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_SERIAL)) {
22362306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-serial", -1,
22462306a36Sopenharmony_ci						       NULL, 0);
22562306a36Sopenharmony_ci		if (IS_ERR(pdev))
22662306a36Sopenharmony_ci			return PTR_ERR(pdev);
22762306a36Sopenharmony_ci	}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_PARALLEL)) {
23062306a36Sopenharmony_ci		pdev = platform_device_register_simple("amiga-parallel", -1,
23162306a36Sopenharmony_ci						       NULL, 0);
23262306a36Sopenharmony_ci		if (IS_ERR(pdev))
23362306a36Sopenharmony_ci			return PTR_ERR(pdev);
23462306a36Sopenharmony_ci	}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	/* real time clocks */
23862306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(A2000_CLK)) {
23962306a36Sopenharmony_ci		pdev = platform_device_register_simple("rtc-msm6242", -1,
24062306a36Sopenharmony_ci						       &amiga_rtc_resource, 1);
24162306a36Sopenharmony_ci		if (IS_ERR(pdev))
24262306a36Sopenharmony_ci			return PTR_ERR(pdev);
24362306a36Sopenharmony_ci	}
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	if (AMIGAHW_PRESENT(A3000_CLK)) {
24662306a36Sopenharmony_ci		pdev = platform_device_register_simple("rtc-rp5c01", -1,
24762306a36Sopenharmony_ci						       &amiga_rtc_resource, 1);
24862306a36Sopenharmony_ci		if (IS_ERR(pdev))
24962306a36Sopenharmony_ci			return PTR_ERR(pdev);
25062306a36Sopenharmony_ci	}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	return 0;
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ciarch_initcall(amiga_init_devices);
256