18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-omap1/board-palmz71.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Modified from board-generic.c
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Support for the Palm Zire71 PDA.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Original version : Laurent Gonzalez
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Modified for zire71 : Marek Vasut
128c2ecf20Sopenharmony_ci */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/delay.h>
158c2ecf20Sopenharmony_ci#include <linux/gpio.h>
168c2ecf20Sopenharmony_ci#include <linux/kernel.h>
178c2ecf20Sopenharmony_ci#include <linux/init.h>
188c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
198c2ecf20Sopenharmony_ci#include <linux/notifier.h>
208c2ecf20Sopenharmony_ci#include <linux/clk.h>
218c2ecf20Sopenharmony_ci#include <linux/irq.h>
228c2ecf20Sopenharmony_ci#include <linux/input.h>
238c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
248c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h>
258c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h>
268c2ecf20Sopenharmony_ci#include <linux/mtd/physmap.h>
278c2ecf20Sopenharmony_ci#include <linux/omapfb.h>
288c2ecf20Sopenharmony_ci#include <linux/spi/spi.h>
298c2ecf20Sopenharmony_ci#include <linux/spi/ads7846.h>
308c2ecf20Sopenharmony_ci#include <linux/platform_data/omap1_bl.h>
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#include <asm/mach-types.h>
338c2ecf20Sopenharmony_ci#include <asm/mach/arch.h>
348c2ecf20Sopenharmony_ci#include <asm/mach/map.h>
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#include "flash.h"
378c2ecf20Sopenharmony_ci#include <mach/mux.h>
388c2ecf20Sopenharmony_ci#include <linux/omap-dma.h>
398c2ecf20Sopenharmony_ci#include <mach/tc.h>
408c2ecf20Sopenharmony_ci#include <linux/platform_data/keypad-omap.h>
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#include <mach/hardware.h>
438c2ecf20Sopenharmony_ci#include <mach/usb.h>
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#include "common.h"
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define PALMZ71_USBDETECT_GPIO	0
488c2ecf20Sopenharmony_ci#define PALMZ71_PENIRQ_GPIO	6
498c2ecf20Sopenharmony_ci#define PALMZ71_MMC_WP_GPIO	8
508c2ecf20Sopenharmony_ci#define PALMZ71_HDQ_GPIO 	11
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci#define PALMZ71_HOTSYNC_GPIO	OMAP_MPUIO(1)
538c2ecf20Sopenharmony_ci#define PALMZ71_CABLE_GPIO	OMAP_MPUIO(2)
548c2ecf20Sopenharmony_ci#define PALMZ71_SLIDER_GPIO	OMAP_MPUIO(3)
558c2ecf20Sopenharmony_ci#define PALMZ71_MMC_IN_GPIO	OMAP_MPUIO(4)
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic const unsigned int palmz71_keymap[] = {
588c2ecf20Sopenharmony_ci	KEY(0, 0, KEY_F1),
598c2ecf20Sopenharmony_ci	KEY(1, 0, KEY_F2),
608c2ecf20Sopenharmony_ci	KEY(2, 0, KEY_F3),
618c2ecf20Sopenharmony_ci	KEY(3, 0, KEY_F4),
628c2ecf20Sopenharmony_ci	KEY(4, 0, KEY_POWER),
638c2ecf20Sopenharmony_ci	KEY(0, 1, KEY_LEFT),
648c2ecf20Sopenharmony_ci	KEY(1, 1, KEY_DOWN),
658c2ecf20Sopenharmony_ci	KEY(2, 1, KEY_UP),
668c2ecf20Sopenharmony_ci	KEY(3, 1, KEY_RIGHT),
678c2ecf20Sopenharmony_ci	KEY(4, 1, KEY_ENTER),
688c2ecf20Sopenharmony_ci	KEY(0, 2, KEY_CAMERA),
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic const struct matrix_keymap_data palmz71_keymap_data = {
728c2ecf20Sopenharmony_ci	.keymap		= palmz71_keymap,
738c2ecf20Sopenharmony_ci	.keymap_size	= ARRAY_SIZE(palmz71_keymap),
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic struct omap_kp_platform_data palmz71_kp_data = {
778c2ecf20Sopenharmony_ci	.rows	= 8,
788c2ecf20Sopenharmony_ci	.cols	= 8,
798c2ecf20Sopenharmony_ci	.keymap_data	= &palmz71_keymap_data,
808c2ecf20Sopenharmony_ci	.rep	= true,
818c2ecf20Sopenharmony_ci	.delay	= 80,
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic struct resource palmz71_kp_resources[] = {
858c2ecf20Sopenharmony_ci	[0] = {
868c2ecf20Sopenharmony_ci		.start	= INT_KEYBOARD,
878c2ecf20Sopenharmony_ci		.end	= INT_KEYBOARD,
888c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
898c2ecf20Sopenharmony_ci	},
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic struct platform_device palmz71_kp_device = {
938c2ecf20Sopenharmony_ci	.name	= "omap-keypad",
948c2ecf20Sopenharmony_ci	.id	= -1,
958c2ecf20Sopenharmony_ci	.dev	= {
968c2ecf20Sopenharmony_ci		.platform_data = &palmz71_kp_data,
978c2ecf20Sopenharmony_ci	},
988c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(palmz71_kp_resources),
998c2ecf20Sopenharmony_ci	.resource	= palmz71_kp_resources,
1008c2ecf20Sopenharmony_ci};
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic struct mtd_partition palmz71_rom_partitions[] = {
1038c2ecf20Sopenharmony_ci	/* PalmOS "Small ROM", contains the bootloader and the debugger */
1048c2ecf20Sopenharmony_ci	{
1058c2ecf20Sopenharmony_ci		.name		= "smallrom",
1068c2ecf20Sopenharmony_ci		.offset		= 0,
1078c2ecf20Sopenharmony_ci		.size		= 0xa000,
1088c2ecf20Sopenharmony_ci		.mask_flags	= MTD_WRITEABLE,
1098c2ecf20Sopenharmony_ci	},
1108c2ecf20Sopenharmony_ci	/* PalmOS "Big ROM", a filesystem with all the OS code and data */
1118c2ecf20Sopenharmony_ci	{
1128c2ecf20Sopenharmony_ci		.name	= "bigrom",
1138c2ecf20Sopenharmony_ci		.offset	= SZ_128K,
1148c2ecf20Sopenharmony_ci		/*
1158c2ecf20Sopenharmony_ci		 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
1168c2ecf20Sopenharmony_ci		 * 0x7b0000 bytes in the English-only ("enUS") version.
1178c2ecf20Sopenharmony_ci		 */
1188c2ecf20Sopenharmony_ci		.size		= 0x7b0000,
1198c2ecf20Sopenharmony_ci		.mask_flags	= MTD_WRITEABLE,
1208c2ecf20Sopenharmony_ci	},
1218c2ecf20Sopenharmony_ci};
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic struct physmap_flash_data palmz71_rom_data = {
1248c2ecf20Sopenharmony_ci	.width		= 2,
1258c2ecf20Sopenharmony_ci	.set_vpp	= omap1_set_vpp,
1268c2ecf20Sopenharmony_ci	.parts		= palmz71_rom_partitions,
1278c2ecf20Sopenharmony_ci	.nr_parts	= ARRAY_SIZE(palmz71_rom_partitions),
1288c2ecf20Sopenharmony_ci};
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic struct resource palmz71_rom_resource = {
1318c2ecf20Sopenharmony_ci	.start	= OMAP_CS0_PHYS,
1328c2ecf20Sopenharmony_ci	.end	= OMAP_CS0_PHYS + SZ_8M - 1,
1338c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
1348c2ecf20Sopenharmony_ci};
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic struct platform_device palmz71_rom_device = {
1378c2ecf20Sopenharmony_ci	.name	= "physmap-flash",
1388c2ecf20Sopenharmony_ci	.id	= -1,
1398c2ecf20Sopenharmony_ci	.dev = {
1408c2ecf20Sopenharmony_ci		.platform_data = &palmz71_rom_data,
1418c2ecf20Sopenharmony_ci	},
1428c2ecf20Sopenharmony_ci	.num_resources	= 1,
1438c2ecf20Sopenharmony_ci	.resource	= &palmz71_rom_resource,
1448c2ecf20Sopenharmony_ci};
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cistatic struct platform_device palmz71_lcd_device = {
1478c2ecf20Sopenharmony_ci	.name	= "lcd_palmz71",
1488c2ecf20Sopenharmony_ci	.id	= -1,
1498c2ecf20Sopenharmony_ci};
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic struct platform_device palmz71_spi_device = {
1528c2ecf20Sopenharmony_ci	.name	= "spi_palmz71",
1538c2ecf20Sopenharmony_ci	.id	= -1,
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic struct omap_backlight_config palmz71_backlight_config = {
1578c2ecf20Sopenharmony_ci	.default_intensity	= 0xa0,
1588c2ecf20Sopenharmony_ci};
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistatic struct platform_device palmz71_backlight_device = {
1618c2ecf20Sopenharmony_ci	.name	= "omap-bl",
1628c2ecf20Sopenharmony_ci	.id	= -1,
1638c2ecf20Sopenharmony_ci	.dev	= {
1648c2ecf20Sopenharmony_ci		.platform_data = &palmz71_backlight_config,
1658c2ecf20Sopenharmony_ci	},
1668c2ecf20Sopenharmony_ci};
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic struct platform_device *devices[] __initdata = {
1698c2ecf20Sopenharmony_ci	&palmz71_rom_device,
1708c2ecf20Sopenharmony_ci	&palmz71_kp_device,
1718c2ecf20Sopenharmony_ci	&palmz71_lcd_device,
1728c2ecf20Sopenharmony_ci	&palmz71_spi_device,
1738c2ecf20Sopenharmony_ci	&palmz71_backlight_device,
1748c2ecf20Sopenharmony_ci};
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic int
1778c2ecf20Sopenharmony_cipalmz71_get_pendown_state(void)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	return !gpio_get_value(PALMZ71_PENIRQ_GPIO);
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic const struct ads7846_platform_data palmz71_ts_info = {
1838c2ecf20Sopenharmony_ci	.model			= 7846,
1848c2ecf20Sopenharmony_ci	.vref_delay_usecs	= 100,	/* internal, no capacitor */
1858c2ecf20Sopenharmony_ci	.x_plate_ohms		= 419,
1868c2ecf20Sopenharmony_ci	.y_plate_ohms		= 486,
1878c2ecf20Sopenharmony_ci	.get_pendown_state	= palmz71_get_pendown_state,
1888c2ecf20Sopenharmony_ci};
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic struct spi_board_info __initdata palmz71_boardinfo[] = { {
1918c2ecf20Sopenharmony_ci	/* MicroWire (bus 2) CS0 has an ads7846e */
1928c2ecf20Sopenharmony_ci	.modalias	= "ads7846",
1938c2ecf20Sopenharmony_ci	.platform_data	= &palmz71_ts_info,
1948c2ecf20Sopenharmony_ci	.max_speed_hz	= 120000	/* max sample rate at 3V */
1958c2ecf20Sopenharmony_ci				* 26	/* command + data + overhead */,
1968c2ecf20Sopenharmony_ci	.bus_num	= 2,
1978c2ecf20Sopenharmony_ci	.chip_select	= 0,
1988c2ecf20Sopenharmony_ci} };
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistatic struct omap_usb_config palmz71_usb_config __initdata = {
2018c2ecf20Sopenharmony_ci	.register_dev	= 1,	/* Mini-B only receptacle */
2028c2ecf20Sopenharmony_ci	.hmc_mode	= 0,
2038c2ecf20Sopenharmony_ci	.pins[0]	= 2,
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistatic const struct omap_lcd_config palmz71_lcd_config __initconst = {
2078c2ecf20Sopenharmony_ci	.ctrl_name = "internal",
2088c2ecf20Sopenharmony_ci};
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic irqreturn_t
2118c2ecf20Sopenharmony_cipalmz71_powercable(int irq, void *dev_id)
2128c2ecf20Sopenharmony_ci{
2138c2ecf20Sopenharmony_ci	if (gpio_get_value(PALMZ71_USBDETECT_GPIO)) {
2148c2ecf20Sopenharmony_ci		printk(KERN_INFO "PM: Power cable connected\n");
2158c2ecf20Sopenharmony_ci		irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
2168c2ecf20Sopenharmony_ci				 IRQ_TYPE_EDGE_FALLING);
2178c2ecf20Sopenharmony_ci	} else {
2188c2ecf20Sopenharmony_ci		printk(KERN_INFO "PM: Power cable disconnected\n");
2198c2ecf20Sopenharmony_ci		irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
2208c2ecf20Sopenharmony_ci				 IRQ_TYPE_EDGE_RISING);
2218c2ecf20Sopenharmony_ci	}
2228c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistatic void __init
2268c2ecf20Sopenharmony_ciomap_mpu_wdt_mode(int mode)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	if (mode)
2298c2ecf20Sopenharmony_ci		omap_writew(0x8000, OMAP_WDT_TIMER_MODE);
2308c2ecf20Sopenharmony_ci	else {
2318c2ecf20Sopenharmony_ci		omap_writew(0x00f5, OMAP_WDT_TIMER_MODE);
2328c2ecf20Sopenharmony_ci		omap_writew(0x00a0, OMAP_WDT_TIMER_MODE);
2338c2ecf20Sopenharmony_ci	}
2348c2ecf20Sopenharmony_ci}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_cistatic void __init
2378c2ecf20Sopenharmony_cipalmz71_gpio_setup(int early)
2388c2ecf20Sopenharmony_ci{
2398c2ecf20Sopenharmony_ci	if (early) {
2408c2ecf20Sopenharmony_ci		/* Only set GPIO1 so we have a working serial */
2418c2ecf20Sopenharmony_ci		gpio_direction_output(1, 1);
2428c2ecf20Sopenharmony_ci	} else {
2438c2ecf20Sopenharmony_ci		/* Set MMC/SD host WP pin as input */
2448c2ecf20Sopenharmony_ci		if (gpio_request(PALMZ71_MMC_WP_GPIO, "MMC WP") < 0) {
2458c2ecf20Sopenharmony_ci			printk(KERN_ERR "Could not reserve WP GPIO!\n");
2468c2ecf20Sopenharmony_ci			return;
2478c2ecf20Sopenharmony_ci		}
2488c2ecf20Sopenharmony_ci		gpio_direction_input(PALMZ71_MMC_WP_GPIO);
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci		/* Monitor the Power-cable-connected signal */
2518c2ecf20Sopenharmony_ci		if (gpio_request(PALMZ71_USBDETECT_GPIO, "USB detect") < 0) {
2528c2ecf20Sopenharmony_ci			printk(KERN_ERR
2538c2ecf20Sopenharmony_ci				"Could not reserve cable signal GPIO!\n");
2548c2ecf20Sopenharmony_ci			return;
2558c2ecf20Sopenharmony_ci		}
2568c2ecf20Sopenharmony_ci		gpio_direction_input(PALMZ71_USBDETECT_GPIO);
2578c2ecf20Sopenharmony_ci		if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
2588c2ecf20Sopenharmony_ci				palmz71_powercable, 0, "palmz71-cable", NULL))
2598c2ecf20Sopenharmony_ci			printk(KERN_ERR
2608c2ecf20Sopenharmony_ci					"IRQ request for power cable failed!\n");
2618c2ecf20Sopenharmony_ci		palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL);
2628c2ecf20Sopenharmony_ci	}
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_cistatic void __init
2668c2ecf20Sopenharmony_ciomap_palmz71_init(void)
2678c2ecf20Sopenharmony_ci{
2688c2ecf20Sopenharmony_ci	/* mux pins for uarts */
2698c2ecf20Sopenharmony_ci	omap_cfg_reg(UART1_TX);
2708c2ecf20Sopenharmony_ci	omap_cfg_reg(UART1_RTS);
2718c2ecf20Sopenharmony_ci	omap_cfg_reg(UART2_TX);
2728c2ecf20Sopenharmony_ci	omap_cfg_reg(UART2_RTS);
2738c2ecf20Sopenharmony_ci	omap_cfg_reg(UART3_TX);
2748c2ecf20Sopenharmony_ci	omap_cfg_reg(UART3_RX);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	palmz71_gpio_setup(1);
2778c2ecf20Sopenharmony_ci	omap_mpu_wdt_mode(0);
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	platform_add_devices(devices, ARRAY_SIZE(devices));
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	palmz71_boardinfo[0].irq = gpio_to_irq(PALMZ71_PENIRQ_GPIO);
2828c2ecf20Sopenharmony_ci	spi_register_board_info(palmz71_boardinfo,
2838c2ecf20Sopenharmony_ci				ARRAY_SIZE(palmz71_boardinfo));
2848c2ecf20Sopenharmony_ci	omap1_usb_init(&palmz71_usb_config);
2858c2ecf20Sopenharmony_ci	omap_serial_init();
2868c2ecf20Sopenharmony_ci	omap_register_i2c_bus(1, 100, NULL, 0);
2878c2ecf20Sopenharmony_ci	palmz71_gpio_setup(0);
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci	omapfb_set_lcd_config(&palmz71_lcd_config);
2908c2ecf20Sopenharmony_ci}
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ciMACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
2938c2ecf20Sopenharmony_ci	.atag_offset	= 0x100,
2948c2ecf20Sopenharmony_ci	.map_io		= omap15xx_map_io,
2958c2ecf20Sopenharmony_ci	.init_early     = omap1_init_early,
2968c2ecf20Sopenharmony_ci	.init_irq	= omap1_init_irq,
2978c2ecf20Sopenharmony_ci	.handle_irq	= omap1_handle_irq,
2988c2ecf20Sopenharmony_ci	.init_machine	= omap_palmz71_init,
2998c2ecf20Sopenharmony_ci	.init_late	= omap1_init_late,
3008c2ecf20Sopenharmony_ci	.init_time	= omap1_timer_init,
3018c2ecf20Sopenharmony_ci	.restart	= omap1_restart,
3028c2ecf20Sopenharmony_ciMACHINE_END
303