xref: /OK3568_Linux_fs/kernel/arch/arm/mach-s3c/mach-smartq.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // Copyright (C) 2010 Maurus Cuelenaere
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/delay.h>
6*4882a593Smuzhiyun #include <linux/fb.h>
7*4882a593Smuzhiyun #include <linux/gpio.h>
8*4882a593Smuzhiyun #include <linux/gpio/machine.h>
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/platform_device.h>
11*4882a593Smuzhiyun #include <linux/pwm.h>
12*4882a593Smuzhiyun #include <linux/pwm_backlight.h>
13*4882a593Smuzhiyun #include <linux/serial_core.h>
14*4882a593Smuzhiyun #include <linux/serial_s3c.h>
15*4882a593Smuzhiyun #include <linux/spi/spi_gpio.h>
16*4882a593Smuzhiyun #include <linux/platform_data/s3c-hsotg.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <asm/mach-types.h>
19*4882a593Smuzhiyun #include <asm/mach/map.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include "map.h"
22*4882a593Smuzhiyun #include "regs-gpio.h"
23*4882a593Smuzhiyun #include "gpio-samsung.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "cpu.h"
26*4882a593Smuzhiyun #include "devs.h"
27*4882a593Smuzhiyun #include <linux/platform_data/i2c-s3c2410.h>
28*4882a593Smuzhiyun #include "gpio-cfg.h"
29*4882a593Smuzhiyun #include <linux/platform_data/hwmon-s3c.h>
30*4882a593Smuzhiyun #include <linux/platform_data/usb-ohci-s3c2410.h>
31*4882a593Smuzhiyun #include "sdhci.h"
32*4882a593Smuzhiyun #include <linux/platform_data/touchscreen-s3c2410.h>
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #include <video/platform_lcd.h>
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include "s3c64xx.h"
37*4882a593Smuzhiyun #include "mach-smartq.h"
38*4882a593Smuzhiyun #include "regs-modem-s3c64xx.h"
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define UCON S3C2410_UCON_DEFAULT
41*4882a593Smuzhiyun #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
42*4882a593Smuzhiyun #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun static struct s3c2410_uartcfg smartq_uartcfgs[] __initdata = {
45*4882a593Smuzhiyun 	[0] = {
46*4882a593Smuzhiyun 		.hwport	     = 0,
47*4882a593Smuzhiyun 		.flags	     = 0,
48*4882a593Smuzhiyun 		.ucon	     = UCON,
49*4882a593Smuzhiyun 		.ulcon	     = ULCON,
50*4882a593Smuzhiyun 		.ufcon	     = UFCON,
51*4882a593Smuzhiyun 	},
52*4882a593Smuzhiyun 	[1] = {
53*4882a593Smuzhiyun 		.hwport	     = 1,
54*4882a593Smuzhiyun 		.flags	     = 0,
55*4882a593Smuzhiyun 		.ucon	     = UCON,
56*4882a593Smuzhiyun 		.ulcon	     = ULCON,
57*4882a593Smuzhiyun 		.ufcon	     = UFCON,
58*4882a593Smuzhiyun 	},
59*4882a593Smuzhiyun 	[2] = {
60*4882a593Smuzhiyun 		.hwport	     = 2,
61*4882a593Smuzhiyun 		.flags	     = 0,
62*4882a593Smuzhiyun 		.ucon	     = UCON,
63*4882a593Smuzhiyun 		.ulcon	     = ULCON,
64*4882a593Smuzhiyun 		.ufcon	     = UFCON,
65*4882a593Smuzhiyun 	},
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
smartq_usb_host_powercontrol(int port,int to)68*4882a593Smuzhiyun static void smartq_usb_host_powercontrol(int port, int to)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	pr_debug("%s(%d, %d)\n", __func__, port, to);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	if (port == 0) {
73*4882a593Smuzhiyun 		gpio_set_value(S3C64XX_GPL(0), to);
74*4882a593Smuzhiyun 		gpio_set_value(S3C64XX_GPL(1), to);
75*4882a593Smuzhiyun 	}
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
smartq_usb_host_ocirq(int irq,void * pw)78*4882a593Smuzhiyun static irqreturn_t smartq_usb_host_ocirq(int irq, void *pw)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	struct s3c2410_hcd_info *info = pw;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	if (gpio_get_value(S3C64XX_GPL(10)) == 0) {
83*4882a593Smuzhiyun 		pr_debug("%s: over-current irq (oc detected)\n", __func__);
84*4882a593Smuzhiyun 		s3c2410_usb_report_oc(info, 3);
85*4882a593Smuzhiyun 	} else {
86*4882a593Smuzhiyun 		pr_debug("%s: over-current irq (oc cleared)\n", __func__);
87*4882a593Smuzhiyun 		s3c2410_usb_report_oc(info, 0);
88*4882a593Smuzhiyun 	}
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	return IRQ_HANDLED;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
smartq_usb_host_enableoc(struct s3c2410_hcd_info * info,int on)93*4882a593Smuzhiyun static void smartq_usb_host_enableoc(struct s3c2410_hcd_info *info, int on)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	int ret;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	/* This isn't present on a SmartQ 5 board */
98*4882a593Smuzhiyun 	if (machine_is_smartq5())
99*4882a593Smuzhiyun 		return;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	if (on) {
102*4882a593Smuzhiyun 		ret = request_irq(gpio_to_irq(S3C64XX_GPL(10)),
103*4882a593Smuzhiyun 				  smartq_usb_host_ocirq,
104*4882a593Smuzhiyun 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
105*4882a593Smuzhiyun 				  "USB host overcurrent", info);
106*4882a593Smuzhiyun 		if (ret != 0)
107*4882a593Smuzhiyun 			pr_err("failed to request usb oc irq: %d\n", ret);
108*4882a593Smuzhiyun 	} else {
109*4882a593Smuzhiyun 		free_irq(gpio_to_irq(S3C64XX_GPL(10)), info);
110*4882a593Smuzhiyun 	}
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun static struct s3c2410_hcd_info smartq_usb_host_info = {
114*4882a593Smuzhiyun 	.port[0]	= {
115*4882a593Smuzhiyun 		.flags	= S3C_HCDFLG_USED
116*4882a593Smuzhiyun 	},
117*4882a593Smuzhiyun 	.port[1]	= {
118*4882a593Smuzhiyun 		.flags	= 0
119*4882a593Smuzhiyun 	},
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	.power_control	= smartq_usb_host_powercontrol,
122*4882a593Smuzhiyun 	.enable_oc	= smartq_usb_host_enableoc,
123*4882a593Smuzhiyun };
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun static struct gpiod_lookup_table smartq_usb_otg_vbus_gpiod_table = {
126*4882a593Smuzhiyun 	.dev_id = "gpio-vbus",
127*4882a593Smuzhiyun 	.table = {
128*4882a593Smuzhiyun 		GPIO_LOOKUP("GPL", 9, "vbus", GPIO_ACTIVE_LOW),
129*4882a593Smuzhiyun 		{ },
130*4882a593Smuzhiyun 	},
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun static struct platform_device smartq_usb_otg_vbus_dev = {
134*4882a593Smuzhiyun 	.name			= "gpio-vbus",
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun static struct pwm_lookup smartq_pwm_lookup[] = {
138*4882a593Smuzhiyun 	PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL,
139*4882a593Smuzhiyun 		   1000000000 / (1000 * 20), PWM_POLARITY_NORMAL),
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun 
smartq_bl_init(struct device * dev)142*4882a593Smuzhiyun static int smartq_bl_init(struct device *dev)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun     s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun     return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun static struct platform_pwm_backlight_data smartq_backlight_data = {
150*4882a593Smuzhiyun 	.max_brightness	= 1000,
151*4882a593Smuzhiyun 	.dft_brightness	= 600,
152*4882a593Smuzhiyun 	.init		= smartq_bl_init,
153*4882a593Smuzhiyun };
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun static struct platform_device smartq_backlight_device = {
156*4882a593Smuzhiyun 	.name		= "pwm-backlight",
157*4882a593Smuzhiyun 	.dev		= {
158*4882a593Smuzhiyun 		.parent	= &samsung_device_pwm.dev,
159*4882a593Smuzhiyun 		.platform_data = &smartq_backlight_data,
160*4882a593Smuzhiyun 	},
161*4882a593Smuzhiyun };
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun static struct s3c2410_ts_mach_info smartq_touchscreen_pdata __initdata = {
164*4882a593Smuzhiyun 	.delay			= 65535,
165*4882a593Smuzhiyun 	.presc			= 99,
166*4882a593Smuzhiyun 	.oversampling_shift	= 4,
167*4882a593Smuzhiyun };
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun static struct s3c_sdhci_platdata smartq_internal_hsmmc_pdata = {
170*4882a593Smuzhiyun 	.max_width		= 4,
171*4882a593Smuzhiyun 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
175*4882a593Smuzhiyun 	/* Battery voltage (?-4.2V) */
176*4882a593Smuzhiyun 	.in[0] = &(struct s3c_hwmon_chcfg) {
177*4882a593Smuzhiyun 		.name		= "smartq:battery-voltage",
178*4882a593Smuzhiyun 		.mult		= 3300,
179*4882a593Smuzhiyun 		.div		= 2048,
180*4882a593Smuzhiyun 	},
181*4882a593Smuzhiyun 	/* Reference voltage (1.2V) */
182*4882a593Smuzhiyun 	.in[1] = &(struct s3c_hwmon_chcfg) {
183*4882a593Smuzhiyun 		.name		= "smartq:reference-voltage",
184*4882a593Smuzhiyun 		.mult		= 3300,
185*4882a593Smuzhiyun 		.div		= 4096,
186*4882a593Smuzhiyun 	},
187*4882a593Smuzhiyun };
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun static struct dwc2_hsotg_plat smartq_hsotg_pdata;
190*4882a593Smuzhiyun 
smartq_lcd_setup_gpio(void)191*4882a593Smuzhiyun static int __init smartq_lcd_setup_gpio(void)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	int ret;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	ret = gpio_request(S3C64XX_GPM(3), "LCD power");
196*4882a593Smuzhiyun 	if (ret < 0)
197*4882a593Smuzhiyun 		return ret;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	/* turn power off */
200*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPM(3), 0);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	return 0;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun /* GPM0 -> CS */
206*4882a593Smuzhiyun static struct spi_gpio_platform_data smartq_lcd_control = {
207*4882a593Smuzhiyun 	.num_chipselect	= 1,
208*4882a593Smuzhiyun };
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun static struct platform_device smartq_lcd_control_device = {
211*4882a593Smuzhiyun 	.name			= "spi_gpio",
212*4882a593Smuzhiyun 	.id			= 1,
213*4882a593Smuzhiyun 	.dev.platform_data	= &smartq_lcd_control,
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun static struct gpiod_lookup_table smartq_lcd_control_gpiod_table = {
217*4882a593Smuzhiyun 	.dev_id         = "spi_gpio",
218*4882a593Smuzhiyun 	.table          = {
219*4882a593Smuzhiyun 		GPIO_LOOKUP("GPIOM", 1,
220*4882a593Smuzhiyun 			    "sck", GPIO_ACTIVE_HIGH),
221*4882a593Smuzhiyun 		GPIO_LOOKUP("GPIOM", 2,
222*4882a593Smuzhiyun 			    "mosi", GPIO_ACTIVE_HIGH),
223*4882a593Smuzhiyun 		GPIO_LOOKUP("GPIOM", 3,
224*4882a593Smuzhiyun 			    "miso", GPIO_ACTIVE_HIGH),
225*4882a593Smuzhiyun 		GPIO_LOOKUP("GPIOM", 0,
226*4882a593Smuzhiyun 			    "cs", GPIO_ACTIVE_HIGH),
227*4882a593Smuzhiyun 		{ },
228*4882a593Smuzhiyun 	},
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun 
smartq_lcd_power_set(struct plat_lcd_data * pd,unsigned int power)231*4882a593Smuzhiyun static void smartq_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPM(3), power);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun static struct plat_lcd_data smartq_lcd_power_data = {
237*4882a593Smuzhiyun 	.set_power	= smartq_lcd_power_set,
238*4882a593Smuzhiyun };
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun static struct platform_device smartq_lcd_power_device = {
241*4882a593Smuzhiyun 	.name			= "platform-lcd",
242*4882a593Smuzhiyun 	.dev.parent		= &s3c_device_fb.dev,
243*4882a593Smuzhiyun 	.dev.platform_data	= &smartq_lcd_power_data,
244*4882a593Smuzhiyun };
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun static struct i2c_board_info smartq_i2c_devs[] __initdata = {
247*4882a593Smuzhiyun 	{ I2C_BOARD_INFO("wm8987", 0x1a), },
248*4882a593Smuzhiyun };
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun static struct platform_device *smartq_devices[] __initdata = {
251*4882a593Smuzhiyun 	&s3c_device_hsmmc1,	/* Init iNAND first, ... */
252*4882a593Smuzhiyun 	&s3c_device_hsmmc0,	/* ... then the external SD card */
253*4882a593Smuzhiyun 	&s3c_device_hsmmc2,
254*4882a593Smuzhiyun 	&s3c_device_adc,
255*4882a593Smuzhiyun 	&s3c_device_fb,
256*4882a593Smuzhiyun 	&s3c_device_hwmon,
257*4882a593Smuzhiyun 	&s3c_device_i2c0,
258*4882a593Smuzhiyun 	&s3c_device_ohci,
259*4882a593Smuzhiyun 	&s3c_device_rtc,
260*4882a593Smuzhiyun 	&samsung_device_pwm,
261*4882a593Smuzhiyun 	&s3c_device_usb_hsotg,
262*4882a593Smuzhiyun 	&s3c64xx_device_iis0,
263*4882a593Smuzhiyun 	&smartq_backlight_device,
264*4882a593Smuzhiyun 	&smartq_lcd_control_device,
265*4882a593Smuzhiyun 	&smartq_lcd_power_device,
266*4882a593Smuzhiyun 	&smartq_usb_otg_vbus_dev,
267*4882a593Smuzhiyun };
268*4882a593Smuzhiyun 
smartq_lcd_mode_set(void)269*4882a593Smuzhiyun static void __init smartq_lcd_mode_set(void)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun 	u32 tmp;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	/* set the LCD type */
274*4882a593Smuzhiyun 	tmp = __raw_readl(S3C64XX_SPCON);
275*4882a593Smuzhiyun 	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
276*4882a593Smuzhiyun 	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
277*4882a593Smuzhiyun 	__raw_writel(tmp, S3C64XX_SPCON);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	/* remove the LCD bypass */
280*4882a593Smuzhiyun 	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
281*4882a593Smuzhiyun 	tmp &= ~MIFPCON_LCD_BYPASS;
282*4882a593Smuzhiyun 	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
smartq_power_off(void)285*4882a593Smuzhiyun static void smartq_power_off(void)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPK(15), 1);
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun 
smartq_power_off_init(void)290*4882a593Smuzhiyun static int __init smartq_power_off_init(void)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	int ret;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	ret = gpio_request(S3C64XX_GPK(15), "Power control");
295*4882a593Smuzhiyun 	if (ret < 0) {
296*4882a593Smuzhiyun 		pr_err("%s: failed to get GPK15\n", __func__);
297*4882a593Smuzhiyun 		return ret;
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	/* leave power on */
301*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPK(15), 0);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	pm_power_off = smartq_power_off;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	return ret;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun 
smartq_usb_host_init(void)308*4882a593Smuzhiyun static int __init smartq_usb_host_init(void)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun 	int ret;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	ret = gpio_request(S3C64XX_GPL(0), "USB power control");
313*4882a593Smuzhiyun 	if (ret < 0) {
314*4882a593Smuzhiyun 		pr_err("%s: failed to get GPL0\n", __func__);
315*4882a593Smuzhiyun 		return ret;
316*4882a593Smuzhiyun 	}
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	ret = gpio_request(S3C64XX_GPL(1), "USB host power control");
319*4882a593Smuzhiyun 	if (ret < 0) {
320*4882a593Smuzhiyun 		pr_err("%s: failed to get GPL1\n", __func__);
321*4882a593Smuzhiyun 		goto err;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	if (!machine_is_smartq5()) {
325*4882a593Smuzhiyun 		/* This isn't present on a SmartQ 5 board */
326*4882a593Smuzhiyun 		ret = gpio_request(S3C64XX_GPL(10), "USB host overcurrent");
327*4882a593Smuzhiyun 		if (ret < 0) {
328*4882a593Smuzhiyun 			pr_err("%s: failed to get GPL10\n", __func__);
329*4882a593Smuzhiyun 			goto err2;
330*4882a593Smuzhiyun 		}
331*4882a593Smuzhiyun 	}
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	/* turn power off */
334*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPL(0), 0);
335*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPL(1), 0);
336*4882a593Smuzhiyun 	if (!machine_is_smartq5())
337*4882a593Smuzhiyun 		gpio_direction_input(S3C64XX_GPL(10));
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	s3c_device_ohci.dev.platform_data = &smartq_usb_host_info;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	return 0;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun err2:
344*4882a593Smuzhiyun 	gpio_free(S3C64XX_GPL(1));
345*4882a593Smuzhiyun err:
346*4882a593Smuzhiyun 	gpio_free(S3C64XX_GPL(0));
347*4882a593Smuzhiyun 	return ret;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
smartq_wifi_init(void)350*4882a593Smuzhiyun static int __init smartq_wifi_init(void)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun 	int ret;
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	ret = gpio_request(S3C64XX_GPK(1), "wifi control");
355*4882a593Smuzhiyun 	if (ret < 0) {
356*4882a593Smuzhiyun 		pr_err("%s: failed to get GPK1\n", __func__);
357*4882a593Smuzhiyun 		return ret;
358*4882a593Smuzhiyun 	}
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	ret = gpio_request(S3C64XX_GPK(2), "wifi reset");
361*4882a593Smuzhiyun 	if (ret < 0) {
362*4882a593Smuzhiyun 		pr_err("%s: failed to get GPK2\n", __func__);
363*4882a593Smuzhiyun 		gpio_free(S3C64XX_GPK(1));
364*4882a593Smuzhiyun 		return ret;
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	/* turn power on */
368*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPK(1), 1);
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	/* reset device */
371*4882a593Smuzhiyun 	gpio_direction_output(S3C64XX_GPK(2), 0);
372*4882a593Smuzhiyun 	mdelay(100);
373*4882a593Smuzhiyun 	gpio_set_value(S3C64XX_GPK(2), 1);
374*4882a593Smuzhiyun 	gpio_direction_input(S3C64XX_GPK(2));
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	return 0;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun static struct map_desc smartq_iodesc[] __initdata = {};
smartq_map_io(void)380*4882a593Smuzhiyun void __init smartq_map_io(void)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun 	s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
383*4882a593Smuzhiyun 	s3c64xx_set_xtal_freq(12000000);
384*4882a593Smuzhiyun 	s3c64xx_set_xusbxti_freq(12000000);
385*4882a593Smuzhiyun 	s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
386*4882a593Smuzhiyun 	s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	smartq_lcd_mode_set();
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun static struct gpiod_lookup_table smartq_audio_gpios = {
392*4882a593Smuzhiyun 	.dev_id = "smartq-audio",
393*4882a593Smuzhiyun 	.table = {
394*4882a593Smuzhiyun 		GPIO_LOOKUP("GPL", 12, "headphone detect", 0),
395*4882a593Smuzhiyun 		GPIO_LOOKUP("GPK", 12, "amplifiers shutdown", 0),
396*4882a593Smuzhiyun 		{ },
397*4882a593Smuzhiyun 	},
398*4882a593Smuzhiyun };
399*4882a593Smuzhiyun 
smartq_machine_init(void)400*4882a593Smuzhiyun void __init smartq_machine_init(void)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	s3c_i2c0_set_platdata(NULL);
403*4882a593Smuzhiyun 	dwc2_hsotg_set_platdata(&smartq_hsotg_pdata);
404*4882a593Smuzhiyun 	s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
405*4882a593Smuzhiyun 	s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
406*4882a593Smuzhiyun 	s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
407*4882a593Smuzhiyun 	s3c64xx_ts_set_platdata(&smartq_touchscreen_pdata);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	i2c_register_board_info(0, smartq_i2c_devs,
410*4882a593Smuzhiyun 				ARRAY_SIZE(smartq_i2c_devs));
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	WARN_ON(smartq_lcd_setup_gpio());
413*4882a593Smuzhiyun 	WARN_ON(smartq_power_off_init());
414*4882a593Smuzhiyun 	WARN_ON(smartq_usb_host_init());
415*4882a593Smuzhiyun 	WARN_ON(smartq_wifi_init());
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
418*4882a593Smuzhiyun 	gpiod_add_lookup_table(&smartq_lcd_control_gpiod_table);
419*4882a593Smuzhiyun 	gpiod_add_lookup_table(&smartq_usb_otg_vbus_gpiod_table);
420*4882a593Smuzhiyun 	platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	gpiod_add_lookup_table(&smartq_audio_gpios);
423*4882a593Smuzhiyun 	platform_device_register_simple("smartq-audio", -1, NULL, 0);
424*4882a593Smuzhiyun }
425