1/* 2 * linux/arch/arm/mach-omap1/board-nokia770.c 3 * 4 * Modified from board-generic.c 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/platform_device.h> 14#include <linux/input.h> 15#include <linux/clk.h> 16 17#include <linux/spi/spi.h> 18#include <linux/spi/ads7846.h> 19#include <linux/workqueue.h> 20#include <linux/delay.h> 21 22#include <asm/hardware.h> 23#include <asm/mach-types.h> 24#include <asm/mach/arch.h> 25#include <asm/mach/map.h> 26 27#include <asm/arch/gpio.h> 28#include <asm/arch/mux.h> 29#include <asm/arch/usb.h> 30#include <asm/arch/board.h> 31#include <asm/arch/keypad.h> 32#include <asm/arch/common.h> 33#include <asm/arch/dsp_common.h> 34#include <asm/arch/aic23.h> 35#include <asm/arch/gpio.h> 36 37static void __init omap_nokia770_init_irq(void) 38{ 39 /* On Nokia 770, the SleepX signal is masked with an 40 * MPUIO line by default. It has to be unmasked for it 41 * to become functional */ 42 43 /* SleepX mask direction */ 44 omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); 45 /* Unmask SleepX signal */ 46 omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); 47 48 omap1_init_common_hw(); 49 omap_init_irq(); 50} 51 52static int nokia770_keymap[] = { 53 KEY(0, 1, GROUP_0 | KEY_UP), 54 KEY(0, 2, GROUP_1 | KEY_F5), 55 KEY(1, 0, GROUP_0 | KEY_LEFT), 56 KEY(1, 1, GROUP_0 | KEY_ENTER), 57 KEY(1, 2, GROUP_0 | KEY_RIGHT), 58 KEY(2, 0, GROUP_1 | KEY_ESC), 59 KEY(2, 1, GROUP_0 | KEY_DOWN), 60 KEY(2, 2, GROUP_1 | KEY_F4), 61 KEY(3, 0, GROUP_2 | KEY_F7), 62 KEY(3, 1, GROUP_2 | KEY_F8), 63 KEY(3, 2, GROUP_2 | KEY_F6), 64 0 65}; 66 67static struct resource nokia770_kp_resources[] = { 68 [0] = { 69 .start = INT_KEYBOARD, 70 .end = INT_KEYBOARD, 71 .flags = IORESOURCE_IRQ, 72 }, 73}; 74 75static struct omap_kp_platform_data nokia770_kp_data = { 76 .rows = 8, 77 .cols = 8, 78 .keymap = nokia770_keymap, 79 .keymapsize = ARRAY_SIZE(nokia770_keymap), 80 .delay = 4, 81}; 82 83static struct platform_device nokia770_kp_device = { 84 .name = "omap-keypad", 85 .id = -1, 86 .dev = { 87 .platform_data = &nokia770_kp_data, 88 }, 89 .num_resources = ARRAY_SIZE(nokia770_kp_resources), 90 .resource = nokia770_kp_resources, 91}; 92 93static struct platform_device *nokia770_devices[] __initdata = { 94 &nokia770_kp_device, 95}; 96 97static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { 98 .x_max = 0x0fff, 99 .y_max = 0x0fff, 100 .x_plate_ohms = 180, 101 .pressure_max = 255, 102 .debounce_max = 10, 103 .debounce_tol = 3, 104}; 105 106static struct spi_board_info nokia770_spi_board_info[] __initdata = { 107 [0] = { 108 .modalias = "lcd_mipid", 109 .bus_num = 2, 110 .chip_select = 3, 111 .max_speed_hz = 12000000, 112 }, 113 [1] = { 114 .modalias = "ads7846", 115 .bus_num = 2, 116 .chip_select = 0, 117 .max_speed_hz = 2500000, 118 .irq = OMAP_GPIO_IRQ(15), 119 .platform_data = &nokia770_ads7846_platform_data, 120 }, 121}; 122 123 124/* assume no Mini-AB port */ 125 126static struct omap_usb_config nokia770_usb_config __initdata = { 127 .otg = 1, 128 .register_host = 1, 129 .register_dev = 1, 130 .hmc_mode = 16, 131 .pins[0] = 6, 132}; 133 134static struct omap_mmc_config nokia770_mmc_config __initdata = { 135 .mmc[0] = { 136 .enabled = 0, 137 .wire4 = 0, 138 .wp_pin = -1, 139 .power_pin = -1, 140 .switch_pin = -1, 141 }, 142 .mmc[1] = { 143 .enabled = 0, 144 .wire4 = 0, 145 .wp_pin = -1, 146 .power_pin = -1, 147 .switch_pin = -1, 148 }, 149}; 150 151static struct omap_board_config_kernel nokia770_config[] = { 152 { OMAP_TAG_USB, NULL }, 153 { OMAP_TAG_MMC, &nokia770_mmc_config }, 154}; 155 156/* 157 * audio power control 158 */ 159#define HEADPHONE_GPIO 14 160#define AMPLIFIER_CTRL_GPIO 58 161 162static struct clk *dspxor_ck; 163static DECLARE_MUTEX(audio_pwr_sem); 164/* 165 * audio_pwr_state 166 * +--+-------------------------+---------------------------------------+ 167 * |-1|down |power-up request -> 0 | 168 * +--+-------------------------+---------------------------------------+ 169 * | 0|up |power-down(1) request -> 1 | 170 * | | |power-down(2) request -> (ignore) | 171 * +--+-------------------------+---------------------------------------+ 172 * | 1|up, |power-up request -> 0 | 173 * | |received down(1) request |power-down(2) request -> -1 | 174 * +--+-------------------------+---------------------------------------+ 175 */ 176static int audio_pwr_state = -1; 177 178/* 179 * audio_pwr_up / down should be called under audio_pwr_sem 180 */ 181static void nokia770_audio_pwr_up(void) 182{ 183 clk_enable(dspxor_ck); 184 185 /* Turn on codec */ 186 tlv320aic23_power_up(); 187 188 if (omap_get_gpio_datain(HEADPHONE_GPIO)) 189 /* HP not connected, turn on amplifier */ 190 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1); 191 else 192 /* HP connected, do not turn on amplifier */ 193 printk("HP connected\n"); 194} 195 196static void codec_delayed_power_down(struct work_struct *work) 197{ 198 down(&audio_pwr_sem); 199 if (audio_pwr_state == -1) 200 tlv320aic23_power_down(); 201 clk_disable(dspxor_ck); 202 up(&audio_pwr_sem); 203} 204 205static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); 206 207static void nokia770_audio_pwr_down(void) 208{ 209 /* Turn off amplifier */ 210 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0); 211 212 /* Turn off codec: schedule delayed work */ 213 schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */ 214} 215 216void nokia770_audio_pwr_up_request(int stage) 217{ 218 down(&audio_pwr_sem); 219 if (audio_pwr_state == -1) 220 nokia770_audio_pwr_up(); 221 /* force audio_pwr_state = 0, even if it was 1. */ 222 audio_pwr_state = 0; 223 up(&audio_pwr_sem); 224} 225 226void nokia770_audio_pwr_down_request(int stage) 227{ 228 down(&audio_pwr_sem); 229 switch (stage) { 230 case 1: 231 if (audio_pwr_state == 0) 232 audio_pwr_state = 1; 233 break; 234 case 2: 235 if (audio_pwr_state == 1) { 236 nokia770_audio_pwr_down(); 237 audio_pwr_state = -1; 238 } 239 break; 240 } 241 up(&audio_pwr_sem); 242} 243 244static void __init omap_nokia770_init(void) 245{ 246 nokia770_config[0].data = &nokia770_usb_config; 247 248 platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); 249 spi_register_board_info(nokia770_spi_board_info, 250 ARRAY_SIZE(nokia770_spi_board_info)); 251 omap_board_config = nokia770_config; 252 omap_board_config_size = ARRAY_SIZE(nokia770_config); 253 omap_serial_init(); 254 omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request; 255 omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request; 256 dspxor_ck = clk_get(0, "dspxor_ck"); 257} 258 259static void __init omap_nokia770_map_io(void) 260{ 261 omap1_map_common_io(); 262} 263 264MACHINE_START(NOKIA770, "Nokia 770") 265 .phys_io = 0xfff00000, 266 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, 267 .boot_params = 0x10000100, 268 .map_io = omap_nokia770_map_io, 269 .init_irq = omap_nokia770_init_irq, 270 .init_machine = omap_nokia770_init, 271 .timer = &omap_timer, 272MACHINE_END 273