diff options
Diffstat (limited to 'arch/arm/mach-s3c2410/mach-h1940.c')
-rw-r--r-- | arch/arm/mach-s3c2410/mach-h1940.c | 169 |
1 files changed, 154 insertions, 15 deletions
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 98c5c9e81ee9..d7ada8c7e41f 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/pwm_backlight.h> | 26 | #include <linux/pwm_backlight.h> |
27 | #include <linux/i2c.h> | ||
27 | #include <video/platform_lcd.h> | 28 | #include <video/platform_lcd.h> |
28 | 29 | ||
29 | #include <linux/mmc/host.h> | 30 | #include <linux/mmc/host.h> |
@@ -59,6 +60,14 @@ | |||
59 | #include <plat/mci.h> | 60 | #include <plat/mci.h> |
60 | #include <plat/ts.h> | 61 | #include <plat/ts.h> |
61 | 62 | ||
63 | #include <sound/uda1380.h> | ||
64 | |||
65 | #define H1940_LATCH ((void __force __iomem *)0xF8000000) | ||
66 | |||
67 | #define H1940_PA_LATCH S3C2410_CS2 | ||
68 | |||
69 | #define H1940_LATCH_BIT(x) (1 << ((x) + 16 - S3C_GPIO_END)) | ||
70 | |||
62 | static struct map_desc h1940_iodesc[] __initdata = { | 71 | static struct map_desc h1940_iodesc[] __initdata = { |
63 | [0] = { | 72 | [0] = { |
64 | .virtual = (unsigned long)H1940_LATCH, | 73 | .virtual = (unsigned long)H1940_LATCH, |
@@ -100,9 +109,9 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = { | |||
100 | 109 | ||
101 | /* Board control latch control */ | 110 | /* Board control latch control */ |
102 | 111 | ||
103 | static unsigned int latch_state = H1940_LATCH_DEFAULT; | 112 | static unsigned int latch_state; |
104 | 113 | ||
105 | void h1940_latch_control(unsigned int clear, unsigned int set) | 114 | static void h1940_latch_control(unsigned int clear, unsigned int set) |
106 | { | 115 | { |
107 | unsigned long flags; | 116 | unsigned long flags; |
108 | 117 | ||
@@ -116,7 +125,42 @@ void h1940_latch_control(unsigned int clear, unsigned int set) | |||
116 | local_irq_restore(flags); | 125 | local_irq_restore(flags); |
117 | } | 126 | } |
118 | 127 | ||
119 | EXPORT_SYMBOL_GPL(h1940_latch_control); | 128 | static inline int h1940_gpiolib_to_latch(int offset) |
129 | { | ||
130 | return 1 << (offset + 16); | ||
131 | } | ||
132 | |||
133 | static void h1940_gpiolib_latch_set(struct gpio_chip *chip, | ||
134 | unsigned offset, int value) | ||
135 | { | ||
136 | int latch_bit = h1940_gpiolib_to_latch(offset); | ||
137 | |||
138 | h1940_latch_control(value ? 0 : latch_bit, | ||
139 | value ? latch_bit : 0); | ||
140 | } | ||
141 | |||
142 | static int h1940_gpiolib_latch_output(struct gpio_chip *chip, | ||
143 | unsigned offset, int value) | ||
144 | { | ||
145 | h1940_gpiolib_latch_set(chip, offset, value); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int h1940_gpiolib_latch_get(struct gpio_chip *chip, | ||
150 | unsigned offset) | ||
151 | { | ||
152 | return (latch_state >> (offset + 16)) & 1; | ||
153 | } | ||
154 | |||
155 | struct gpio_chip h1940_latch_gpiochip = { | ||
156 | .base = H1940_LATCH_GPIO(0), | ||
157 | .owner = THIS_MODULE, | ||
158 | .label = "H1940_LATCH", | ||
159 | .ngpio = 16, | ||
160 | .direction_output = h1940_gpiolib_latch_output, | ||
161 | .set = h1940_gpiolib_latch_set, | ||
162 | .get = h1940_gpiolib_latch_get, | ||
163 | }; | ||
120 | 164 | ||
121 | static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd) | 165 | static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd) |
122 | { | 166 | { |
@@ -125,10 +169,10 @@ static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd) | |||
125 | switch (cmd) | 169 | switch (cmd) |
126 | { | 170 | { |
127 | case S3C2410_UDC_P_ENABLE : | 171 | case S3C2410_UDC_P_ENABLE : |
128 | h1940_latch_control(0, H1940_LATCH_USB_DP); | 172 | gpio_set_value(H1940_LATCH_USB_DP, 1); |
129 | break; | 173 | break; |
130 | case S3C2410_UDC_P_DISABLE : | 174 | case S3C2410_UDC_P_DISABLE : |
131 | h1940_latch_control(H1940_LATCH_USB_DP, 0); | 175 | gpio_set_value(H1940_LATCH_USB_DP, 0); |
132 | break; | 176 | break; |
133 | case S3C2410_UDC_P_RESET : | 177 | case S3C2410_UDC_P_RESET : |
134 | break; | 178 | break; |
@@ -199,10 +243,25 @@ static struct platform_device h1940_device_bluetooth = { | |||
199 | .id = -1, | 243 | .id = -1, |
200 | }; | 244 | }; |
201 | 245 | ||
246 | static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd) | ||
247 | { | ||
248 | switch (power_mode) { | ||
249 | case MMC_POWER_OFF: | ||
250 | gpio_set_value(H1940_LATCH_SD_POWER, 0); | ||
251 | break; | ||
252 | case MMC_POWER_UP: | ||
253 | case MMC_POWER_ON: | ||
254 | gpio_set_value(H1940_LATCH_SD_POWER, 1); | ||
255 | break; | ||
256 | default: | ||
257 | break; | ||
258 | }; | ||
259 | } | ||
260 | |||
202 | static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = { | 261 | static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = { |
203 | .gpio_detect = S3C2410_GPF(5), | 262 | .gpio_detect = S3C2410_GPF(5), |
204 | .gpio_wprotect = S3C2410_GPH(8), | 263 | .gpio_wprotect = S3C2410_GPH(8), |
205 | .set_power = NULL, | 264 | .set_power = h1940_set_mmc_power, |
206 | .ocr_avail = MMC_VDD_32_33, | 265 | .ocr_avail = MMC_VDD_32_33, |
207 | }; | 266 | }; |
208 | 267 | ||
@@ -213,15 +272,32 @@ static int h1940_backlight_init(struct device *dev) | |||
213 | gpio_direction_output(S3C2410_GPB(0), 0); | 272 | gpio_direction_output(S3C2410_GPB(0), 0); |
214 | s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE); | 273 | s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE); |
215 | s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); | 274 | s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); |
275 | gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1); | ||
216 | 276 | ||
217 | return 0; | 277 | return 0; |
218 | } | 278 | } |
219 | 279 | ||
280 | static int h1940_backlight_notify(struct device *dev, int brightness) | ||
281 | { | ||
282 | if (!brightness) { | ||
283 | gpio_direction_output(S3C2410_GPB(0), 1); | ||
284 | gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0); | ||
285 | } else { | ||
286 | gpio_direction_output(S3C2410_GPB(0), 0); | ||
287 | s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE); | ||
288 | s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); | ||
289 | gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1); | ||
290 | } | ||
291 | return brightness; | ||
292 | } | ||
293 | |||
220 | static void h1940_backlight_exit(struct device *dev) | 294 | static void h1940_backlight_exit(struct device *dev) |
221 | { | 295 | { |
222 | gpio_direction_output(S3C2410_GPB(0), 1); | 296 | gpio_direction_output(S3C2410_GPB(0), 1); |
297 | gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0); | ||
223 | } | 298 | } |
224 | 299 | ||
300 | |||
225 | static struct platform_pwm_backlight_data backlight_data = { | 301 | static struct platform_pwm_backlight_data backlight_data = { |
226 | .pwm_id = 0, | 302 | .pwm_id = 0, |
227 | .max_brightness = 100, | 303 | .max_brightness = 100, |
@@ -229,6 +305,7 @@ static struct platform_pwm_backlight_data backlight_data = { | |||
229 | /* tcnt = 0x31 */ | 305 | /* tcnt = 0x31 */ |
230 | .pwm_period_ns = 36296, | 306 | .pwm_period_ns = 36296, |
231 | .init = h1940_backlight_init, | 307 | .init = h1940_backlight_init, |
308 | .notify = h1940_backlight_notify, | ||
232 | .exit = h1940_backlight_exit, | 309 | .exit = h1940_backlight_exit, |
233 | }; | 310 | }; |
234 | 311 | ||
@@ -247,19 +324,37 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd, | |||
247 | int value; | 324 | int value; |
248 | 325 | ||
249 | if (!power) { | 326 | if (!power) { |
250 | /* set to 3ec */ | 327 | gpio_set_value(S3C2410_GPC(0), 0); |
251 | gpio_direction_output(S3C2410_GPC(0), 0); | ||
252 | /* wait for 3ac */ | 328 | /* wait for 3ac */ |
253 | do { | 329 | do { |
254 | value = gpio_get_value(S3C2410_GPC(6)); | 330 | value = gpio_get_value(S3C2410_GPC(6)); |
255 | } while (value); | 331 | } while (value); |
256 | /* set to 38c */ | 332 | |
257 | gpio_direction_output(S3C2410_GPC(5), 0); | 333 | gpio_set_value(H1940_LATCH_LCD_P2, 0); |
334 | gpio_set_value(H1940_LATCH_LCD_P3, 0); | ||
335 | gpio_set_value(H1940_LATCH_LCD_P4, 0); | ||
336 | |||
337 | gpio_direction_output(S3C2410_GPC(1), 0); | ||
338 | gpio_direction_output(S3C2410_GPC(4), 0); | ||
339 | |||
340 | gpio_set_value(H1940_LATCH_LCD_P1, 0); | ||
341 | gpio_set_value(H1940_LATCH_LCD_P0, 0); | ||
342 | |||
343 | gpio_set_value(S3C2410_GPC(5), 0); | ||
344 | |||
258 | } else { | 345 | } else { |
259 | /* Set to 3ac */ | 346 | gpio_set_value(H1940_LATCH_LCD_P0, 1); |
260 | gpio_direction_output(S3C2410_GPC(5), 1); | 347 | gpio_set_value(H1940_LATCH_LCD_P1, 1); |
261 | /* Set to 3ad */ | 348 | |
262 | gpio_direction_output(S3C2410_GPC(0), 1); | 349 | s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2)); |
350 | s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2)); | ||
351 | |||
352 | gpio_set_value(S3C2410_GPC(5), 1); | ||
353 | gpio_set_value(S3C2410_GPC(0), 1); | ||
354 | |||
355 | gpio_set_value(H1940_LATCH_LCD_P3, 1); | ||
356 | gpio_set_value(H1940_LATCH_LCD_P2, 1); | ||
357 | gpio_set_value(H1940_LATCH_LCD_P4, 1); | ||
263 | } | 358 | } |
264 | } | 359 | } |
265 | 360 | ||
@@ -273,12 +368,26 @@ static struct platform_device h1940_lcd_powerdev = { | |||
273 | .dev.platform_data = &h1940_lcd_power_data, | 368 | .dev.platform_data = &h1940_lcd_power_data, |
274 | }; | 369 | }; |
275 | 370 | ||
371 | static struct uda1380_platform_data uda1380_info = { | ||
372 | .gpio_power = H1940_LATCH_UDA_POWER, | ||
373 | .gpio_reset = S3C2410_GPA(12), | ||
374 | .dac_clk = UDA1380_DAC_CLK_SYSCLK, | ||
375 | }; | ||
376 | |||
377 | static struct i2c_board_info h1940_i2c_devices[] = { | ||
378 | { | ||
379 | I2C_BOARD_INFO("uda1380", 0x1a), | ||
380 | .platform_data = &uda1380_info, | ||
381 | }, | ||
382 | }; | ||
383 | |||
276 | static struct platform_device *h1940_devices[] __initdata = { | 384 | static struct platform_device *h1940_devices[] __initdata = { |
277 | &s3c_device_ohci, | 385 | &s3c_device_ohci, |
278 | &s3c_device_lcd, | 386 | &s3c_device_lcd, |
279 | &s3c_device_wdt, | 387 | &s3c_device_wdt, |
280 | &s3c_device_i2c0, | 388 | &s3c_device_i2c0, |
281 | &s3c_device_iis, | 389 | &s3c_device_iis, |
390 | &s3c_device_pcm, | ||
282 | &s3c_device_usbgadget, | 391 | &s3c_device_usbgadget, |
283 | &h1940_device_leds, | 392 | &h1940_device_leds, |
284 | &h1940_device_bluetooth, | 393 | &h1940_device_bluetooth, |
@@ -303,6 +412,10 @@ static void __init h1940_map_io(void) | |||
303 | memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); | 412 | memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); |
304 | #endif | 413 | #endif |
305 | s3c_pm_init(); | 414 | s3c_pm_init(); |
415 | |||
416 | /* Add latch gpio chip, set latch initial value */ | ||
417 | h1940_latch_control(0, 0); | ||
418 | WARN_ON(gpiochip_add(&h1940_latch_gpiochip)); | ||
306 | } | 419 | } |
307 | 420 | ||
308 | /* H1940 and RX3715 need to reserve this for suspend */ | 421 | /* H1940 and RX3715 need to reserve this for suspend */ |
@@ -340,12 +453,38 @@ static void __init h1940_init(void) | |||
340 | writel(tmp, S3C2410_UPLLCON); | 453 | writel(tmp, S3C2410_UPLLCON); |
341 | 454 | ||
342 | gpio_request(S3C2410_GPC(0), "LCD power"); | 455 | gpio_request(S3C2410_GPC(0), "LCD power"); |
456 | gpio_request(S3C2410_GPC(1), "LCD power"); | ||
457 | gpio_request(S3C2410_GPC(4), "LCD power"); | ||
343 | gpio_request(S3C2410_GPC(5), "LCD power"); | 458 | gpio_request(S3C2410_GPC(5), "LCD power"); |
344 | gpio_request(S3C2410_GPC(6), "LCD power"); | 459 | gpio_request(S3C2410_GPC(6), "LCD power"); |
345 | 460 | gpio_request(H1940_LATCH_LCD_P0, "LCD power"); | |
461 | gpio_request(H1940_LATCH_LCD_P1, "LCD power"); | ||
462 | gpio_request(H1940_LATCH_LCD_P2, "LCD power"); | ||
463 | gpio_request(H1940_LATCH_LCD_P3, "LCD power"); | ||
464 | gpio_request(H1940_LATCH_LCD_P4, "LCD power"); | ||
465 | gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power"); | ||
466 | gpio_direction_output(S3C2410_GPC(0), 0); | ||
467 | gpio_direction_output(S3C2410_GPC(1), 0); | ||
468 | gpio_direction_output(S3C2410_GPC(4), 0); | ||
469 | gpio_direction_output(S3C2410_GPC(5), 0); | ||
346 | gpio_direction_input(S3C2410_GPC(6)); | 470 | gpio_direction_input(S3C2410_GPC(6)); |
471 | gpio_direction_output(H1940_LATCH_LCD_P0, 0); | ||
472 | gpio_direction_output(H1940_LATCH_LCD_P1, 0); | ||
473 | gpio_direction_output(H1940_LATCH_LCD_P2, 0); | ||
474 | gpio_direction_output(H1940_LATCH_LCD_P3, 0); | ||
475 | gpio_direction_output(H1940_LATCH_LCD_P4, 0); | ||
476 | gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0); | ||
477 | |||
478 | gpio_request(H1940_LATCH_USB_DP, "USB pullup"); | ||
479 | gpio_direction_output(H1940_LATCH_USB_DP, 0); | ||
480 | |||
481 | gpio_request(H1940_LATCH_SD_POWER, "SD power"); | ||
482 | gpio_direction_output(H1940_LATCH_SD_POWER, 0); | ||
347 | 483 | ||
348 | platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); | 484 | platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); |
485 | |||
486 | i2c_register_board_info(0, h1940_i2c_devices, | ||
487 | ARRAY_SIZE(h1940_i2c_devices)); | ||
349 | } | 488 | } |
350 | 489 | ||
351 | MACHINE_START(H1940, "IPAQ-H1940") | 490 | MACHINE_START(H1940, "IPAQ-H1940") |