18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  Copyright (C) 2007-2009 Geert Uytterhoeven
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
58c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
68c2ecf20Sopenharmony_ci * for more details.
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/err.h>
108c2ecf20Sopenharmony_ci#include <linux/init.h>
118c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
128c2ecf20Sopenharmony_ci#include <linux/zorro.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <asm/amigahw.h>
158c2ecf20Sopenharmony_ci#include <asm/amigayle.h>
168c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#ifdef CONFIG_ZORRO
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic const struct resource zorro_resources[] __initconst = {
228c2ecf20Sopenharmony_ci	/* Zorro II regions (on Zorro II/III) */
238c2ecf20Sopenharmony_ci	{
248c2ecf20Sopenharmony_ci		.name	= "Zorro II exp",
258c2ecf20Sopenharmony_ci		.start	= 0x00e80000,
268c2ecf20Sopenharmony_ci		.end	= 0x00efffff,
278c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
288c2ecf20Sopenharmony_ci	}, {
298c2ecf20Sopenharmony_ci		.name	= "Zorro II mem",
308c2ecf20Sopenharmony_ci		.start	= 0x00200000,
318c2ecf20Sopenharmony_ci		.end	= 0x009fffff,
328c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
338c2ecf20Sopenharmony_ci	},
348c2ecf20Sopenharmony_ci	/* Zorro III regions (on Zorro III only) */
358c2ecf20Sopenharmony_ci	{
368c2ecf20Sopenharmony_ci		.name	= "Zorro III exp",
378c2ecf20Sopenharmony_ci		.start	= 0xff000000,
388c2ecf20Sopenharmony_ci		.end	= 0xffffffff,
398c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
408c2ecf20Sopenharmony_ci	}, {
418c2ecf20Sopenharmony_ci		.name	= "Zorro III cfg",
428c2ecf20Sopenharmony_ci		.start	= 0x40000000,
438c2ecf20Sopenharmony_ci		.end	= 0x7fffffff,
448c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
458c2ecf20Sopenharmony_ci	}
468c2ecf20Sopenharmony_ci};
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic int __init amiga_init_bus(void)
508c2ecf20Sopenharmony_ci{
518c2ecf20Sopenharmony_ci	struct platform_device *pdev;
528c2ecf20Sopenharmony_ci	unsigned int n;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
558c2ecf20Sopenharmony_ci		return -ENODEV;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	n = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
588c2ecf20Sopenharmony_ci	pdev = platform_device_register_simple("amiga-zorro", -1,
598c2ecf20Sopenharmony_ci					       zorro_resources, n);
608c2ecf20Sopenharmony_ci	return PTR_ERR_OR_ZERO(pdev);
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cisubsys_initcall(amiga_init_bus);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic int __init z_dev_present(zorro_id id)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	unsigned int i;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	for (i = 0; i < zorro_num_autocon; i++) {
718c2ecf20Sopenharmony_ci		const struct ExpansionRom *rom = &zorro_autocon_init[i].rom;
728c2ecf20Sopenharmony_ci		if (be16_to_cpu(rom->er_Manufacturer) == ZORRO_MANUF(id) &&
738c2ecf20Sopenharmony_ci		    rom->er_Product == ZORRO_PROD(id))
748c2ecf20Sopenharmony_ci			return 1;
758c2ecf20Sopenharmony_ci	}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	return 0;
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci#else /* !CONFIG_ZORRO */
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistatic inline int z_dev_present(zorro_id id) { return 0; }
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#endif /* !CONFIG_ZORRO */
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic const struct resource a3000_scsi_resource __initconst = {
888c2ecf20Sopenharmony_ci	.start	= 0xdd0000,
898c2ecf20Sopenharmony_ci	.end	= 0xdd00ff,
908c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
918c2ecf20Sopenharmony_ci};
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic const struct resource a4000t_scsi_resource __initconst = {
958c2ecf20Sopenharmony_ci	.start	= 0xdd0000,
968c2ecf20Sopenharmony_ci	.end	= 0xdd0fff,
978c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic const struct resource a1200_ide_resource __initconst = {
1028c2ecf20Sopenharmony_ci	.start	= 0xda0000,
1038c2ecf20Sopenharmony_ci	.end	= 0xda1fff,
1048c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
1058c2ecf20Sopenharmony_ci};
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistatic const struct gayle_ide_platform_data a1200_ide_pdata __initconst = {
1088c2ecf20Sopenharmony_ci	.base		= 0xda0000,
1098c2ecf20Sopenharmony_ci	.irqport	= 0xda9000,
1108c2ecf20Sopenharmony_ci	.explicit_ack	= 1,
1118c2ecf20Sopenharmony_ci};
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistatic const struct resource a4000_ide_resource __initconst = {
1158c2ecf20Sopenharmony_ci	.start	= 0xdd2000,
1168c2ecf20Sopenharmony_ci	.end	= 0xdd3fff,
1178c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
1188c2ecf20Sopenharmony_ci};
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistatic const struct gayle_ide_platform_data a4000_ide_pdata __initconst = {
1218c2ecf20Sopenharmony_ci	.base		= 0xdd2020,
1228c2ecf20Sopenharmony_ci	.irqport	= 0xdd3020,
1238c2ecf20Sopenharmony_ci	.explicit_ack	= 0,
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_cistatic const struct resource amiga_rtc_resource __initconst = {
1288c2ecf20Sopenharmony_ci	.start	= 0x00dc0000,
1298c2ecf20Sopenharmony_ci	.end	= 0x00dcffff,
1308c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cistatic int __init amiga_init_devices(void)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	struct platform_device *pdev;
1378c2ecf20Sopenharmony_ci	int error;
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	if (!MACH_IS_AMIGA)
1408c2ecf20Sopenharmony_ci		return -ENODEV;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	/* video hardware */
1438c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_VIDEO)) {
1448c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-video", -1, NULL,
1458c2ecf20Sopenharmony_ci						       0);
1468c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1478c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
1488c2ecf20Sopenharmony_ci	}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	/* sound hardware */
1528c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_AUDIO)) {
1538c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-audio", -1, NULL,
1548c2ecf20Sopenharmony_ci						       0);
1558c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1568c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
1578c2ecf20Sopenharmony_ci	}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	/* storage interfaces */
1618c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_FLOPPY)) {
1628c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-floppy", -1,
1638c2ecf20Sopenharmony_ci						       NULL, 0);
1648c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1658c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
1668c2ecf20Sopenharmony_ci	}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(A3000_SCSI)) {
1698c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-a3000-scsi", -1,
1708c2ecf20Sopenharmony_ci						       &a3000_scsi_resource, 1);
1718c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1728c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
1738c2ecf20Sopenharmony_ci	}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(A4000_SCSI)) {
1768c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-a4000t-scsi", -1,
1778c2ecf20Sopenharmony_ci						       &a4000t_scsi_resource,
1788c2ecf20Sopenharmony_ci						       1);
1798c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1808c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
1818c2ecf20Sopenharmony_ci	}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(A1200_IDE) ||
1848c2ecf20Sopenharmony_ci	    z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) {
1858c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-gayle-ide", -1,
1868c2ecf20Sopenharmony_ci						       &a1200_ide_resource, 1);
1878c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1888c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
1898c2ecf20Sopenharmony_ci		error = platform_device_add_data(pdev, &a1200_ide_pdata,
1908c2ecf20Sopenharmony_ci						 sizeof(a1200_ide_pdata));
1918c2ecf20Sopenharmony_ci		if (error)
1928c2ecf20Sopenharmony_ci			return error;
1938c2ecf20Sopenharmony_ci	}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(A4000_IDE)) {
1968c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-gayle-ide", -1,
1978c2ecf20Sopenharmony_ci						       &a4000_ide_resource, 1);
1988c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
1998c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2008c2ecf20Sopenharmony_ci		error = platform_device_add_data(pdev, &a4000_ide_pdata,
2018c2ecf20Sopenharmony_ci						 sizeof(a4000_ide_pdata));
2028c2ecf20Sopenharmony_ci		if (error)
2038c2ecf20Sopenharmony_ci			return error;
2048c2ecf20Sopenharmony_ci	}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	/* other I/O hardware */
2088c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_KEYBOARD)) {
2098c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-keyboard", -1,
2108c2ecf20Sopenharmony_ci						       NULL, 0);
2118c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
2128c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2138c2ecf20Sopenharmony_ci	}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_MOUSE)) {
2168c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-mouse", -1, NULL,
2178c2ecf20Sopenharmony_ci						       0);
2188c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
2198c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2208c2ecf20Sopenharmony_ci	}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_SERIAL)) {
2238c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-serial", -1,
2248c2ecf20Sopenharmony_ci						       NULL, 0);
2258c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
2268c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2278c2ecf20Sopenharmony_ci	}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(AMI_PARALLEL)) {
2308c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("amiga-parallel", -1,
2318c2ecf20Sopenharmony_ci						       NULL, 0);
2328c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
2338c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2348c2ecf20Sopenharmony_ci	}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	/* real time clocks */
2388c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(A2000_CLK)) {
2398c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("rtc-msm6242", -1,
2408c2ecf20Sopenharmony_ci						       &amiga_rtc_resource, 1);
2418c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
2428c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2438c2ecf20Sopenharmony_ci	}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	if (AMIGAHW_PRESENT(A3000_CLK)) {
2468c2ecf20Sopenharmony_ci		pdev = platform_device_register_simple("rtc-rp5c01", -1,
2478c2ecf20Sopenharmony_ci						       &amiga_rtc_resource, 1);
2488c2ecf20Sopenharmony_ci		if (IS_ERR(pdev))
2498c2ecf20Sopenharmony_ci			return PTR_ERR(pdev);
2508c2ecf20Sopenharmony_ci	}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	return 0;
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ciarch_initcall(amiga_init_devices);
256