18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-omap1/board-nokia770.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Modified from board-generic.c 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <linux/clkdev.h> 88c2ecf20Sopenharmony_ci#include <linux/irq.h> 98c2ecf20Sopenharmony_ci#include <linux/gpio.h> 108c2ecf20Sopenharmony_ci#include <linux/gpio/machine.h> 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/mutex.h> 148c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 158c2ecf20Sopenharmony_ci#include <linux/input.h> 168c2ecf20Sopenharmony_ci#include <linux/omapfb.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 198c2ecf20Sopenharmony_ci#include <linux/spi/ads7846.h> 208c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 218c2ecf20Sopenharmony_ci#include <linux/delay.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <linux/platform_data/keypad-omap.h> 248c2ecf20Sopenharmony_ci#include <linux/platform_data/lcd-mipid.h> 258c2ecf20Sopenharmony_ci#include <linux/platform_data/gpio-omap.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 288c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 298c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include <mach/mux.h> 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#include <mach/hardware.h> 348c2ecf20Sopenharmony_ci#include <mach/usb.h> 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#include "common.h" 378c2ecf20Sopenharmony_ci#include "clock.h" 388c2ecf20Sopenharmony_ci#include "mmc.h" 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define ADS7846_PENDOWN_GPIO 15 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic const unsigned int nokia770_keymap[] = { 438c2ecf20Sopenharmony_ci KEY(1, 0, GROUP_0 | KEY_UP), 448c2ecf20Sopenharmony_ci KEY(2, 0, GROUP_1 | KEY_F5), 458c2ecf20Sopenharmony_ci KEY(0, 1, GROUP_0 | KEY_LEFT), 468c2ecf20Sopenharmony_ci KEY(1, 1, GROUP_0 | KEY_ENTER), 478c2ecf20Sopenharmony_ci KEY(2, 1, GROUP_0 | KEY_RIGHT), 488c2ecf20Sopenharmony_ci KEY(0, 2, GROUP_1 | KEY_ESC), 498c2ecf20Sopenharmony_ci KEY(1, 2, GROUP_0 | KEY_DOWN), 508c2ecf20Sopenharmony_ci KEY(2, 2, GROUP_1 | KEY_F4), 518c2ecf20Sopenharmony_ci KEY(0, 3, GROUP_2 | KEY_F7), 528c2ecf20Sopenharmony_ci KEY(1, 3, GROUP_2 | KEY_F8), 538c2ecf20Sopenharmony_ci KEY(2, 3, GROUP_2 | KEY_F6), 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic struct resource nokia770_kp_resources[] = { 578c2ecf20Sopenharmony_ci [0] = { 588c2ecf20Sopenharmony_ci .start = INT_KEYBOARD, 598c2ecf20Sopenharmony_ci .end = INT_KEYBOARD, 608c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 618c2ecf20Sopenharmony_ci }, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic const struct matrix_keymap_data nokia770_keymap_data = { 658c2ecf20Sopenharmony_ci .keymap = nokia770_keymap, 668c2ecf20Sopenharmony_ci .keymap_size = ARRAY_SIZE(nokia770_keymap), 678c2ecf20Sopenharmony_ci}; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic struct omap_kp_platform_data nokia770_kp_data = { 708c2ecf20Sopenharmony_ci .rows = 8, 718c2ecf20Sopenharmony_ci .cols = 8, 728c2ecf20Sopenharmony_ci .keymap_data = &nokia770_keymap_data, 738c2ecf20Sopenharmony_ci .delay = 4, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic struct platform_device nokia770_kp_device = { 778c2ecf20Sopenharmony_ci .name = "omap-keypad", 788c2ecf20Sopenharmony_ci .id = -1, 798c2ecf20Sopenharmony_ci .dev = { 808c2ecf20Sopenharmony_ci .platform_data = &nokia770_kp_data, 818c2ecf20Sopenharmony_ci }, 828c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(nokia770_kp_resources), 838c2ecf20Sopenharmony_ci .resource = nokia770_kp_resources, 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic struct platform_device *nokia770_devices[] __initdata = { 878c2ecf20Sopenharmony_ci &nokia770_kp_device, 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic void mipid_shutdown(struct mipid_platform_data *pdata) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci if (pdata->nreset_gpio != -1) { 938c2ecf20Sopenharmony_ci printk(KERN_INFO "shutdown LCD\n"); 948c2ecf20Sopenharmony_ci gpio_set_value(pdata->nreset_gpio, 0); 958c2ecf20Sopenharmony_ci msleep(120); 968c2ecf20Sopenharmony_ci } 978c2ecf20Sopenharmony_ci} 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic struct mipid_platform_data nokia770_mipid_platform_data = { 1008c2ecf20Sopenharmony_ci .shutdown = mipid_shutdown, 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic const struct omap_lcd_config nokia770_lcd_config __initconst = { 1048c2ecf20Sopenharmony_ci .ctrl_name = "hwa742", 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic void __init mipid_dev_init(void) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci nokia770_mipid_platform_data.nreset_gpio = 13; 1108c2ecf20Sopenharmony_ci nokia770_mipid_platform_data.data_lines = 16; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci omapfb_set_lcd_config(&nokia770_lcd_config); 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { 1168c2ecf20Sopenharmony_ci .x_max = 0x0fff, 1178c2ecf20Sopenharmony_ci .y_max = 0x0fff, 1188c2ecf20Sopenharmony_ci .x_plate_ohms = 180, 1198c2ecf20Sopenharmony_ci .pressure_max = 255, 1208c2ecf20Sopenharmony_ci .debounce_max = 10, 1218c2ecf20Sopenharmony_ci .debounce_tol = 3, 1228c2ecf20Sopenharmony_ci .debounce_rep = 1, 1238c2ecf20Sopenharmony_ci .gpio_pendown = ADS7846_PENDOWN_GPIO, 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic struct spi_board_info nokia770_spi_board_info[] __initdata = { 1278c2ecf20Sopenharmony_ci [0] = { 1288c2ecf20Sopenharmony_ci .modalias = "lcd_mipid", 1298c2ecf20Sopenharmony_ci .bus_num = 2, 1308c2ecf20Sopenharmony_ci .chip_select = 3, 1318c2ecf20Sopenharmony_ci .max_speed_hz = 12000000, 1328c2ecf20Sopenharmony_ci .platform_data = &nokia770_mipid_platform_data, 1338c2ecf20Sopenharmony_ci }, 1348c2ecf20Sopenharmony_ci [1] = { 1358c2ecf20Sopenharmony_ci .modalias = "ads7846", 1368c2ecf20Sopenharmony_ci .bus_num = 2, 1378c2ecf20Sopenharmony_ci .chip_select = 0, 1388c2ecf20Sopenharmony_ci .max_speed_hz = 2500000, 1398c2ecf20Sopenharmony_ci .platform_data = &nokia770_ads7846_platform_data, 1408c2ecf20Sopenharmony_ci }, 1418c2ecf20Sopenharmony_ci}; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic void __init hwa742_dev_init(void) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* assume no Mini-AB port */ 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic struct omap_usb_config nokia770_usb_config __initdata = { 1518c2ecf20Sopenharmony_ci .otg = 1, 1528c2ecf20Sopenharmony_ci .register_host = 1, 1538c2ecf20Sopenharmony_ci .register_dev = 1, 1548c2ecf20Sopenharmony_ci .hmc_mode = 16, 1558c2ecf20Sopenharmony_ci .pins[0] = 6, 1568c2ecf20Sopenharmony_ci .extcon = "tahvo-usb", 1578c2ecf20Sopenharmony_ci}; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MMC_OMAP) 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci#define NOKIA770_GPIO_MMC_POWER 41 1628c2ecf20Sopenharmony_ci#define NOKIA770_GPIO_MMC_SWITCH 23 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic int nokia770_mmc_set_power(struct device *dev, int slot, int power_on, 1658c2ecf20Sopenharmony_ci int vdd) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on); 1688c2ecf20Sopenharmony_ci return 0; 1698c2ecf20Sopenharmony_ci} 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistatic int nokia770_mmc_get_cover_state(struct device *dev, int slot) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH); 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic struct omap_mmc_platform_data nokia770_mmc2_data = { 1778c2ecf20Sopenharmony_ci .nr_slots = 1, 1788c2ecf20Sopenharmony_ci .max_freq = 12000000, 1798c2ecf20Sopenharmony_ci .slots[0] = { 1808c2ecf20Sopenharmony_ci .set_power = nokia770_mmc_set_power, 1818c2ecf20Sopenharmony_ci .get_cover_state = nokia770_mmc_get_cover_state, 1828c2ecf20Sopenharmony_ci .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 1838c2ecf20Sopenharmony_ci .name = "mmcblk", 1848c2ecf20Sopenharmony_ci }, 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC]; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic void __init nokia770_mmc_init(void) 1908c2ecf20Sopenharmony_ci{ 1918c2ecf20Sopenharmony_ci int ret; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power"); 1948c2ecf20Sopenharmony_ci if (ret < 0) 1958c2ecf20Sopenharmony_ci return; 1968c2ecf20Sopenharmony_ci gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover"); 1998c2ecf20Sopenharmony_ci if (ret < 0) { 2008c2ecf20Sopenharmony_ci gpio_free(NOKIA770_GPIO_MMC_POWER); 2018c2ecf20Sopenharmony_ci return; 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci /* Only the second MMC controller is used */ 2068c2ecf20Sopenharmony_ci nokia770_mmc_data[1] = &nokia770_mmc2_data; 2078c2ecf20Sopenharmony_ci omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC); 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci#else 2118c2ecf20Sopenharmony_cistatic inline void nokia770_mmc_init(void) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci#endif 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_I2C_CBUS_GPIO) 2178c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table nokia770_cbus_gpio_table = { 2188c2ecf20Sopenharmony_ci .dev_id = "i2c-cbus-gpio.2", 2198c2ecf20Sopenharmony_ci .table = { 2208c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX("mpuio", 9, NULL, 0, 0), /* clk */ 2218c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX("mpuio", 10, NULL, 1, 0), /* dat */ 2228c2ecf20Sopenharmony_ci GPIO_LOOKUP_IDX("mpuio", 11, NULL, 2, 0), /* sel */ 2238c2ecf20Sopenharmony_ci { }, 2248c2ecf20Sopenharmony_ci }, 2258c2ecf20Sopenharmony_ci}; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic struct platform_device nokia770_cbus_device = { 2288c2ecf20Sopenharmony_ci .name = "i2c-cbus-gpio", 2298c2ecf20Sopenharmony_ci .id = 2, 2308c2ecf20Sopenharmony_ci}; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = { 2338c2ecf20Sopenharmony_ci { 2348c2ecf20Sopenharmony_ci I2C_BOARD_INFO("retu", 0x01), 2358c2ecf20Sopenharmony_ci }, 2368c2ecf20Sopenharmony_ci { 2378c2ecf20Sopenharmony_ci I2C_BOARD_INFO("tahvo", 0x02), 2388c2ecf20Sopenharmony_ci }, 2398c2ecf20Sopenharmony_ci}; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic void __init nokia770_cbus_init(void) 2428c2ecf20Sopenharmony_ci{ 2438c2ecf20Sopenharmony_ci const int retu_irq_gpio = 62; 2448c2ecf20Sopenharmony_ci const int tahvo_irq_gpio = 40; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci if (gpio_request_one(retu_irq_gpio, GPIOF_IN, "Retu IRQ")) 2478c2ecf20Sopenharmony_ci return; 2488c2ecf20Sopenharmony_ci if (gpio_request_one(tahvo_irq_gpio, GPIOF_IN, "Tahvo IRQ")) { 2498c2ecf20Sopenharmony_ci gpio_free(retu_irq_gpio); 2508c2ecf20Sopenharmony_ci return; 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci irq_set_irq_type(gpio_to_irq(retu_irq_gpio), IRQ_TYPE_EDGE_RISING); 2538c2ecf20Sopenharmony_ci irq_set_irq_type(gpio_to_irq(tahvo_irq_gpio), IRQ_TYPE_EDGE_RISING); 2548c2ecf20Sopenharmony_ci nokia770_i2c_board_info_2[0].irq = gpio_to_irq(retu_irq_gpio); 2558c2ecf20Sopenharmony_ci nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio); 2568c2ecf20Sopenharmony_ci i2c_register_board_info(2, nokia770_i2c_board_info_2, 2578c2ecf20Sopenharmony_ci ARRAY_SIZE(nokia770_i2c_board_info_2)); 2588c2ecf20Sopenharmony_ci gpiod_add_lookup_table(&nokia770_cbus_gpio_table); 2598c2ecf20Sopenharmony_ci platform_device_register(&nokia770_cbus_device); 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci#else /* CONFIG_I2C_CBUS_GPIO */ 2628c2ecf20Sopenharmony_cistatic void __init nokia770_cbus_init(void) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci} 2658c2ecf20Sopenharmony_ci#endif /* CONFIG_I2C_CBUS_GPIO */ 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_cistatic void __init omap_nokia770_init(void) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci /* On Nokia 770, the SleepX signal is masked with an 2708c2ecf20Sopenharmony_ci * MPUIO line by default. It has to be unmasked for it 2718c2ecf20Sopenharmony_ci * to become functional */ 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci /* SleepX mask direction */ 2748c2ecf20Sopenharmony_ci omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); 2758c2ecf20Sopenharmony_ci /* Unmask SleepX signal */ 2768c2ecf20Sopenharmony_ci omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); 2798c2ecf20Sopenharmony_ci nokia770_spi_board_info[1].irq = gpio_to_irq(15); 2808c2ecf20Sopenharmony_ci spi_register_board_info(nokia770_spi_board_info, 2818c2ecf20Sopenharmony_ci ARRAY_SIZE(nokia770_spi_board_info)); 2828c2ecf20Sopenharmony_ci omap_serial_init(); 2838c2ecf20Sopenharmony_ci omap_register_i2c_bus(1, 100, NULL, 0); 2848c2ecf20Sopenharmony_ci hwa742_dev_init(); 2858c2ecf20Sopenharmony_ci mipid_dev_init(); 2868c2ecf20Sopenharmony_ci omap1_usb_init(&nokia770_usb_config); 2878c2ecf20Sopenharmony_ci nokia770_mmc_init(); 2888c2ecf20Sopenharmony_ci nokia770_cbus_init(); 2898c2ecf20Sopenharmony_ci} 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ciMACHINE_START(NOKIA770, "Nokia 770") 2928c2ecf20Sopenharmony_ci .atag_offset = 0x100, 2938c2ecf20Sopenharmony_ci .map_io = omap16xx_map_io, 2948c2ecf20Sopenharmony_ci .init_early = omap1_init_early, 2958c2ecf20Sopenharmony_ci .init_irq = omap1_init_irq, 2968c2ecf20Sopenharmony_ci .handle_irq = omap1_handle_irq, 2978c2ecf20Sopenharmony_ci .init_machine = omap_nokia770_init, 2988c2ecf20Sopenharmony_ci .init_late = omap1_init_late, 2998c2ecf20Sopenharmony_ci .init_time = omap1_timer_init, 3008c2ecf20Sopenharmony_ci .restart = omap1_restart, 3018c2ecf20Sopenharmony_ciMACHINE_END 302