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