2017-12-25 22:54:32 +03:00
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
// Copyright (c) 2007-2010 Vasily Khoruzhick
//
// based on smdk2440 written by Ben Dooks
2010-05-11 10:55:07 +04:00
# include <linux/kernel.h>
# include <linux/types.h>
# include <linux/interrupt.h>
# include <linux/list.h>
2010-05-22 22:47:18 +04:00
# include <linux/memblock.h>
2010-05-11 10:55:07 +04:00
# include <linux/delay.h>
# include <linux/timer.h>
# include <linux/init.h>
# include <linux/gpio.h>
2018-12-02 11:43:20 +03:00
# include <linux/gpio/machine.h>
2010-05-11 10:55:07 +04:00
# include <linux/platform_device.h>
# include <linux/serial_core.h>
2014-02-14 05:32:45 +04:00
# include <linux/serial_s3c.h>
2010-05-11 10:55:07 +04:00
# include <linux/input.h>
# include <linux/gpio_keys.h>
2011-12-22 04:26:03 +04:00
# include <linux/device.h>
2010-09-27 01:17:48 +04:00
# include <linux/pda_power.h>
2010-05-11 10:55:07 +04:00
# include <linux/pwm_backlight.h>
# include <linux/pwm.h>
2010-09-27 01:17:48 +04:00
# include <linux/s3c_adc_battery.h>
2010-09-07 18:32:25 +04:00
# include <linux/leds.h>
2010-09-07 18:32:26 +04:00
# include <linux/i2c.h>
2010-05-11 10:55:07 +04:00
# include <linux/mtd/mtd.h>
# include <linux/mtd/partitions.h>
# include <linux/mmc/host.h>
2013-01-02 22:18:58 +04:00
# include <asm/mach-types.h>
2010-05-11 10:55:07 +04:00
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
2013-01-02 22:18:58 +04:00
# include <linux/platform_data/i2c-s3c2410.h>
# include <linux/platform_data/mmc-s3cmci.h>
# include <linux/platform_data/mtd-nand-s3c2410.h>
# include <linux/platform_data/touchscreen-s3c2410.h>
# include <linux/platform_data/usb-s3c2410_udc.h>
2019-09-02 23:33:24 +03:00
# include <linux/platform_data/fb-s3c2410.h>
2013-01-02 22:18:58 +04:00
# include <sound/uda1380.h>
2019-09-02 19:37:30 +03:00
# include "hardware-s3c24xx.h"
# include "regs-gpio.h"
# include "gpio-samsung.h"
2010-05-11 10:55:07 +04:00
2019-09-02 19:37:30 +03:00
# include "cpu.h"
# include "devs.h"
# include "pm.h"
# include "gpio-cfg.h"
2010-09-07 18:32:26 +04:00
2019-09-02 18:47:55 +03:00
# include "s3c24xx.h"
2013-01-02 22:18:58 +04:00
# include "h1940.h"
2012-01-03 17:02:03 +04:00
2010-05-11 10:55:07 +04:00
# define LCD_PWM_PERIOD 192960
# define LCD_PWM_DUTY 127353
static struct map_desc rx1950_iodesc [ ] __initdata = {
} ;
static struct s3c2410_uartcfg rx1950_uartcfgs [ ] __initdata = {
[ 0 ] = {
. hwport = 0 ,
. flags = 0 ,
. ucon = 0x3c5 ,
. ulcon = 0x03 ,
. ufcon = 0x51 ,
2011-10-24 13:47:51 +04:00
. clk_sel = S3C2410_UCON_CLKSEL3 ,
2010-05-11 10:55:07 +04:00
} ,
[ 1 ] = {
. hwport = 1 ,
. flags = 0 ,
. ucon = 0x3c5 ,
. ulcon = 0x03 ,
. ufcon = 0x51 ,
2011-10-24 13:47:51 +04:00
. clk_sel = S3C2410_UCON_CLKSEL3 ,
2010-05-11 10:55:07 +04:00
} ,
/* IR port */
[ 2 ] = {
. hwport = 2 ,
. flags = 0 ,
. ucon = 0x3c5 ,
. ulcon = 0x43 ,
. ufcon = 0xf1 ,
2011-10-24 13:47:51 +04:00
. clk_sel = S3C2410_UCON_CLKSEL3 ,
2010-05-11 10:55:07 +04:00
} ,
} ;
static struct s3c2410fb_display rx1950_display = {
. type = S3C2410_LCDCON1_TFT ,
. width = 240 ,
. height = 320 ,
. xres = 240 ,
. yres = 320 ,
. bpp = 16 ,
. pixclock = 260000 ,
. left_margin = 10 ,
. right_margin = 20 ,
. hsync_len = 10 ,
. upper_margin = 2 ,
. lower_margin = 2 ,
. vsync_len = 2 ,
. lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVCLK |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_HWSWP |
( 0x02 < < 13 ) |
( 0x02 < < 15 ) ,
} ;
2010-09-27 01:17:48 +04:00
static int power_supply_init ( struct device * dev )
{
return gpio_request ( S3C2410_GPF ( 2 ) , " cable plugged " ) ;
}
static int rx1950_is_ac_online ( void )
{
return ! gpio_get_value ( S3C2410_GPF ( 2 ) ) ;
}
static void power_supply_exit ( struct device * dev )
{
gpio_free ( S3C2410_GPF ( 2 ) ) ;
}
static char * rx1950_supplicants [ ] = {
" main-battery "
} ;
static struct pda_power_pdata power_supply_info = {
. init = power_supply_init ,
. is_ac_online = rx1950_is_ac_online ,
. exit = power_supply_exit ,
. supplied_to = rx1950_supplicants ,
. num_supplicants = ARRAY_SIZE ( rx1950_supplicants ) ,
} ;
static struct resource power_supply_resources [ ] = {
2012-05-12 11:12:25 +04:00
[ 0 ] = DEFINE_RES_NAMED ( IRQ_EINT2 , 1 , " ac " , IORESOURCE_IRQ \
| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE ) ,
2010-09-27 01:17:48 +04:00
} ;
static struct platform_device power_supply = {
. name = " pda-power " ,
. id = - 1 ,
. dev = {
. platform_data =
& power_supply_info ,
} ,
. resource = power_supply_resources ,
. num_resources = ARRAY_SIZE ( power_supply_resources ) ,
} ;
static const struct s3c_adc_bat_thresh bat_lut_noac [ ] = {
{ . volt = 4100 , . cur = 156 , . level = 100 } ,
{ . volt = 4050 , . cur = 156 , . level = 95 } ,
{ . volt = 4025 , . cur = 141 , . level = 90 } ,
{ . volt = 3995 , . cur = 144 , . level = 85 } ,
{ . volt = 3957 , . cur = 162 , . level = 80 } ,
{ . volt = 3931 , . cur = 147 , . level = 75 } ,
{ . volt = 3902 , . cur = 147 , . level = 70 } ,
{ . volt = 3863 , . cur = 153 , . level = 65 } ,
{ . volt = 3838 , . cur = 150 , . level = 60 } ,
{ . volt = 3800 , . cur = 153 , . level = 55 } ,
{ . volt = 3765 , . cur = 153 , . level = 50 } ,
{ . volt = 3748 , . cur = 172 , . level = 45 } ,
{ . volt = 3740 , . cur = 153 , . level = 40 } ,
{ . volt = 3714 , . cur = 175 , . level = 35 } ,
{ . volt = 3710 , . cur = 156 , . level = 30 } ,
{ . volt = 3963 , . cur = 156 , . level = 25 } ,
{ . volt = 3672 , . cur = 178 , . level = 20 } ,
{ . volt = 3651 , . cur = 178 , . level = 15 } ,
{ . volt = 3629 , . cur = 178 , . level = 10 } ,
{ . volt = 3612 , . cur = 162 , . level = 5 } ,
{ . volt = 3605 , . cur = 162 , . level = 0 } ,
} ;
static const struct s3c_adc_bat_thresh bat_lut_acin [ ] = {
{ . volt = 4200 , . cur = 0 , . level = 100 } ,
{ . volt = 4190 , . cur = 0 , . level = 99 } ,
{ . volt = 4178 , . cur = 0 , . level = 95 } ,
{ . volt = 4110 , . cur = 0 , . level = 70 } ,
{ . volt = 4076 , . cur = 0 , . level = 65 } ,
{ . volt = 4046 , . cur = 0 , . level = 60 } ,
{ . volt = 4021 , . cur = 0 , . level = 55 } ,
{ . volt = 3999 , . cur = 0 , . level = 50 } ,
{ . volt = 3982 , . cur = 0 , . level = 45 } ,
{ . volt = 3965 , . cur = 0 , . level = 40 } ,
{ . volt = 3957 , . cur = 0 , . level = 35 } ,
{ . volt = 3948 , . cur = 0 , . level = 30 } ,
{ . volt = 3936 , . cur = 0 , . level = 25 } ,
{ . volt = 3927 , . cur = 0 , . level = 20 } ,
{ . volt = 3906 , . cur = 0 , . level = 15 } ,
{ . volt = 3880 , . cur = 0 , . level = 10 } ,
{ . volt = 3829 , . cur = 0 , . level = 5 } ,
{ . volt = 3820 , . cur = 0 , . level = 0 } ,
} ;
2020-11-03 02:48:44 +03:00
static struct gpiod_lookup_table rx1950_bat_gpio_table = {
. dev_id = " s3c-adc-battery " ,
. table = {
/* Charge status S3C2410_GPF(3) */
GPIO_LOOKUP ( " GPIOF " , 3 , " charge-status " , GPIO_ACTIVE_HIGH ) ,
{ } ,
} ,
} ;
2012-01-21 06:46:41 +04:00
static int rx1950_bat_init ( void )
2010-09-27 01:17:48 +04:00
{
int ret ;
ret = gpio_request ( S3C2410_GPJ ( 2 ) , " rx1950-charger-enable-1 " ) ;
if ( ret )
goto err_gpio1 ;
ret = gpio_request ( S3C2410_GPJ ( 3 ) , " rx1950-charger-enable-2 " ) ;
if ( ret )
goto err_gpio2 ;
return 0 ;
err_gpio2 :
gpio_free ( S3C2410_GPJ ( 2 ) ) ;
err_gpio1 :
return ret ;
}
2012-01-21 06:46:41 +04:00
static void rx1950_bat_exit ( void )
2010-09-27 01:17:48 +04:00
{
gpio_free ( S3C2410_GPJ ( 2 ) ) ;
gpio_free ( S3C2410_GPJ ( 3 ) ) ;
}
2012-01-21 06:46:41 +04:00
static void rx1950_enable_charger ( void )
2010-09-27 01:17:48 +04:00
{
gpio_direction_output ( S3C2410_GPJ ( 2 ) , 1 ) ;
gpio_direction_output ( S3C2410_GPJ ( 3 ) , 1 ) ;
}
2012-01-21 06:46:41 +04:00
static void rx1950_disable_charger ( void )
2010-09-27 01:17:48 +04:00
{
gpio_direction_output ( S3C2410_GPJ ( 2 ) , 0 ) ;
gpio_direction_output ( S3C2410_GPJ ( 3 ) , 0 ) ;
}
2012-01-21 06:46:41 +04:00
static DEFINE_SPINLOCK ( rx1950_blink_spin ) ;
2011-01-06 22:52:52 +03:00
2014-10-31 14:40:58 +03:00
static int rx1950_led_blink_set ( struct gpio_desc * desc , int state ,
2011-01-06 22:52:52 +03:00
unsigned long * delay_on , unsigned long * delay_off )
{
2014-10-31 14:40:58 +03:00
int gpio = desc_to_gpio ( desc ) ;
2011-01-06 22:52:52 +03:00
int blink_gpio , check_gpio ;
switch ( gpio ) {
case S3C2410_GPA ( 6 ) :
blink_gpio = S3C2410_GPA ( 4 ) ;
check_gpio = S3C2410_GPA ( 3 ) ;
break ;
case S3C2410_GPA ( 7 ) :
blink_gpio = S3C2410_GPA ( 3 ) ;
check_gpio = S3C2410_GPA ( 4 ) ;
break ;
default :
return - EINVAL ;
}
if ( delay_on & & delay_off & & ! * delay_on & & ! * delay_off )
* delay_on = * delay_off = 500 ;
spin_lock ( & rx1950_blink_spin ) ;
switch ( state ) {
case GPIO_LED_NO_BLINK_LOW :
case GPIO_LED_NO_BLINK_HIGH :
if ( ! gpio_get_value ( check_gpio ) )
gpio_set_value ( S3C2410_GPJ ( 6 ) , 0 ) ;
gpio_set_value ( blink_gpio , 0 ) ;
gpio_set_value ( gpio , state ) ;
break ;
case GPIO_LED_BLINK :
gpio_set_value ( gpio , 0 ) ;
gpio_set_value ( S3C2410_GPJ ( 6 ) , 1 ) ;
gpio_set_value ( blink_gpio , 1 ) ;
break ;
}
spin_unlock ( & rx1950_blink_spin ) ;
return 0 ;
}
2010-09-07 18:32:25 +04:00
static struct gpio_led rx1950_leds_desc [ ] = {
{
2011-03-17 21:04:57 +03:00
. name = " Green " ,
. default_trigger = " main-battery-full " ,
. gpio = S3C2410_GPA ( 6 ) ,
. retain_state_suspended = 1 ,
2010-09-07 18:32:25 +04:00
} ,
{
2011-03-17 21:04:57 +03:00
. name = " Red " ,
. default_trigger
= " main-battery-charging-blink-full-solid " ,
. gpio = S3C2410_GPA ( 7 ) ,
. retain_state_suspended = 1 ,
2010-09-07 18:32:25 +04:00
} ,
{
2011-03-17 21:04:57 +03:00
. name = " Blue " ,
2010-09-07 18:32:25 +04:00
. default_trigger = " rx1950-acx-mem " ,
2011-03-17 21:04:57 +03:00
. gpio = S3C2410_GPA ( 11 ) ,
. retain_state_suspended = 1 ,
2010-09-07 18:32:25 +04:00
} ,
} ;
static struct gpio_led_platform_data rx1950_leds_pdata = {
. num_leds = ARRAY_SIZE ( rx1950_leds_desc ) ,
. leds = rx1950_leds_desc ,
2011-01-06 22:52:52 +03:00
. gpio_blink_set = rx1950_led_blink_set ,
2010-09-07 18:32:25 +04:00
} ;
static struct platform_device rx1950_leds = {
. name = " leds-gpio " ,
. id = - 1 ,
. dev = {
. platform_data = & rx1950_leds_pdata ,
} ,
} ;
2010-09-27 01:17:48 +04:00
static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
. init = rx1950_bat_init ,
. exit = rx1950_bat_exit ,
. enable_charger = rx1950_enable_charger ,
. disable_charger = rx1950_disable_charger ,
. lut_noac = bat_lut_noac ,
. lut_noac_cnt = ARRAY_SIZE ( bat_lut_noac ) ,
. lut_acin = bat_lut_acin ,
. lut_acin_cnt = ARRAY_SIZE ( bat_lut_acin ) ,
. volt_channel = 0 ,
. current_channel = 1 ,
. volt_mult = 4235 ,
. current_mult = 2900 ,
. internal_impedance = 200 ,
} ;
static struct platform_device rx1950_battery = {
. name = " s3c-adc-battery " ,
. id = - 1 ,
. dev = {
. parent = & s3c_device_adc . dev ,
. platform_data = & rx1950_bat_cfg ,
} ,
} ;
2010-05-11 10:55:07 +04:00
static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
. displays = & rx1950_display ,
. num_displays = 1 ,
. default_display = 0 ,
. lpcsel = 0x02 ,
. gpccon = 0xaa9556a9 ,
. gpccon_mask = 0xffc003fc ,
2019-09-02 23:33:24 +03:00
. gpccon_reg = S3C2410_GPCCON ,
2010-05-11 10:55:07 +04:00
. gpcup = 0x0000ffff ,
. gpcup_mask = 0xffffffff ,
2019-09-02 23:33:24 +03:00
. gpcup_reg = S3C2410_GPCUP ,
2010-05-11 10:55:07 +04:00
. gpdcon = 0xaa90aaa1 ,
. gpdcon_mask = 0xffc0fff0 ,
2019-09-02 23:33:24 +03:00
. gpdcon_reg = S3C2410_GPDCON ,
2010-05-11 10:55:07 +04:00
. gpdup = 0x0000fcfd ,
. gpdup_mask = 0xffffffff ,
2019-09-02 23:33:24 +03:00
. gpdup_reg = S3C2410_GPDUP ,
2010-05-11 10:55:07 +04:00
} ;
2015-10-12 23:04:22 +03:00
static struct pwm_lookup rx1950_pwm_lookup [ ] = {
PWM_LOOKUP ( " samsung-pwm " , 0 , " pwm-backlight.0 " , NULL , 48000 ,
PWM_POLARITY_NORMAL ) ,
2021-03-26 12:06:41 +03:00
PWM_LOOKUP ( " samsung-pwm " , 1 , " pwm-backlight.0 " , " RX1950 LCD " , LCD_PWM_PERIOD ,
PWM_POLARITY_NORMAL ) ,
2015-10-12 23:04:22 +03:00
} ;
2010-05-11 10:55:07 +04:00
static struct pwm_device * lcd_pwm ;
2020-01-20 22:33:28 +03:00
static struct pwm_state lcd_pwm_state ;
2010-05-11 10:55:07 +04:00
2012-01-21 06:46:41 +04:00
static void rx1950_lcd_power ( int enable )
2010-05-11 10:55:07 +04:00
{
int i ;
static int enabled ;
if ( enabled = = enable )
return ;
if ( ! enable ) {
/* GPC11-GPC15->OUTPUT */
for ( i = 11 ; i < 16 ; i + + )
gpio_direction_output ( S3C2410_GPC ( i ) , 1 ) ;
/* Wait a bit here... */
mdelay ( 100 ) ;
/* GPD2-GPD7->OUTPUT */
/* GPD11-GPD15->OUTPUT */
/* GPD2-GPD7->1, GPD11-GPD15->1 */
for ( i = 2 ; i < 8 ; i + + )
gpio_direction_output ( S3C2410_GPD ( i ) , 1 ) ;
for ( i = 11 ; i < 16 ; i + + )
gpio_direction_output ( S3C2410_GPD ( i ) , 1 ) ;
/* Wait a bit here...*/
mdelay ( 100 ) ;
/* GPB0->OUTPUT, GPB0->0 */
gpio_direction_output ( S3C2410_GPB ( 0 ) , 0 ) ;
/* GPC1-GPC4->OUTPUT, GPC1-4->0 */
for ( i = 1 ; i < 5 ; i + + )
gpio_direction_output ( S3C2410_GPC ( i ) , 0 ) ;
/* GPC15-GPC11->0 */
for ( i = 11 ; i < 16 ; i + + )
gpio_direction_output ( S3C2410_GPC ( i ) , 0 ) ;
/* GPD15-GPD11->0, GPD2->GPD7->0 */
for ( i = 11 ; i < 16 ; i + + )
gpio_direction_output ( S3C2410_GPD ( i ) , 0 ) ;
for ( i = 2 ; i < 8 ; i + + )
gpio_direction_output ( S3C2410_GPD ( i ) , 0 ) ;
/* GPC6->0, GPC7->0, GPC5->0 */
gpio_direction_output ( S3C2410_GPC ( 6 ) , 0 ) ;
gpio_direction_output ( S3C2410_GPC ( 7 ) , 0 ) ;
gpio_direction_output ( S3C2410_GPC ( 5 ) , 0 ) ;
/* GPB1->OUTPUT, GPB1->0 */
gpio_direction_output ( S3C2410_GPB ( 1 ) , 0 ) ;
2020-01-20 22:33:28 +03:00
lcd_pwm_state . enabled = false ;
pwm_apply_state ( lcd_pwm , & lcd_pwm_state ) ;
2010-05-11 10:55:07 +04:00
/* GPC0->0, GPC10->0 */
gpio_direction_output ( S3C2410_GPC ( 0 ) , 0 ) ;
gpio_direction_output ( S3C2410_GPC ( 10 ) , 0 ) ;
} else {
2020-01-20 22:33:28 +03:00
lcd_pwm_state . enabled = true ;
pwm_apply_state ( lcd_pwm , & lcd_pwm_state ) ;
2010-05-11 10:55:07 +04:00
gpio_direction_output ( S3C2410_GPC ( 0 ) , 1 ) ;
gpio_direction_output ( S3C2410_GPC ( 5 ) , 1 ) ;
s3c_gpio_cfgpin ( S3C2410_GPB ( 1 ) , S3C2410_GPB1_TOUT1 ) ;
gpio_direction_output ( S3C2410_GPC ( 7 ) , 1 ) ;
for ( i = 1 ; i < 5 ; i + + )
s3c_gpio_cfgpin ( S3C2410_GPC ( i ) , S3C_GPIO_SFN ( 2 ) ) ;
for ( i = 11 ; i < 16 ; i + + )
s3c_gpio_cfgpin ( S3C2410_GPC ( i ) , S3C_GPIO_SFN ( 2 ) ) ;
for ( i = 2 ; i < 8 ; i + + )
s3c_gpio_cfgpin ( S3C2410_GPD ( i ) , S3C_GPIO_SFN ( 2 ) ) ;
for ( i = 11 ; i < 16 ; i + + )
s3c_gpio_cfgpin ( S3C2410_GPD ( i ) , S3C_GPIO_SFN ( 2 ) ) ;
gpio_direction_output ( S3C2410_GPC ( 10 ) , 1 ) ;
gpio_direction_output ( S3C2410_GPC ( 6 ) , 1 ) ;
}
enabled = enable ;
}
static void rx1950_bl_power ( int enable )
{
static int enabled ;
if ( enabled = = enable )
return ;
if ( ! enable ) {
gpio_direction_output ( S3C2410_GPB ( 0 ) , 0 ) ;
} else {
/* LED driver need a "push" to power on */
gpio_direction_output ( S3C2410_GPB ( 0 ) , 1 ) ;
/* Warm up backlight for one period of PWM.
* Without this trick its almost impossible to
* enable backlight with low brightness value
*/
ndelay ( 48000 ) ;
s3c_gpio_cfgpin ( S3C2410_GPB ( 0 ) , S3C2410_GPB0_TOUT0 ) ;
}
enabled = enable ;
}
static int rx1950_backlight_init ( struct device * dev )
{
WARN_ON ( gpio_request ( S3C2410_GPB ( 0 ) , " Backlight " ) ) ;
2021-03-26 12:06:41 +03:00
lcd_pwm = pwm_get ( dev , " RX1950 LCD " ) ;
2010-05-11 10:55:07 +04:00
if ( IS_ERR ( lcd_pwm ) ) {
dev_err ( dev , " Unable to request PWM for LCD power! \n " ) ;
return PTR_ERR ( lcd_pwm ) ;
}
2016-04-14 22:17:36 +03:00
/*
2021-03-26 12:06:41 +03:00
* Call pwm_init_state to initialize . polarity and . period . The other
* values are fixed in this driver .
2016-04-14 22:17:36 +03:00
*/
2020-01-20 22:33:28 +03:00
pwm_init_state ( lcd_pwm , & lcd_pwm_state ) ;
lcd_pwm_state . duty_cycle = LCD_PWM_DUTY ;
2016-04-14 22:17:36 +03:00
2010-05-11 10:55:07 +04:00
rx1950_lcd_power ( 1 ) ;
rx1950_bl_power ( 1 ) ;
return 0 ;
}
static void rx1950_backlight_exit ( struct device * dev )
{
rx1950_bl_power ( 0 ) ;
rx1950_lcd_power ( 0 ) ;
2021-03-26 12:06:41 +03:00
pwm_put ( lcd_pwm ) ;
2010-05-11 10:55:07 +04:00
gpio_free ( S3C2410_GPB ( 0 ) ) ;
}
static int rx1950_backlight_notify ( struct device * dev , int brightness )
{
if ( ! brightness ) {
rx1950_bl_power ( 0 ) ;
rx1950_lcd_power ( 0 ) ;
} else {
rx1950_lcd_power ( 1 ) ;
rx1950_bl_power ( 1 ) ;
}
return brightness ;
}
static struct platform_pwm_backlight_data rx1950_backlight_data = {
. max_brightness = 24 ,
. dft_brightness = 4 ,
. init = rx1950_backlight_init ,
. notify = rx1950_backlight_notify ,
. exit = rx1950_backlight_exit ,
} ;
static struct platform_device rx1950_backlight = {
. name = " pwm-backlight " ,
. dev = {
2013-03-09 18:37:53 +04:00
. parent = & samsung_device_pwm . dev ,
2010-05-11 10:55:07 +04:00
. platform_data = & rx1950_backlight_data ,
} ,
} ;
static void rx1950_set_mmc_power ( unsigned char power_mode , unsigned short vdd )
{
2020-08-06 21:20:46 +03:00
s3c24xx_mci_def_set_power ( power_mode , vdd ) ;
2010-05-11 10:55:07 +04:00
switch ( power_mode ) {
case MMC_POWER_OFF :
gpio_direction_output ( S3C2410_GPJ ( 1 ) , 0 ) ;
break ;
case MMC_POWER_UP :
case MMC_POWER_ON :
gpio_direction_output ( S3C2410_GPJ ( 1 ) , 1 ) ;
break ;
default :
break ;
}
}
static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
. set_power = rx1950_set_mmc_power ,
. ocr_avail = MMC_VDD_32_33 ,
} ;
2018-12-02 11:43:20 +03:00
static struct gpiod_lookup_table rx1950_mmc_gpio_table = {
. dev_id = " s3c2410-sdi " ,
. table = {
/* Card detect S3C2410_GPF(5) */
2020-08-06 21:20:20 +03:00
GPIO_LOOKUP ( " GPIOF " , 5 , " cd " , GPIO_ACTIVE_LOW ) ,
2018-12-02 11:43:20 +03:00
/* Write protect S3C2410_GPH(8) */
2020-08-06 21:20:20 +03:00
GPIO_LOOKUP ( " GPIOH " , 8 , " wp " , GPIO_ACTIVE_LOW ) ,
2020-08-06 21:20:46 +03:00
/* bus pins */
GPIO_LOOKUP_IDX ( " GPIOE " , 5 , " bus " , 0 , GPIO_ACTIVE_HIGH ) ,
GPIO_LOOKUP_IDX ( " GPIOE " , 6 , " bus " , 1 , GPIO_ACTIVE_HIGH ) ,
GPIO_LOOKUP_IDX ( " GPIOE " , 7 , " bus " , 2 , GPIO_ACTIVE_HIGH ) ,
GPIO_LOOKUP_IDX ( " GPIOE " , 8 , " bus " , 3 , GPIO_ACTIVE_HIGH ) ,
GPIO_LOOKUP_IDX ( " GPIOE " , 9 , " bus " , 4 , GPIO_ACTIVE_HIGH ) ,
GPIO_LOOKUP_IDX ( " GPIOE " , 10 , " bus " , 5 , GPIO_ACTIVE_HIGH ) ,
2018-12-02 11:43:20 +03:00
{ } ,
} ,
} ;
2010-05-11 10:55:07 +04:00
static struct mtd_partition rx1950_nand_part [ ] = {
[ 0 ] = {
. name = " Boot0 " ,
. offset = 0 ,
. size = 0x4000 ,
. mask_flags = MTD_WRITEABLE ,
} ,
[ 1 ] = {
. name = " Boot1 " ,
. offset = MTDPART_OFS_APPEND ,
. size = 0x40000 ,
. mask_flags = MTD_WRITEABLE ,
} ,
[ 2 ] = {
. name = " Kernel " ,
. offset = MTDPART_OFS_APPEND ,
. size = 0x300000 ,
. mask_flags = 0 ,
} ,
[ 3 ] = {
. name = " Filesystem " ,
. offset = MTDPART_OFS_APPEND ,
. size = MTDPART_SIZ_FULL ,
. mask_flags = 0 ,
} ,
} ;
static struct s3c2410_nand_set rx1950_nand_sets [ ] = {
[ 0 ] = {
. name = " Internal " ,
. nr_chips = 1 ,
. nr_partitions = ARRAY_SIZE ( rx1950_nand_part ) ,
. partitions = rx1950_nand_part ,
} ,
} ;
static struct s3c2410_platform_nand rx1950_nand_info = {
. tacls = 25 ,
. twrph0 = 50 ,
. twrph1 = 15 ,
. nr_sets = ARRAY_SIZE ( rx1950_nand_sets ) ,
. sets = rx1950_nand_sets ,
2020-08-27 11:51:58 +03:00
. engine_type = NAND_ECC_ENGINE_TYPE_SOFT ,
2010-05-11 10:55:07 +04:00
} ;
static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
. vbus_pin = S3C2410_GPG ( 5 ) ,
. vbus_pin_inverted = 1 ,
2011-03-07 10:42:00 +03:00
. pullup_pin = S3C2410_GPJ ( 5 ) ,
2010-05-11 10:55:07 +04:00
} ;
static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
. delay = 10000 ,
. presc = 49 ,
. oversampling_shift = 3 ,
} ;
static struct gpio_keys_button rx1950_gpio_keys_table [ ] = {
{
. code = KEY_POWER ,
. gpio = S3C2410_GPF ( 0 ) ,
. active_low = 1 ,
. desc = " Power button " ,
. wakeup = 1 ,
} ,
{
. code = KEY_F5 ,
. gpio = S3C2410_GPF ( 7 ) ,
. active_low = 1 ,
. desc = " Record button " ,
} ,
{
. code = KEY_F1 ,
. gpio = S3C2410_GPG ( 0 ) ,
. active_low = 1 ,
. desc = " Calendar button " ,
} ,
{
. code = KEY_F2 ,
. gpio = S3C2410_GPG ( 2 ) ,
. active_low = 1 ,
. desc = " Contacts button " ,
} ,
{
. code = KEY_F3 ,
. gpio = S3C2410_GPG ( 3 ) ,
. active_low = 1 ,
. desc = " Mail button " ,
} ,
{
. code = KEY_F4 ,
. gpio = S3C2410_GPG ( 7 ) ,
. active_low = 1 ,
. desc = " WLAN button " ,
} ,
{
. code = KEY_LEFT ,
. gpio = S3C2410_GPG ( 10 ) ,
. active_low = 1 ,
. desc = " Left button " ,
} ,
{
. code = KEY_RIGHT ,
. gpio = S3C2410_GPG ( 11 ) ,
. active_low = 1 ,
. desc = " Right button " ,
} ,
{
. code = KEY_UP ,
. gpio = S3C2410_GPG ( 4 ) ,
. active_low = 1 ,
. desc = " Up button " ,
} ,
{
. code = KEY_DOWN ,
. gpio = S3C2410_GPG ( 6 ) ,
. active_low = 1 ,
. desc = " Down button " ,
} ,
{
. code = KEY_ENTER ,
. gpio = S3C2410_GPG ( 9 ) ,
. active_low = 1 ,
. desc = " Ok button "
} ,
} ;
static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
. buttons = rx1950_gpio_keys_table ,
. nbuttons = ARRAY_SIZE ( rx1950_gpio_keys_table ) ,
} ;
static struct platform_device rx1950_device_gpiokeys = {
. name = " gpio-keys " ,
. dev . platform_data = & rx1950_gpio_keys_data ,
} ;
2010-09-07 18:32:26 +04:00
static struct uda1380_platform_data uda1380_info = {
. gpio_power = S3C2410_GPJ ( 0 ) ,
. gpio_reset = S3C2410_GPD ( 0 ) ,
. dac_clk = UDA1380_DAC_CLK_SYSCLK ,
} ;
static struct i2c_board_info rx1950_i2c_devices [ ] = {
{
I2C_BOARD_INFO ( " uda1380 " , 0x1a ) ,
. platform_data = & uda1380_info ,
} ,
2010-05-11 10:55:07 +04:00
} ;
2020-08-06 21:20:43 +03:00
static struct gpiod_lookup_table rx1950_audio_gpio_table = {
. dev_id = " rx1950-audio " ,
. table = {
GPIO_LOOKUP ( " GPIOG " , 12 , " hp-gpio " , GPIO_ACTIVE_HIGH ) ,
GPIO_LOOKUP ( " GPIOA " , 1 , " speaker-power " , GPIO_ACTIVE_HIGH ) ,
{ } ,
} ,
} ;
static struct platform_device rx1950_audio = {
. name = " rx1950-audio " ,
. id = - 1 ,
} ;
2010-05-11 10:55:07 +04:00
static struct platform_device * rx1950_devices [ ] __initdata = {
2014-05-09 00:48:57 +04:00
& s3c2410_device_dclk ,
2010-05-11 10:55:07 +04:00
& s3c_device_lcd ,
& s3c_device_wdt ,
& s3c_device_i2c0 ,
& s3c_device_iis ,
& s3c_device_usbgadget ,
& s3c_device_rtc ,
& s3c_device_nand ,
& s3c_device_sdi ,
& s3c_device_adc ,
& s3c_device_ts ,
2013-03-09 18:37:53 +04:00
& samsung_device_pwm ,
2010-05-11 10:55:07 +04:00
& rx1950_backlight ,
& rx1950_device_gpiokeys ,
2010-09-27 01:17:48 +04:00
& power_supply ,
& rx1950_battery ,
2010-09-07 18:32:25 +04:00
& rx1950_leds ,
2020-08-06 21:20:43 +03:00
& rx1950_audio ,
2010-05-11 10:55:07 +04:00
} ;
static void __init rx1950_map_io ( void )
{
s3c24xx_init_io ( rx1950_iodesc , ARRAY_SIZE ( rx1950_iodesc ) ) ;
s3c24xx_init_uarts ( rx1950_uartcfgs , ARRAY_SIZE ( rx1950_uartcfgs ) ) ;
2020-08-20 23:42:03 +03:00
s3c24xx_set_timer_source ( S3C24XX_PWM3 , S3C24XX_PWM4 ) ;
2010-05-11 10:55:07 +04:00
/* setup PM */
# ifdef CONFIG_PM_H1940
memcpy ( phys_to_virt ( H1940_SUSPEND_RESUMEAT ) , h1940_pm_return , 8 ) ;
# endif
s3c_pm_init ( ) ;
}
2014-05-09 00:49:19 +04:00
static void __init rx1950_init_time ( void )
{
s3c2442_init_clocks ( 16934000 ) ;
2020-08-20 23:42:03 +03:00
s3c24xx_timer_init ( ) ;
2014-05-09 00:49:19 +04:00
}
2010-05-11 10:55:07 +04:00
static void __init rx1950_init_machine ( void )
{
int i ;
s3c24xx_fb_set_platdata ( & rx1950_lcd_cfg ) ;
s3c24xx_udc_set_platdata ( & rx1950_udc_cfg ) ;
s3c24xx_ts_set_platdata ( & rx1950_ts_cfg ) ;
2018-12-02 11:43:20 +03:00
gpiod_add_lookup_table ( & rx1950_mmc_gpio_table ) ;
2010-05-11 10:55:07 +04:00
s3c24xx_mci_set_platdata ( & rx1950_mmc_cfg ) ;
2010-09-07 18:32:26 +04:00
s3c_i2c0_set_platdata ( NULL ) ;
2010-05-11 10:55:07 +04:00
s3c_nand_set_platdata ( & rx1950_nand_info ) ;
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode . */
s3c2410_modify_misccr ( S3C2410_MISCCR_USBHOST |
S3C2410_MISCCR_USBSUSPND0 |
S3C2410_MISCCR_USBSUSPND1 , 0x0 ) ;
/* mmc power is disabled by default */
WARN_ON ( gpio_request ( S3C2410_GPJ ( 1 ) , " MMC power " ) ) ;
gpio_direction_output ( S3C2410_GPJ ( 1 ) , 0 ) ;
for ( i = 0 ; i < 8 ; i + + )
WARN_ON ( gpio_request ( S3C2410_GPC ( i ) , " LCD power " ) ) ;
for ( i = 10 ; i < 16 ; i + + )
WARN_ON ( gpio_request ( S3C2410_GPC ( i ) , " LCD power " ) ) ;
for ( i = 2 ; i < 8 ; i + + )
WARN_ON ( gpio_request ( S3C2410_GPD ( i ) , " LCD power " ) ) ;
for ( i = 11 ; i < 16 ; i + + )
WARN_ON ( gpio_request ( S3C2410_GPD ( i ) , " LCD power " ) ) ;
WARN_ON ( gpio_request ( S3C2410_GPB ( 1 ) , " LCD power " ) ) ;
2011-01-06 22:52:52 +03:00
WARN_ON ( gpio_request ( S3C2410_GPA ( 3 ) , " Red blink " ) ) ;
WARN_ON ( gpio_request ( S3C2410_GPA ( 4 ) , " Green blink " ) ) ;
WARN_ON ( gpio_request ( S3C2410_GPJ ( 6 ) , " LED blink " ) ) ;
gpio_direction_output ( S3C2410_GPA ( 3 ) , 0 ) ;
gpio_direction_output ( S3C2410_GPA ( 4 ) , 0 ) ;
gpio_direction_output ( S3C2410_GPJ ( 6 ) , 0 ) ;
2015-10-12 23:04:22 +03:00
pwm_add_table ( rx1950_pwm_lookup , ARRAY_SIZE ( rx1950_pwm_lookup ) ) ;
2020-08-06 21:20:43 +03:00
gpiod_add_lookup_table ( & rx1950_audio_gpio_table ) ;
2020-11-03 02:48:44 +03:00
gpiod_add_lookup_table ( & rx1950_bat_gpio_table ) ;
2020-08-06 21:20:45 +03:00
/* Configure the I2S pins (GPE0...GPE4) in correct mode */
s3c_gpio_cfgall_range ( S3C2410_GPE ( 0 ) , 5 , S3C_GPIO_SFN ( 2 ) ,
S3C_GPIO_PULL_NONE ) ;
2010-05-11 10:55:07 +04:00
platform_add_devices ( rx1950_devices , ARRAY_SIZE ( rx1950_devices ) ) ;
2010-09-07 18:32:26 +04:00
i2c_register_board_info ( 0 , rx1950_i2c_devices ,
ARRAY_SIZE ( rx1950_i2c_devices ) ) ;
2010-05-11 10:55:07 +04:00
}
2010-05-22 21:18:57 +04:00
/* H1940 and RX3715 need to reserve this for suspend */
static void __init rx1950_reserve ( void )
{
2010-05-22 22:47:18 +04:00
memblock_reserve ( 0x30003000 , 0x1000 ) ;
memblock_reserve ( 0x30081000 , 0x1000 ) ;
2010-05-22 21:18:57 +04:00
}
2010-05-11 10:55:07 +04:00
MACHINE_START ( RX1950 , " HP iPAQ RX1950 " )
/* Maintainers: Vasily Khoruzhick */
2011-07-06 06:38:17 +04:00
. atag_offset = 0x100 ,
2022-04-02 16:28:18 +03:00
. nr_irqs = NR_IRQS_S3C2442 ,
2010-05-11 10:55:07 +04:00
. map_io = rx1950_map_io ,
2010-05-22 21:18:57 +04:00
. reserve = rx1950_reserve ,
2013-02-12 21:59:20 +04:00
. init_irq = s3c2442_init_irq ,
2010-05-11 10:55:07 +04:00
. init_machine = rx1950_init_machine ,
2014-05-09 00:49:19 +04:00
. init_time = rx1950_init_time ,
2010-05-11 10:55:07 +04:00
MACHINE_END