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/omapfb.h> 36 #include <asm/arch/lcd_mipid.h> 37 38 #define ADS7846_PENDOWN_GPIO 15 39 40 static void __init omap_nokia770_init_irq(void) 41 { 42 /* On Nokia 770, the SleepX signal is masked with an 43 * MPUIO line by default. It has to be unmasked for it 44 * to become functional */ 45 46 /* SleepX mask direction */ 47 omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); 48 /* Unmask SleepX signal */ 49 omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); 50 51 omap1_init_common_hw(); 52 omap_init_irq(); 53 } 54 55 static int nokia770_keymap[] = { 56 KEY(0, 1, GROUP_0 | KEY_UP), 57 KEY(0, 2, GROUP_1 | KEY_F5), 58 KEY(1, 0, GROUP_0 | KEY_LEFT), 59 KEY(1, 1, GROUP_0 | KEY_ENTER), 60 KEY(1, 2, GROUP_0 | KEY_RIGHT), 61 KEY(2, 0, GROUP_1 | KEY_ESC), 62 KEY(2, 1, GROUP_0 | KEY_DOWN), 63 KEY(2, 2, GROUP_1 | KEY_F4), 64 KEY(3, 0, GROUP_2 | KEY_F7), 65 KEY(3, 1, GROUP_2 | KEY_F8), 66 KEY(3, 2, GROUP_2 | KEY_F6), 67 0 68 }; 69 70 static struct resource nokia770_kp_resources[] = { 71 [0] = { 72 .start = INT_KEYBOARD, 73 .end = INT_KEYBOARD, 74 .flags = IORESOURCE_IRQ, 75 }, 76 }; 77 78 static struct omap_kp_platform_data nokia770_kp_data = { 79 .rows = 8, 80 .cols = 8, 81 .keymap = nokia770_keymap, 82 .keymapsize = ARRAY_SIZE(nokia770_keymap), 83 .delay = 4, 84 }; 85 86 static struct platform_device nokia770_kp_device = { 87 .name = "omap-keypad", 88 .id = -1, 89 .dev = { 90 .platform_data = &nokia770_kp_data, 91 }, 92 .num_resources = ARRAY_SIZE(nokia770_kp_resources), 93 .resource = nokia770_kp_resources, 94 }; 95 96 static struct platform_device *nokia770_devices[] __initdata = { 97 &nokia770_kp_device, 98 }; 99 100 static void mipid_shutdown(struct mipid_platform_data *pdata) 101 { 102 if (pdata->nreset_gpio != -1) { 103 printk(KERN_INFO "shutdown LCD\n"); 104 omap_set_gpio_dataout(pdata->nreset_gpio, 0); 105 msleep(120); 106 } 107 } 108 109 static struct mipid_platform_data nokia770_mipid_platform_data = { 110 .shutdown = mipid_shutdown, 111 }; 112 113 static void mipid_dev_init(void) 114 { 115 const struct omap_lcd_config *conf; 116 117 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); 118 if (conf != NULL) { 119 nokia770_mipid_platform_data.nreset_gpio = conf->nreset_gpio; 120 nokia770_mipid_platform_data.data_lines = conf->data_lines; 121 } 122 } 123 124 static void ads7846_dev_init(void) 125 { 126 if (omap_request_gpio(ADS7846_PENDOWN_GPIO) < 0) 127 printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); 128 } 129 130 static int ads7846_get_pendown_state(void) 131 { 132 return !omap_get_gpio_datain(ADS7846_PENDOWN_GPIO); 133 } 134 135 static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { 136 .x_max = 0x0fff, 137 .y_max = 0x0fff, 138 .x_plate_ohms = 180, 139 .pressure_max = 255, 140 .debounce_max = 10, 141 .debounce_tol = 3, 142 .debounce_rep = 1, 143 .get_pendown_state = ads7846_get_pendown_state, 144 }; 145 146 static struct spi_board_info nokia770_spi_board_info[] __initdata = { 147 [0] = { 148 .modalias = "lcd_mipid", 149 .bus_num = 2, 150 .chip_select = 3, 151 .max_speed_hz = 12000000, 152 .platform_data = &nokia770_mipid_platform_data, 153 }, 154 [1] = { 155 .modalias = "ads7846", 156 .bus_num = 2, 157 .chip_select = 0, 158 .max_speed_hz = 2500000, 159 .irq = OMAP_GPIO_IRQ(15), 160 .platform_data = &nokia770_ads7846_platform_data, 161 }, 162 }; 163 164 165 /* assume no Mini-AB port */ 166 167 static struct omap_usb_config nokia770_usb_config __initdata = { 168 .otg = 1, 169 .register_host = 1, 170 .register_dev = 1, 171 .hmc_mode = 16, 172 .pins[0] = 6, 173 }; 174 175 static struct omap_mmc_config nokia770_mmc_config __initdata = { 176 .mmc[0] = { 177 .enabled = 0, 178 .wire4 = 0, 179 .wp_pin = -1, 180 .power_pin = -1, 181 .switch_pin = -1, 182 }, 183 .mmc[1] = { 184 .enabled = 0, 185 .wire4 = 0, 186 .wp_pin = -1, 187 .power_pin = -1, 188 .switch_pin = -1, 189 }, 190 }; 191 192 static struct omap_board_config_kernel nokia770_config[] __initdata = { 193 { OMAP_TAG_USB, NULL }, 194 { OMAP_TAG_MMC, &nokia770_mmc_config }, 195 }; 196 197 #if defined(CONFIG_OMAP_DSP) 198 /* 199 * audio power control 200 */ 201 #define HEADPHONE_GPIO 14 202 #define AMPLIFIER_CTRL_GPIO 58 203 204 static struct clk *dspxor_ck; 205 static DECLARE_MUTEX(audio_pwr_sem); 206 /* 207 * audio_pwr_state 208 * +--+-------------------------+---------------------------------------+ 209 * |-1|down |power-up request -> 0 | 210 * +--+-------------------------+---------------------------------------+ 211 * | 0|up |power-down(1) request -> 1 | 212 * | | |power-down(2) request -> (ignore) | 213 * +--+-------------------------+---------------------------------------+ 214 * | 1|up, |power-up request -> 0 | 215 * | |received down(1) request |power-down(2) request -> -1 | 216 * +--+-------------------------+---------------------------------------+ 217 */ 218 static int audio_pwr_state = -1; 219 220 /* 221 * audio_pwr_up / down should be called under audio_pwr_sem 222 */ 223 static void nokia770_audio_pwr_up(void) 224 { 225 clk_enable(dspxor_ck); 226 227 /* Turn on codec */ 228 aic23_power_up(); 229 230 if (omap_get_gpio_datain(HEADPHONE_GPIO)) 231 /* HP not connected, turn on amplifier */ 232 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1); 233 else 234 /* HP connected, do not turn on amplifier */ 235 printk("HP connected\n"); 236 } 237 238 static void codec_delayed_power_down(struct work_struct *work) 239 { 240 down(&audio_pwr_sem); 241 if (audio_pwr_state == -1) 242 aic23_power_down(); 243 clk_disable(dspxor_ck); 244 up(&audio_pwr_sem); 245 } 246 247 static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); 248 249 static void nokia770_audio_pwr_down(void) 250 { 251 /* Turn off amplifier */ 252 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0); 253 254 /* Turn off codec: schedule delayed work */ 255 schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */ 256 } 257 258 static int 259 nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage) 260 { 261 down(&audio_pwr_sem); 262 if (audio_pwr_state == -1) 263 nokia770_audio_pwr_up(); 264 /* force audio_pwr_state = 0, even if it was 1. */ 265 audio_pwr_state = 0; 266 up(&audio_pwr_sem); 267 return 0; 268 } 269 270 static int 271 nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage) 272 { 273 down(&audio_pwr_sem); 274 switch (stage) { 275 case 1: 276 if (audio_pwr_state == 0) 277 audio_pwr_state = 1; 278 break; 279 case 2: 280 if (audio_pwr_state == 1) { 281 nokia770_audio_pwr_down(); 282 audio_pwr_state = -1; 283 } 284 break; 285 } 286 up(&audio_pwr_sem); 287 return 0; 288 } 289 290 static struct dsp_kfunc_device nokia770_audio_device = { 291 .name = "audio", 292 .type = DSP_KFUNC_DEV_TYPE_AUDIO, 293 .enable = nokia770_audio_pwr_up_request, 294 .disable = nokia770_audio_pwr_down_request, 295 }; 296 297 static __init int omap_dsp_init(void) 298 { 299 int ret; 300 301 dspxor_ck = clk_get(0, "dspxor_ck"); 302 if (IS_ERR(dspxor_ck)) { 303 printk(KERN_ERR "couldn't acquire dspxor_ck\n"); 304 return PTR_ERR(dspxor_ck); 305 } 306 307 ret = dsp_kfunc_device_register(&nokia770_audio_device); 308 if (ret) { 309 printk(KERN_ERR 310 "KFUNC device registration faild: %s\n", 311 nokia770_audio_device.name); 312 goto out; 313 } 314 return 0; 315 out: 316 return ret; 317 } 318 #else 319 #define omap_dsp_init() do {} while (0) 320 #endif /* CONFIG_OMAP_DSP */ 321 322 static void __init omap_nokia770_init(void) 323 { 324 nokia770_config[0].data = &nokia770_usb_config; 325 326 platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); 327 spi_register_board_info(nokia770_spi_board_info, 328 ARRAY_SIZE(nokia770_spi_board_info)); 329 omap_board_config = nokia770_config; 330 omap_board_config_size = ARRAY_SIZE(nokia770_config); 331 omap_gpio_init(); 332 omap_serial_init(); 333 omap_register_i2c_bus(1, 100, NULL, 0); 334 omap_dsp_init(); 335 ads7846_dev_init(); 336 mipid_dev_init(); 337 } 338 339 static void __init omap_nokia770_map_io(void) 340 { 341 omap1_map_common_io(); 342 } 343 344 MACHINE_START(NOKIA770, "Nokia 770") 345 .phys_io = 0xfff00000, 346 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, 347 .boot_params = 0x10000100, 348 .map_io = omap_nokia770_map_io, 349 .init_irq = omap_nokia770_init_irq, 350 .init_machine = omap_nokia770_init, 351 .timer = &omap_timer, 352 MACHINE_END 353