1/* mach-hmt.c - Platform code for Airgoo HMT 2 * 3 * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9*/ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/serial_core.h> 14#include <linux/serial_s3c.h> 15#include <linux/platform_device.h> 16#include <linux/io.h> 17#include <linux/i2c.h> 18#include <linux/fb.h> 19#include <linux/gpio.h> 20#include <linux/delay.h> 21#include <linux/leds.h> 22#include <linux/pwm.h> 23#include <linux/pwm_backlight.h> 24#include <linux/mtd/mtd.h> 25#include <linux/mtd/partitions.h> 26 27#include <asm/mach/arch.h> 28#include <asm/mach/map.h> 29#include <asm/mach/irq.h> 30 31#include <video/samsung_fimd.h> 32#include <mach/hardware.h> 33#include <mach/map.h> 34 35#include <asm/irq.h> 36#include <asm/mach-types.h> 37 38#include <linux/platform_data/i2c-s3c2410.h> 39#include <mach/gpio-samsung.h> 40#include <plat/fb.h> 41#include <linux/platform_data/mtd-nand-s3c2410.h> 42 43#include <plat/devs.h> 44#include <plat/cpu.h> 45#include <plat/samsung-time.h> 46 47#include "common.h" 48 49#define UCON S3C2410_UCON_DEFAULT 50#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) 51#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) 52 53static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = { 54 [0] = { 55 .hwport = 0, 56 .flags = 0, 57 .ucon = UCON, 58 .ulcon = ULCON, 59 .ufcon = UFCON, 60 }, 61 [1] = { 62 .hwport = 1, 63 .flags = 0, 64 .ucon = UCON, 65 .ulcon = ULCON, 66 .ufcon = UFCON, 67 }, 68 [2] = { 69 .hwport = 2, 70 .flags = 0, 71 .ucon = UCON, 72 .ulcon = ULCON, 73 .ufcon = UFCON, 74 }, 75}; 76 77static struct pwm_lookup hmt_pwm_lookup[] = { 78 PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 79 1000000000 / (100 * 256 * 20), PWM_POLARITY_NORMAL), 80}; 81 82static int hmt_bl_init(struct device *dev) 83{ 84 int ret; 85 86 ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable"); 87 if (!ret) 88 ret = gpio_direction_output(S3C64XX_GPB(4), 0); 89 90 return ret; 91} 92 93static int hmt_bl_notify(struct device *dev, int brightness) 94{ 95 /* 96 * translate from CIELUV/CIELAB L*->brightness, E.G. from 97 * perceived luminance to light output. Assumes range 0..25600 98 */ 99 if (brightness < 0x800) { 100 /* Y = Yn * L / 903.3 */ 101 brightness = (100*256 * brightness + 231245/2) / 231245; 102 } else { 103 /* Y = Yn * ((L + 16) / 116 )^3 */ 104 int t = (brightness*4 + 16*1024 + 58)/116; 105 brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000); 106 } 107 108 gpio_set_value(S3C64XX_GPB(4), brightness); 109 110 return brightness; 111} 112 113static void hmt_bl_exit(struct device *dev) 114{ 115 gpio_free(S3C64XX_GPB(4)); 116} 117 118static struct platform_pwm_backlight_data hmt_backlight_data = { 119 .max_brightness = 100 * 256, 120 .dft_brightness = 40 * 256, 121 .enable_gpio = -1, 122 .init = hmt_bl_init, 123 .notify = hmt_bl_notify, 124 .exit = hmt_bl_exit, 125 126}; 127 128static struct platform_device hmt_backlight_device = { 129 .name = "pwm-backlight", 130 .dev = { 131 .parent = &samsung_device_pwm.dev, 132 .platform_data = &hmt_backlight_data, 133 }, 134}; 135 136static struct s3c_fb_pd_win hmt_fb_win0 = { 137 .max_bpp = 32, 138 .default_bpp = 16, 139 .xres = 800, 140 .yres = 480, 141}; 142 143static struct fb_videomode hmt_lcd_timing = { 144 .left_margin = 8, 145 .right_margin = 13, 146 .upper_margin = 7, 147 .lower_margin = 5, 148 .hsync_len = 3, 149 .vsync_len = 1, 150 .xres = 800, 151 .yres = 480, 152}; 153 154/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ 155static struct s3c_fb_platdata hmt_lcd_pdata __initdata = { 156 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 157 .vtiming = &hmt_lcd_timing, 158 .win[0] = &hmt_fb_win0, 159 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 160 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 161}; 162 163static struct mtd_partition hmt_nand_part[] = { 164 [0] = { 165 .name = "uboot", 166 .size = SZ_512K, 167 .offset = 0, 168 }, 169 [1] = { 170 .name = "uboot-env1", 171 .size = SZ_256K, 172 .offset = SZ_512K, 173 }, 174 [2] = { 175 .name = "uboot-env2", 176 .size = SZ_256K, 177 .offset = SZ_512K + SZ_256K, 178 }, 179 [3] = { 180 .name = "kernel", 181 .size = SZ_2M, 182 .offset = SZ_1M, 183 }, 184 [4] = { 185 .name = "rootfs", 186 .size = MTDPART_SIZ_FULL, 187 .offset = SZ_1M + SZ_2M, 188 }, 189}; 190 191static struct s3c2410_nand_set hmt_nand_sets[] = { 192 [0] = { 193 .name = "nand", 194 .nr_chips = 1, 195 .nr_partitions = ARRAY_SIZE(hmt_nand_part), 196 .partitions = hmt_nand_part, 197 }, 198}; 199 200static struct s3c2410_platform_nand hmt_nand_info = { 201 .tacls = 25, 202 .twrph0 = 55, 203 .twrph1 = 40, 204 .nr_sets = ARRAY_SIZE(hmt_nand_sets), 205 .sets = hmt_nand_sets, 206}; 207 208static struct gpio_led hmt_leds[] = { 209 { /* left function keys */ 210 .name = "left:blue", 211 .gpio = S3C64XX_GPO(12), 212 .default_trigger = "default-on", 213 }, 214 { /* right function keys - red */ 215 .name = "right:red", 216 .gpio = S3C64XX_GPO(13), 217 }, 218 { /* right function keys - green */ 219 .name = "right:green", 220 .gpio = S3C64XX_GPO(14), 221 }, 222 { /* right function keys - blue */ 223 .name = "right:blue", 224 .gpio = S3C64XX_GPO(15), 225 .default_trigger = "default-on", 226 }, 227}; 228 229static struct gpio_led_platform_data hmt_led_data = { 230 .num_leds = ARRAY_SIZE(hmt_leds), 231 .leds = hmt_leds, 232}; 233 234static struct platform_device hmt_leds_device = { 235 .name = "leds-gpio", 236 .id = -1, 237 .dev.platform_data = &hmt_led_data, 238}; 239 240static struct map_desc hmt_iodesc[] = {}; 241 242static struct platform_device *hmt_devices[] __initdata = { 243 &s3c_device_i2c0, 244 &s3c_device_nand, 245 &s3c_device_fb, 246 &s3c_device_ohci, 247 &samsung_device_pwm, 248 &hmt_backlight_device, 249 &hmt_leds_device, 250}; 251 252static void __init hmt_map_io(void) 253{ 254 s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); 255 s3c64xx_set_xtal_freq(12000000); 256 s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); 257 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); 258} 259 260static void __init hmt_machine_init(void) 261{ 262 s3c_i2c0_set_platdata(NULL); 263 s3c_fb_set_platdata(&hmt_lcd_pdata); 264 s3c_nand_set_platdata(&hmt_nand_info); 265 266 gpio_request(S3C64XX_GPC(7), "usb power"); 267 gpio_direction_output(S3C64XX_GPC(7), 0); 268 gpio_request(S3C64XX_GPM(0), "usb power"); 269 gpio_direction_output(S3C64XX_GPM(0), 1); 270 gpio_request(S3C64XX_GPK(7), "usb power"); 271 gpio_direction_output(S3C64XX_GPK(7), 1); 272 gpio_request(S3C64XX_GPF(13), "usb power"); 273 gpio_direction_output(S3C64XX_GPF(13), 1); 274 275 pwm_add_table(hmt_pwm_lookup, ARRAY_SIZE(hmt_pwm_lookup)); 276 platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices)); 277} 278 279MACHINE_START(HMT, "Airgoo-HMT") 280 /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */ 281 .atag_offset = 0x100, 282 .init_irq = s3c6410_init_irq, 283 .map_io = hmt_map_io, 284 .init_machine = hmt_machine_init, 285 .init_time = samsung_timer_init, 286 .restart = s3c64xx_restart, 287MACHINE_END 288