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 37 static 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 52 static 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 67 static struct resource nokia770_kp_resources[] = { 68 [0] = { 69 .start = INT_KEYBOARD, 70 .end = INT_KEYBOARD, 71 .flags = IORESOURCE_IRQ, 72 }, 73 }; 74 75 static 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 83 static 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 93 static struct platform_device *nokia770_devices[] __initdata = { 94 &nokia770_kp_device, 95 }; 96 97 static 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 106 static 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 126 static 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 134 static 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 151 static 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 162 static struct clk *dspxor_ck; 163 static 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 */ 176 static int audio_pwr_state = -1; 177 178 /* 179 * audio_pwr_up / down should be called under audio_pwr_sem 180 */ 181 static 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 196 static 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 205 static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); 206 207 static 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 216 void 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 226 void 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 244 static 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 259 static void __init omap_nokia770_map_io(void) 260 { 261 omap1_map_common_io(); 262 } 263 264 MACHINE_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, 272 MACHINE_END 273